仓颉编程入门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 = value
            map[a[0]]=a[1]                                      //a[0]是key  ,a[1]是value,存储到hashmap
            s=sr.readln()??""                                   //读取下一行
        }
        println(map)                                            //输出一下
        fs.close()
 }

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

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

class MyServer{

    let server

    public init(){
        let ip=Config.Instance.getString("serverIP")            //读取ip
        let 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:Server
    let run:Bool=true
    public init(){
        let ip=Config.Instance.getString("serverIP")            //读取ip
        let 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>()    //存储配置文件的map

    static 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 = value
            map[a[0]]=a[1]                                      //a[0]是key  ,a[1]是value,存储到hashmap
            s=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=true
    public init(){
        let ip=Config.Instance.getString("serverIP")            //读取ip
        let port=UInt16(Config.Instance.getInt("port"))         //读取端口需要转出UInt16 实际就是unsigend short
        server=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.mfbz.cn/a/883042.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode[c、cmake]:某些引用可能丢失,因为在 查找所有引用 启动时,工作区分析不完整

1. 问题描述 vscode 调试一个c语言工程&#xff0c;利用cmake编译调试&#xff0c;通过cmakelist.txt传递宏标识来条件编译代码。但是&#xff0c;在build之后&#xff0c;传递的宏标识不能让vscode自动转跳相关代码&#xff0c;猜测为代码分析时未包含宏标识。提示&#xff1a…

双向链表的基本结构及功能实现

1.基本结构: 双向链表是一种链表数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含三个部分&#xff1a; (1).数据域&#xff1a;存储节点的数据 (2).前驱指针:指向前一个节点 (3).后驱指针:指向下一个节点 2.基本特性&#xff1a; 双向链接: 与单向链表…

不在同一局域网怎么远程桌面?非局域网环境下,实现远程桌面访问的5个方法分享!

非局域网环境下&#xff0c;怎么远程桌面&#xff1f;还能做到吗&#xff1f; 在企业管理中&#xff0c;远程桌面访问已成为提高工作效率、实现跨地域协同工作的关键工具。 然而&#xff0c;当被控端与控制端不在同一局域网时&#xff0c;如何实现远程桌面连接成为了许多企业…

【Android】页面启动耗时统计流程梳理

文章基于Android 11 写在前面&#xff1a; 最近的文章都会放流程图&#xff0c;时序图之类的图片&#xff0c;解释下为什么这么做&#xff1a; 图片的好处&#xff1a; 流程清晰&#xff0c;一目了然很多代码&#xff0c;如同老太太的裹脚布&#xff0c;又臭又长。影响理解&a…

【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台

一、介绍 果蔬识别系统&#xff0c;本系统使用Python作为主要开发语言&#xff0c;通过收集了12种常见的水果和蔬菜&#xff08;‘土豆’, ‘圣女果’, ‘大白菜’, ‘大葱’, ‘梨’, ‘胡萝卜’, ‘芒果’, ‘苹果’, ‘西红柿’, ‘韭菜’, ‘香蕉’, ‘黄瓜’&#xff09;…

基于SpringBoot+Vue的校园快递代取管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

CNN网络训练WISDM数据集:模型仿真及可视化分析

卷积神经网络&#xff08;CNN&#xff09;因其强大的特征提取能力和深度学习架构而备受推崇&#xff0c;CNN在处理图像数据时展现出的卓越性能&#xff0c;使其成为解决各种视觉识别任务的首选工具。WISDM数据集是一个广泛用于运动估计研究的基准数据集&#xff0c;它包含了多个…

14年408-计算机网络

第一题&#xff1a; 解析&#xff1a;OSI体系结构 OSI由下至上依次是&#xff1a;物理层-网络链路层-网络层-运输层-会话层-表示层-应用层。 因此直接为会话层提供服务的是运输层。答案选C 第二题&#xff1a; 解析&#xff1a;数据链路层-交换机的自学习和帧转发 主机a1向交换…

关于养育孩子的一点想法

我们许多人总是很看重结果&#xff0c;不重视过程&#xff0c;在工作中有时候确实会这样&#xff0c;但这种想法会经常蔓延到生活中&#xff0c;比如养育孩子&#xff0c;我们总有一个目标&#xff0c;希望他成才&#xff0c;实现某种理想&#xff0c;弥补你人生中的某种缺憾&a…

开通微信视频号直播的流程

首先我们要了解什么是视频号&#xff1f; 视频号其实就是腾讯家的“抖音”/“快手”&#xff0c;可以发布视频和直播&#xff08;包括直播带货&#xff09;。 微信视频号不同于订阅号、服务号&#xff0c;它是一个全新的内容记录与创作平台&#xff0c;也是一个了解他人、了解…

AIGC专栏15——CogVideoX-Fun详解 支持图文生视频 拓展CogVideoX到256~1024任意分辨率生成

AIGC专栏15——CogVideoX-Fun详解 支持图&文生视频 拓展CogVideoX到256&#xff5e;1024任意分辨率生成 学习前言项目特点生成效果相关地址汇总源码下载地址 CogVideoX-Fun详解技术储备Diffusion Transformer (DiT)Stable Diffusion 3EasyAnimate-I2V 算法细节算法组成InPa…

计算机出现msvcp140.dll丢失的6种解决方法,亲测有效

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcp140.dll丢失”。这个错误通常会导致某些应用程序无法正常运行&#xff0c;给用户带来困扰。本文将总结6种解决msvcp140.dll丢失的方法&#xff0c;帮助大家轻松解决这个问题。 一&…

随机梯度下降的学习

梯度下降&#xff08;Gradient-Descent&#xff09; 在机器学习的旅途中&#xff0c;不可避免需要与它打交道&#xff0c;那么该如何初步理解它的用途呢&#xff1f; 好的&#xff0c;想象你在一个山谷中&#xff0c;想要找到最低点&#xff08;山谷的底部&#xff09;。你现…

如何使用 Bittly 为基于 HTTP 的 API 快速创建 UI 操作界面

在开发 Web 应用或服务时&#xff0c;通常会提供不同数量的 API 接口给客户端或其他第三方使用&#xff0c; 当 API 数量达到一定数量的时候&#xff0c;在处理接口间的调用链以及参数关系时就会变得异常麻烦。 在这种情况下便可通过 Bittly 的面板功能将这些 API 结构进行组装…

电子元件制造5G智能工厂物联数字孪生平台,推进制造业数字化转型

5G智能工厂与物联数字孪生平台的融合应用&#xff0c;不仅为电容器制造业注入了新的活力&#xff0c;更为整个制造业的数字化转型树立了新的标杆。电子元件制造过程中&#xff0c;数字孪生平台通过实时监测生产线的各个环节&#xff0c;实现了生产流程的可视化监控。管理人员可…

es的封装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、类和接口介绍0.封装思想1.es的操作分类 二、创建索引1.成员变量2.构造函数2.添加字段3.发送请求4.创建索引总体代码 三.插入数据四.删除数据五.查询数据 前…

大数据新视界 --大数据大厂之探索ES:大数据时代的高效搜索引擎实战攻略

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

java 获取集合a比集合b多出来的对象元素

public class OrderListEntity {/*** deprecated 对象集合的处理* param aData 集合a* param bData 集合b* return 返回集合a比集合b多出来的部分, 通过id判断*/public static List<OrderListEntity> AHasMoreThanBData(List<OrderListEntity> aData, List<Ord…

AI日常绘画【国庆海报】:盛世迎华诞,Flux国庆节海报制作教程

大家好我是安琪&#xff01;&#xff01;&#xff01; 马上就要到祖国母亲的节日了&#xff0c;想想心里都美滋滋的&#xff0c;终于可以放松一下了。相信AI绘画关于国庆主题肯定也会精彩纷呈吧&#xff0c;今天和大家分享几组关于国庆海报的制作教程。 本文使用基于Flux的相关…

西安交大曹相湧、孟德宇教授团队最新成果┆HSIGene: 一个用于高光谱图像生成的基础模型(含详细视频解读)

目录 论文简介 1. 团队介绍 2. 研究背景及主要贡献 3. 方法 4. 实验及结果 5. 总结与展望 6. 论文介绍视频 参考文献 论文简介 本推文详细介绍了一篇西安交通大学孟德宇教授与曹相湧副教授团队最新论文《HSIGene: A Foundation Model For Hyperspectral Image Gener…