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

news2024/11/13 18:06:14

上一篇配置了仓颉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.coloradmin.cn/o/2153158.html

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

相关文章

Redis——持久化策略

Redis持久化 Redis的读写操作都是在内存上&#xff0c;所以Redis性能高。 但是当重启的时候&#xff0c;或者因为特殊情况导致Redis崩了&#xff0c;就可能导致数据的丢失。 所以Redis采取了持久化的机制&#xff0c;重启的时候利用之间持久化的文件实现数据的恢复。 Redis提…

python怎么打开编辑器

1、在电脑开始菜单中点击所有程序&#xff0c;找到Python程序&#xff0c;点击其中idle。 2、然后点击左上角的“File”&#xff0c;打开菜单&#xff0c;在下拉菜单中选择“New File”选项&#xff0c;就可打开python编辑器了。 3、在打开的python编辑器中就可以输入自己想写的…

Qwen大型语言模型系列的最新成果 ----Qwen2.5

通义千问2.5-7B-Instruct-GGUF 模型库 (modelscope.cn) apt install git-lfsgit lfs installgit clone https://www.modelscope.cn/qwen/Qwen2.5-7B-Instruct-GGUF.git

从源码到平台:食堂采购系统与供应链管理平台的开发详解

本篇文章&#xff0c;小编将从技术角度探讨如何基于源码开发一个食堂采购系统&#xff0c;并结合供应链管理平台的实现策略&#xff0c;帮助开发者与企业深入了解该系统的开发流程与关键要点。 一、食堂采购系统源码开发概述 食堂采购系统作为餐饮企业管理食材采购、库存以及…

综述论文“Towards Personalized Federated Learning”分享

综述论文“Towards Personalized Federated Learning”分享 文章目录 综述论文“Towards Personalized Federated Learning”分享I. 引言A. 联邦学习的分类B. 个性化联邦学习的动机C. 贡献 II. 个性化联邦学习的策略策略I&#xff1a;全局模型个性化策略II&#xff1a;学习个性…

无人机集群路径规划:麻雀搜索算法(Sparrow Search Algorithm, SSA)​求解无人机集群路径规划,提供MATLAB代码

一、单个无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径&#xff0c;使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一&#xff0c;它可以通过算法和模型来确定无人机的航迹&#xff0c;以避开障碍物、优化…

2024年中国研究生数学建模竞赛【华为杯】C题-数据驱动下磁性元件的磁芯损耗建模(代码+讲解+成品论文+答疑)

2024年中国研究生数学建模竞赛&#xff0c;即华为杯&#xff0c;研赛正式开赛了&#xff0c;本次比赛white学长团队选择了C题&#xff0c;各位小伙伴可以根据自己的擅长选择合适题目&#xff0c;比赛过程中请注意以下时间节点&#xff1a; 华为杯比赛时间节点 一、背景 随着国民…

大小端字节序 和 内存高低地址顺序

目录 1. 大小端字节序 1.1 什么是大小端字节序&#xff1f; 1.2 为什么有大小端字节序? 1.3 习题&#xff1a;用程序结果判断大端小端 2. 各种易混淆的高低地址顺序 2.1 监视窗口的地址表示【计算机标准展示方式】 2.2 横向地址表示 2.3 一个字节 与 多个字节 的地址…

在腾讯云申请https(我得是腾讯云服务器),通过宝塔设置https

参考 一键 HTTPS&#xff1a;https://cloud.tencent.com/document/product/400/58062 DNS 验证&#xff1a;https://cloud.tencent.com/document/product/400/54500?from_cn_redirect1 申请免费的证书 访问连接&#xff1a;https://console.cloud.tencent.com/ssl 点击页…

Python数据分析与可视化(Python绘图详解)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【更新】上市公司绿色专利申请及授权数据(2000-2023年)

一、数据介绍 数据名称&#xff1a;上市公司-绿色专利申请、授权数据 数据范围&#xff1a;A股上市公司 数据年份&#xff1a;2000-2023年 数据样本&#xff1a;61243条 数据来源&#xff1a;国家知识产权局 二、数据指标 年份股票代码股票简称行业名称行业代码省份城市区…

SQL - 基础语法

SQL作为一种操作命令集, 以其丰富的功能受到业内人士的广泛欢迎, 成为提升数据库操作效率的保障。SQL Server数据库的应用&#xff0c;能够有效提升数据请求与返回的速度&#xff0c;有效应对复杂任务的处理&#xff0c;是提升工作效率的关键。 由于SQL Servers数据库管理系统…

★pwn 更改pwn题libc保姆级教程★

★pwn 更改pwn题libc保姆级教程★ &#x1f35a;前言&#x1f95f;安装&#x1f95f;glibc-all-in-one下载与调整libc&#x1f95f;patchelf更改libc&#x1f95f;clibc的使用与分析 &#x1f35a;前言 现在市面上有很多关于改libc的教程&#xff0c;但是基本有以下几个问题&a…

IDEA中实现springboot热部署

IDEA中实现springboot热部署 热部署: 每一次修改代码后会自动更新&#xff0c;无需每次重启 依赖(pom.xml) 修改后记得Reload一下 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><…

微信小程序IOS真机调试-onPullDownRefresh和onReachBottom不生效

切换真机调试2.0版本 勾选JS编译成ES5 如果使用了 uniapp&#xff0c;这里也需要勾选 重新启动

系统架构笔记-3-信息系统基础知识

知识要点 结构化方法&#xff1a;结构是指系统内各个组成要素之间的相互联系、相互作用的框架。结构化方法也称为生命周期法&#xff0c;是一种传统的信息系统开发方法&#xff0c;由结构化分析、结构化设计、结构化程序设计三部分有机组合而成&#xff0c;精髓是自顶向下、逐…

Java笔试面试题AI答之设计模式(2)

文章目录 6. 什么是单例模式&#xff0c;以及他解决的问题&#xff0c;应用的环境 &#xff1f;解决的问题应用的环境实现方式 7. 什么是工厂模式&#xff0c;以及他解决的问题&#xff0c;应用的环境 &#xff1f;工厂模式简述工厂模式解决的问题工厂模式的应用环境工厂模式的…

高算力芯片的发展

最近参与了2024年北京AI芯片峰会&#xff0c;虽然是讲AI芯片&#xff0c;但因为目前算力主要讲的是智能算力&#xff0c;所以&#xff0c;针对高算力芯片的发展趋势有重点的讲解。之前没有很系统关注这块&#xff0c;这次算是做了全面了解。下面&#xff0c;借用峰会的一些内容…

九章云极DataCanvas公司荣获2024年服贸会“科技创新服务示范案例”

9月15日&#xff0c;2024年中国国际服务贸易交易会&#xff08;服贸会&#xff09;示范案例交流会暨颁奖典礼在北京国家会议中心举行&#xff0c;九章云极DataCanvas 公司自研的DataCanvas Alaya NeW智算操作系统凭借卓越的AI创新实力、前瞻性的市场布局以及突破性的技术革新成…

uniapp中使用echarts 完整步骤,包括报错以及解决方案

在我们日常可能会有小程序中要使用echarts&#xff0c;我今天总结了一下整个引入的步骤 首先echarts - DCloud 插件市场在插件市场里面导入进项目&#xff0c;我这边用的是vue3的以及主要开发小程序&#xff0c;就直接放我的案例了 按照上面的步骤&#xff0c;在样式部分这样…