仓颉编程入门2,启动HTTP服务

上一篇配置了仓颉sdk编译和运行环境,读取一个配置文件,并把配置文件简单解析了一下。

前面读取配置文件,使用File.readFrom(),这个直接把文件全部读取出来,返回一个字节数组。然后又创建一个字节流,给文件字节写进去,又创建了一个StringReader,相当的麻烦。

后来又尝试使用File.openRead(),可以直接返回一个文件流,直接被StringReader使用。优化的代码如下:

public init(){let fs=File.openRead('./config.ini')                    //创建一个文件流let sr=StringReader(fs)                                 //创建一个字符串流读取对象var s=sr.readln()??""                                   //读取一行,如果没有内容就是空while(s.size>0){                                        //如果这一行有数据let a=s.split("=")                                  //对这一行分割 key = valuemap[a[0]]=a[1]                                      //a[0]是key  ,a[1]是value,存储到hashmaps=sr.readln()??""                                   //读取下一行}println(map)                                            //输出一下fs.close()}

接下来,启动一个http服务,按照官方给的代码示例:

咱们创建一个MyServer类,里面有一个属性是server,有初始化,有启动服务。注意配置文件类,已经修改为单例模式。

class MyServer{let serverpublic init(){let ip=Config.Instance.getString("serverIP")            //读取iplet port=Config.Instance.getInt("port")                 //读取端口server=ServerBuilder().addr(ip).port(port).build()                                //返回一个Server对象}func service(){//注册监听server.distributor.register("/index", {httpContext =>httpContext.responseBuilder.body("Hello 仓颉!")})// 启动服务server.serve()}}

接下来是main函数调用一下,代码如下:

main()
{println("cangjie http") let svr=MyServer()                              //创建myserver对象spawn {svr.service()                               //在子线程中运行http服务}while(true){                                    //主线程不能退,退了子线程也要退出println("cangjie http service")sleep(Duration.second)  // sleep for 1s.}}

 编译,.....不出所料,报错了。

报错的意思大概是let server,没有初始化,也没有类型说明,这样不行。那就给一个类型把。类型到底是什么呢?到这里我还是不知道的,那就随便写一个吧。let server:ServerBuilder,先写这个把,因为官方给的代码里面,看不出来到底是啥类型。继续编译:

又报了两个错,第一个错误,端口号应该是UInt16,那就转一下。

let port=UInt16(Config.Instance.getInt("port"))                 //读取端口 ,转换为UInt16 实际就是unsigned short

继续编译,还是报错。。。。。。。

到这个错误,基本明白了,serverBuiler返回的是一个Server类型的对象。下面那两个错误,是说ServerBuilder没有这两个方法。

意思就是给前面let server:serverBuilder 改成let server:Server。 前面为啥不直接写出Server呢?因为看官方的代码,真看不出来类型。这次编译通过了!!!!!!!

这里要吐槽一下,这种不用声明的方式,虽然用起来方便,但是对于初学者非常不友好,完全不清楚是啥类型的,也不知道应该去调用这个类型的什么方法,或者去找这个类的帮助文档。

(有可能用仓颉的开放插件会好点,目前是装逼阶段,暂时不用)

强烈建议官方出示例代码,带上类型。

强烈建议官方出示例代码,带上类型。

强烈建议官方出示例代码,带上类型。

运行截图如下:

现在实现了一个接口/index,尝试再增加一个/stop,当访问stop的时候,app.exe退出。在MyServer里面增加一个Bool类型的run,如果run等于true,那么主线程就继续,否则就退出。代码如下:

class MyServer{let server:Serverlet run:Bool=truepublic init(){let ip=Config.Instance.getString("serverIP")            //读取iplet port=UInt16(Config.Instance.getInt("port"))                 //读取端口server=ServerBuilder().addr(ip).port(port).build()                                //返回一个Server对象}func service(){//注册监听server.distributor.register("/index", {httpContext =>httpContext.responseBuilder.body("Hello 仓颉!")})//注册监听server.distributor.register("/stop", {httpContext =>httpContext.responseBuilder.body("再见 仓颉!")run=false})// 启动服务server.serve()}}

 编译.......又报错了,大致意思,let 声明的变量一般不能修改,想修改需要给func增加mut。或者直接用var。这么说,用var 就行了。

再次编译,没有问题,访问/stop。页面返回正常,app.exe主线程退出。

完整代码:

import std.io.*
import std.fs.*
import std.collection.*
import std.convert.*
import net.http.*
import std.sync.*
import std.time.*
/**
*配置文件类
*/
class Config
{let map:HashMap<String,String>=HashMap<String,String>()    //存储配置文件的mapstatic let  Instance:Config=Config()                        //单例模式public init(){let fs=File.openRead('./config.ini')                    //创建一个文件流let sr=StringReader(fs)                                 //创建一个字符串流读取对象var s=sr.readln()??""                                   //读取一行,如果没有内容就是空while(s.size>0){                                        //如果这一行有数据let a=s.split("=")                                  //对这一行分割 key = valuemap[a[0]]=a[1]                                      //a[0]是key  ,a[1]是value,存储到hashmaps=sr.readln()??""                                   //读取下一行}println(map)                                            //输出一下fs.close()                                              //关闭流}public func getString(key:String):String{                   //获取一个字符串配置return map[key]}public func getInt(key:String):Int32{                       //获取一个整数配置return Int32.parse(map[key])                             //字符转换为整数}
}class MyServer{                                                 //自定义服务类let server:Server                                           //声明server对象,必须带类型,但是不能初始化,因为要从var run:Bool=truepublic init(){let ip=Config.Instance.getString("serverIP")            //读取iplet port=UInt16(Config.Instance.getInt("port"))         //读取端口需要转出UInt16 实际就是unsigend shortserver=ServerBuilder().addr(ip).port(port).build()                                //返回一个Server对象}func service(){//注册监听/index,反回一个字符串server.distributor.register("/index", {httpContext =>httpContext.responseBuilder.body("Hello 仓颉!")})server.distributor.register("/stop", {                  //注册监听/stop。访问以后,就会退出应用httpContext =>httpContext.responseBuilder.body("再见 仓颉!")run=false})server.serve()                                           // 启动服务}}main()
{println("cangjie http")                                                    let svr=MyServer()                                       //创建myserver对象spawn {svr.service()                                        //在子线程中运行http服务}while(svr.run){                                          //主线程增加退出条件,退了子线程也要退出println("cangjie http service ${svr.run}")sleep(Duration.second)  // sleep for 1s.}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1542003.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

动手学深度学习(李沐)PyTorch 第 1 章 引言

在线电子书 深度学习介绍 安装 使用conda环境 conda create -n d2l-zh python3.8 pip安装需要的包 pip install jupyter d2l torch torchvision下载代码并执行 wget https://zh-v2.d2l.ai/d2l-zh.zip unzip d2l-zh.zip jupyter notebookpip install rise如果不想使用jupyt…

数模打怪(九)之线性规划、非线性规划、多目标规划

一、线性规划 1、问题特征&#xff1a;有限的条件下&#xff0c;最大的收益 怎样分配&#xff0c;使……尽量多&#xff08;少&#xff09;&#xff0c;使利润最多&#xff0c;使最合理 变量都是一次项&#xff08;x&#xff09; 2、三个要素&#xff1a;决策变量、目标函数…

docker技术(上)

一、docker简介 Docker 是一个开源的应用容器引擎&#xff0c;于 2013 年由 Solomon Hykes 推出并开源。它基于 Go 语言开发&#xff0c;遵从 Apache2.0 协议。Docker 可以让开发者将应用及其依赖包打包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 或 Windows…

工程师 - Windows下打开PowerShell和CMD Prompt的若干方法

打开PowerShell 在Windows中&#xff0c;你可以通过以下几种方式来打开PowerShell&#xff1a; 1. 开始菜单&#xff08;Start Menu&#xff09;&#xff1a;点击“开始”按钮&#xff0c;然后在搜索栏中输入“PowerShell”。在搜索结果中&#xff0c;选择“Windows PowerShell…

【若依RuoYi-Vue | 项目实战】帝可得后台管理系统(二)

文章目录 一、人员管理1、需求说明2、生成基础代码&#xff08;1&#xff09;创建目录菜单&#xff08;2&#xff09;添加数据字典&#xff08;3&#xff09;配置代码生成信息&#xff08;4&#xff09;下载代码并导入项目 3、人员列表改造&#xff08;1&#xff09;基础页面&a…

最新免费域名申请

在互联网时代&#xff0c;每个码农都想拥有一个免费的域名&#xff0c;方便开发调试&#xff0c;也可用作自己网站等。如何申请一个免费的域名&#xff0c;时间上先错过了freenom&#xff0c;后面又错过nic.eu.org申请(现在申请时间长且很难通过)&#xff0c;直到最近又有免费的…

计算机网络(八) —— Udp协议

目录 一&#xff0c;再谈端口号 1.1 端口号 1.2 netsta命令 二&#xff0c;UDP协议 2.1 关于UDP 2.2 Udp协议格式 2.3 Udp协议特点 2.4 Udp的缓冲区 一&#xff0c;再谈端口号 http协议本质是“请求 - 响应”形式的协议&#xff0c;但是应用层需要先将数据交给传输层&…

pthread_cond_signal 和pthread_cond_wait

0、pthread_join()函数作用&#xff1a; pthread_join() 函数会一直阻塞调用它的线程&#xff0c;直至目标线程执行结束&#xff08;接收到目标线程的返回值&#xff09;&#xff0c;阻塞状态才会解除。如果 pthread_join() 函数成功等到了目标线程执行结束&#xff08;成功获取…

(Python) Structured Streaming读取Kafka源实时处理图像

Producer.py import cv2 from kafka import KafkaProducer import os import os.path as osp# Kafka 服务器地址 bootstrap_servers [xxx.xxx.xxx.xxx:9092] #terminal运行ifconfig可以查看localhost# 创建 Kafka 生产者 producer KafkaProducer(bootstrap_serversbootstrap…

什么是 GPT?通过图形化的方式来理解 Transformer 架构

Predict, sample, repeat 预测、取样、重复 GPT 是 Generative Pre-trained Transformer 的缩写。首个单词较为直接&#xff0c;它们是用来生成新文本的机器人。“Pre-trained” 指的是模型经历了从大量数据中学习的过程&#xff0c;这个词暗示了该模型还有进一步在特定任务中…

开关柜设备红外检测数据集

开关柜设备红外检测数据集 包含以下2个数据文件&#xff1a; /train&#xff1a;训练集 /valid&#xff1a;验证集 /test&#xff1a;测试集 README.txt&#xff1a;数据说明 【数据说明】检测目标以Pascal VOC格式进行标注&#xff0c;对每个图像进行以下预处理&#xff0c;统…

极度精简 Winows11 系统镜像!Tiny11 2311下载 - 支持苹果 M 芯片 Mac 安装 (ARM 精简版)!

最新推出的 Tiny11 是一款极端精简版 Windows 11 系统镜像&#xff0c;针对苹果 M 芯片 Mac 用户&#xff08;ARM 架构&#xff09;提供良好支持。Tiny11 内置了众多优化特性&#xff0c;如更小的安装体积和更快的启动速度&#xff0c;特别适合有特殊需求或老机型的用户。用户可…

华为HarmonyOS地图服务 7- 在地图上绘制标记

场景介绍 本章节将向您介绍如何在地图的指定位置添加标记以标识位置、商家、建筑等。 点标记用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。Map Kit提供的点标记功能(又称 Marker)封装了大量的触发事件,例如点击事件、长按事件、…

基于YOLO算法的网球运动实时分析-击球速度测量-击球次数(附源码)

这个项目通过分析视频中的网球运动员来测量他们的速度、击球速度以及击球次数。该项目使用YOLO&#xff08;You Only Look Once&#xff09;算法来检测球员和网球&#xff0c;并利用卷积神经网络&#xff08;CNNs&#xff09;来提取球场的关键点。此实战项目非常适合提升您的机…

VsCode C语言 SDL包配置 2024.9

写这篇文章的起因是&#xff0c;最近我需要使用 SDL 包&#xff0c;我懒得下载V-studio ,所以直接在VsCode 里配置C环境。我搞了好几个小时&#xff0c;啥都弄好了&#xff0c;但是一直被下面几个问题缠绕导致demo启动不了&#xff0c;现在我记录一下这奇葩的解决过程。所有路径…

Qt Debugging帮助文档

Qt中给断点添加条件&#xff1a; 示例1&#xff1a; 当i10时&#xff0c;程序中断 但不知道为什么&#xff0c;46行的条件没有生效&#xff0c;47行的条件生效了 给断点添加忽略次数&#xff1a; 在程序停止之前忽略该断点200次。 Breakpoints (Debugging with GDB)

Apache Doris 实践

Apache Doris 实践 官方使用指南&#xff1a;https://doris.incubator.apache.org/zh-CN/docs/install/source-install/compilation-with-docker/ 手动安装 下载二进制安装包https://apache-doris-releases.oss-accelerate.aliyuncs.com/apache-doris-2.1.5-bin-x64.tar.gz …

华润电力最新校招社招润择认知能力测评:逻辑推理数字计算语言理解高分攻略

​ 尊敬的求职者们&#xff0c; 在您准备加入华润电力这个大家庭之前&#xff0c;了解其招聘测评的详细流程和要求是至关重要的。以下是我们为您整理的测评系统核心内容&#xff0c;希望对您的求职之旅有所帮助。 测评系统概览 华润电力的招聘测评系统旨在全面评估求职者的认…

机器学习04-逻辑回归(python)-02原理与损失函数

1. 逻辑回归概念 逻辑回归&#xff08;Logistic Regression&#xff09; 是一种 分类模型&#xff0c;主要用于解决 二分类问题&#xff08;即分成两类&#xff0c;如是否通过、是否患病等&#xff09;。逻辑回归的目标是根据输入的特征预测一个 概率&#xff0c;这个概率值介于…

计算机毕业设计hadoop+spark+hive新能源汽车销售数据分析系统 二手车销量分析 新能源汽车推荐系统 可视化大屏 汽车爬虫 机器学习

《HadoopSparkHive新能源汽车销售数据分析系统》开题报告 一、选题背景与意义 1.1 选题背景 随着全球对环境保护意识的增强和能源结构的转型&#xff0c;新能源汽车市场迅速崛起。新能源汽车的销售数据不仅反映了市场趋势和消费者偏好&#xff0c;还为企业决策、政府监管和政…