鸿蒙开发仓颉语言【在工程中使用Hyperion TCP框架】

news2024/11/14 19:00:14

3. 在工程中使用Hyperion TCP框架

3.1 导入Hyperion TCP框架的静态库

在工程的module.json中引入Hyperion TCP框架的静态库:

  "package_requires": {
    "package_option": {
      "hyperion_hyperion.buffer": "${path_to_hyperion_project}/build/release/hyperion/hyperion.buffer.cjo",
      "hyperion_hyperion.logadapter": "${path_to_hyperion_project}/build/release/hyperion/hyperion.logadapter.cjo",
      "hyperion_hyperion.objectpool": "${path_to_hyperion_project}/build/release/hyperion/hyperion.objectpool.cjo",
      "hyperion_hyperion.threadpool": "${path_to_hyperion_project}/build/release/hyperion/hyperion.threadpool.cjo",
      "hyperion_hyperion.transport": "${path_to_hyperion_project}/build/release/hyperion/hyperion.transport.cjo"
    },
    "path_option": []
  },

3.2 TCP框架客户端和服务端支持的配置

1. 客户端和服务端都支持的配置
Socket配置
TcpSocketOptions类的属性作用
prop port: UInt16设置TCP服务端的监听端口
prop receiveBufferSize: ?Int64接收缓冲区大小
prop sendBufferSizeVal: ?Int64发送缓冲区大小
prop noDelay: ?BoolTCP_NODELAY选项
prop linger: ?DurationSO_LINGER选项
prop readTimeout: ?DurationSocket读超时时间
prop writeTimeout: ?DurationSocket写超时时间
prop idleTimeout: Duration连接空闲超时时间
Hyperion TCP框架配置
TcpSocketOptions类的属性作用默认值
prop asyncWrite: Bool是否开启每个连接一个写线程true
prop sliceExceedBuffer: Bool是否通过切片方式减少数组拷贝true
prop maxMessageSizeInBytes: Int64支持处理的消息的最大长度64M
prop bufferAllocateSize: Int64分配的ByteBuffer大小8192
* prop usePooledBufferAllocator: Bool是否将ByteBuffer池化重用false
* prop maxPooledBuffers: Int64缓存的ByteBuffer的最大数量2048

标*的为实验性质配置,目前不建议在生产环境中修改这些配置的默认值

2. 服务端特有的配置
EndpointConfig类的属性作用
prop address: String设置TCP服务端的监听地址
prop backlogSize: ?Int64backlog队列大小
prop reuseAddress: ?BoolSO_REUSE_ADDR选项
prop sendBufferSizeVal: ?Int64发送缓冲区大小
prop reusePort: ?BoolSO_REUSE_PORT选项
prop acceptTimeout: ?DurationAccept超时时间
3. 客户端特有的配置
ClientEndpointConfig类的属性作用
prop host: String设置TCP服务端的监听地址
prop minConnections: Int64连接池的最小连接数
prop maxConnections: Int64连接池的最大连接数
prop waitConnectionTimeout: Duration等待连接超时时间

3.3 实现一个回写消息的服务端

3.3.1 需求

需求: 回写客户端发送过来的字符串消息
传输报文:4字节的字符串二进制数组长度+字符串的二进制数组

长度说明
4字节使用utf8编码的字符串的Byte数组的长度
n字节使用utf8编码的字符串的Byte数组
3.3.2 服务定义

编写一个回写字符串消息的服务:

public class EchoService {

    public func processMessage(message: String) {
        return message
    }

}
3.3.3 实现编解码和调用服务的IoFilter

编写一个IoFilter,将入栈消息交给EchoService处理:

public class EchoHanlder <: SingularMessageIoFilter {
    private let service = EchoService()

    /**
     * 处理入栈消息
     */
    public func processInboundMessage(context: IoFilterContext, session: Session, inMessage: Any): Unit {
        if (let Some(text) <- inMessage as String) {
            println("Received Message: ${text}")
            // 调用业务处理逻辑
            let result = service.processMessage(text)
            context.offerMessage(result)
        } else {
            let exception = Exception("Only accept string message")
            context.exceptionCaught(exception)
        }
    }

    public func processInboundException(context: IoFilterContext, session: Session, ex: Exception) {
        context.exceptionCaught(ex)
    }

    /**
     *  处理出栈消息
     */
    public func processOutboundMessage(context: IoFilterContext, session: Session, outMessage: Any): Unit {
        // 转交给下一个IoFilter处理
        context.offerMessage(outMessage)
    }

    public func processOutboundException(context: IoFilterContext, session: Session, ex: Exception): Unit {
        context.exceptionCaught(ex)
    }

    public func toString() {
        return "EchoHanlder"
    }
}

编写一个将字符串转换为二进制数组的IoFilter,由于hyperion.transport.ByteAndStringCodec已经实现该功能,可以直接选用ByteAndStringCodec
编写一个给二进制数组添加报文长度的IoFilter,由于hyperion.transport.LengthBasedFrameCodec已经实现该功能,可以直接选用LengthBasedFrameCodec

3.3.4 编写TCP服务端

编写服务端,并添加编解码和调用服务使用的IoFilter:

    let config = EndpointConfig()
    config.address = "127.0.0.1"
    config.port = 8090

    // 服务端使用的线程池
    let threadPool = ThreadPoolFactory.createThreadPool(3, 128, 4096, Duration.minute * 2)
    // 创建服务端Endpoint
    let tcpEndpoint = TcpEndpoint(config, threadPool)

    // 使用4字节记录报文长度的编解码器
    let lengthFrameEncoder = LengthBasedFrameEncoder(4)
    let lengthFrameDecoder = LengthBasedFrameDecoder(4)
    // 判断报文是否包含完整消息的MessageCompletedHandler
    tcpEndpoint.setMessageCompletedHandler(lengthFrameDecoder)
    // 解析报文长度的IoFilter
    tcpEndpoint.addFilter(LengthBasedFrameCodec(lengthFrameEncoder, lengthFrameDecoder))
    // 字符串和二进制数组转换的IoFilter
    tcpEndpoint.addFilter(ByteAndStringCodec())
    // 调用服务的IoFilter
    tcpEndpoint.addFilter(EchoHanlder())

    // 启动服务端Endpoint
    tcpEndpoint.start()

3.4 实现一个收发字符串消息的客户端

3.4.1 需求

需求: 向服务端发送字符串,并收取字符串响应
传输报文:4字节的字符串二进制数组长度+字符串的二进制数组

长度说明
4字节使用utf8编码的字符串的Byte数组的长度
n字节使用utf8编码的字符串的Byte数组
3.4.2 实现接收响应消息的类
public class EchoResponse {
    private var exception: ?Exception = None

    private var message: ?String = None

    public func setException(exception: Exception) {
        this.exception = exception
    }

    public func getException(): ?Exception {
        return this.exception
    }

    public func setMessage(message: String) {
        this.message = message
    }

    public func getMessage(): String {
        if (let Some(ex) <- exception) {
            throw ex
        }

        if (let Some(message) <- message) {
            return message
        }

        throw Exception("No response message")
    }
}
3.4.3 实现编解码和调用服务的IoFilter

编写一个IoFilter,将收取到的消息放入队列中,以便后续获取使用:

public class ClientHandler <: SingularMessageIoFilter {
    private let messages = BlockingQueue<EchoResponse>()

    public func takeMessage(): String {
        let echoResponse = messages.dequeue()
        return echoResponse.getMessage()
    }

    public func takeMessage(timeout: Duration): ?String {
        if (let Some(echoResponse) <- messages.dequeue(timeout)) {
            return echoResponse.getMessage()
        }

        return None
    }

    /**
     * 处理入栈消息
     */
    public func processInboundMessage(context: IoFilterContext, session: Session, inMessage: Any): Unit {
        let echoResponse = EchoResponse()
        if (let Some(text) <- inMessage as String) {
            echoResponse.setMessage(text)
        } else {
            let exception = Exception("Only accept string message")
            echoResponse.setException(exception)
        }

        // 添加到messages队列中,不再交给下一个IoFilter处理
        messages.enqueue(echoResponse)
    }

    public func processInboundException(context: IoFilterContext, session: Session, ex: Exception) {
        let echoResponse = EchoResponse()
        echoResponse.setException(ex)
        // 添加到messages队列中,不再交给下一个IoFilter处理
        messages.enqueue(echoResponse)
    }

    /**
     *  处理出栈消息
     */
    public func processOutboundMessage(context: IoFilterContext, session: Session, outMessage: Any): Unit {
        if (let Some(text) <- outMessage as String) {
            // 直接发给下个IoFilter处理
            context.offerMessage(text)
        } else {
            let exception = Exception("Only accept string message")
            context.exceptionCaught(exception)
        }
    }

    public func processOutboundException(context: IoFilterContext, session: Session, ex: Exception): Unit {
        context.exceptionCaught(ex)
    }

    public func toString() {
        return "ClientHanlder"
    }
}

编写一个将字符串转换为二进制数组的IoFilter,由于hyperion.transport.ByteAndStringCodec已经实现该功能,可以直接选用ByteAndStringCodec
编写一个给二进制数组添加报文长度的IoFilter,由于hyperion.transport.LengthBasedFrameCodec已经实现该功能,可以直接选用LengthBasedFrameCodec

3.4.4 编写TCP客户端

编写服务端,并添加编解码和调用服务使用的IoFilter:

    let config = ClientEndpointConfig()
    config.host = "127.0.0.1"
    config.port = 8090

    // 客户端使用的线程池
    let threadPool = ThreadPoolFactory.createThreadPool(3, 128, 4096, Duration.minute * 2)
    // 创建客户端Endpoint
    let tcpEndpoint = ClientTcpEndpoint(config, threadPool)

    // 使用4字节记录报文长度的编解码器
    let lengthFrameEncoder = LengthBasedFrameEncoder(4)
    let lengthFrameDecoder = LengthBasedFrameDecoder(4)
    // 判断报文是否包含完整消息的MessageCompletedHandler
    tcpEndpoint.setMessageCompletedHandler(lengthFrameDecoder)
    // 解析报文长度的IoFilter
    tcpEndpoint.addFilter(LengthBasedFrameCodec(lengthFrameEncoder, lengthFrameDecoder))
    // 字符串和二进制数组转换的IoFilter
    tcpEndpoint.addFilter(ByteAndStringCodec())
    // 接收消息并缓存消息到队列中的IoFilter
    let clientHandler = ClientHandler()
    tcpEndpoint.addFilter(clientHandler)
     // 启动客户端Endpoint
    tcpEndpoint.start()

    // 创建会话,并使用会话发送消息
    try (session = tcpEndpoint.createSession()) {
        // 发送消息,并收取对应的响应
        for (i in 1..=100) {
            let message = "Message${i}"
            println("Send message: ${message}")
            session.writeAndFlushMessage(message)
            let receiveMsg = clientHandler.takeMessage()
            println("Client receive message: ${receiveMsg}")
        }
    }

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
在这里插入图片描述
在这里插入图片描述
除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档笔记

在这里插入图片描述

鸿蒙【基础+实战项目】视频

在这里插入图片描述

鸿蒙面经

在这里插入图片描述
为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自取喔!谢谢大家观看!

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

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

相关文章

SpringBoot整合SSE技术详解

Hi &#x1f44b;, Im shy SpringBoot整合SSE技术详解 1. 引言 在现代Web应用中,实时通信变得越来越重要。Server-Sent Events (SSE)是一种允许服务器向客户端推送数据的技术,为实现实时更新提供了一种简单而有效的方法。本文将详细介绍如何在SpringBoot中整合SSE,并探讨S…

java之回合制游戏以及如何优化

public class Role {private String name;private int blood;//空参public Role() {}//包含全部参数的构造public Role(String name, int blood) {this.name name;this.blood blood;}public String getName() {return name;}public void setName(String name) {this.name na…

单细胞生物都能学会的树莓派4B实现路由器

本文参考自CSDN用户羟基氟化宇的畅玩树莓派4B&#xff08;二&#xff09;树莓派搭建无线路由器&#xff08;支持5GWIFI&#xff09; 本文补充其中的细节及遇到的问题。 本文提及的代码&#xff0c;均需在树莓派终端中运行。 〇、硬件准备 树莓派4B一个、网线一根。 &#xff…

【NoSQL数据库】Redis学习笔记

一、缓存穿透 缓存穿透是先查Redis&#xff0c;发现缓存中没有数据&#xff0c;再查数据库。然而&#xff0c;如果查询的数据在数据库中也不存在&#xff0c;那么每次查询都会绕过缓存&#xff0c;直接落到数据库上。 解决方案一、缓存空数据 查询Redis缓存&#xff1a;首先查…

前后端分离项目部署,vue--nagix发布部署,.net--API发布部署。

目录 Nginx免安装部署文件包准备一、vue前端部署1、修改http.js2、npm run build 编译项目3、解压Nginx免安装,修改nginx.conf二、.net后端发布部署1、编辑appsetting.json,配置跨域请求2、配置WebApi,点击发布3、配置文件发布到那个文件夹4、配置发布相关选项5、点击保存,…

中电金信:AI数据服务

01 方案简介 AI数据服务解决方案为泛娱乐、电子商务、交通出行等行业提供数据处理、数据分析、AI模型训练等服务&#xff0c;通过自主研发的IDSC自动化数据服务平台与客户业务流程无缝衔接&#xff0c;实现超低延时的实时数据处理支持。 02 应用场景 智能医疗&#xff1a; 通…

Ribbon负载均衡与内核原理

什么是Ribbon? 目前主流的负载方案分为两种&#xff1a; 集中式负载均衡&#xff0c;在消费者和服务提供方中间使用独立的代理方式进行负载&#xff0c;有硬件的&#xff08;比如F5&#xff09;&#xff0c;也有软件的&#xff08;Nginx&#xff09;客户端根据自己的请求做负…

transformers进行学习率调整lr_scheduler(warmup)

一、get_scheduler实现warmup 1、warmup基本思想 Warmup&#xff08;预热&#xff09;是深度学习训练中的一种技巧&#xff0c;旨在逐步增加学习率以稳定训练过程&#xff0c;特别是在训练的早期阶段。它主要用于防止在训练初期因学习率过大导致的模型参数剧烈波动或不稳定。…

力扣经典题目之->设计循环队列 的超详细讲解与实现

一&#xff1a;题目 二&#xff1a;思路讲解 前提&#xff1a; a&#xff1a;本文采取数组来实现队列去解决题目 b&#xff1a;开辟k1个空间&#xff0c;front指向队首&#xff0c;rear指向队尾的后一个&#xff0c;rear这样会更好的判空和判满 以下根据pop和push感受满和空…

python如何调用matlab python package库matlab转python安装包调用使用简单示例

说明(废话) 之前没有进行python调用过matlab&#xff0c;前面用matlab engine for python可以通过调用matlab的源码文件的形式可以调用工程&#xff0c;但是这又有一个问题&#xff0c;就是在运行的时候必须提供python和matlab的全部源码 该文章是通过matlab源码转python pack…

FPGA JTAG最小系统 EP2C5T144C8N

FPGA的文档没有相应的基础还真不容易看懂&#xff0c;下面是B站上对FPGA文档的解读(本文非对文档解读&#xff0c;只是为个人记录第三期&#xff1a;CycloneIV E最小系统板设计&#xff08;一&#xff09;从Datasheet上获取FPGA的基本参数_哔哩哔哩_bilibili 电源部份 核心电…

PlantUML 语法、图标和示例

基本语法 关键字 声明参与者的几个关键字 actor、boundary、control、entity、database、collections、participant 箭头样式 我们可以通过&#xff0c;修改箭头样式&#xff0c;来表达不一样的意思&#xff1a; 表示一条丢失的消息&#xff1a;末尾加 x让箭头只有上半部…

[UE 虚幻引擎] DTHmacSha 蓝图HMACSHA加密算法插件说明

本插件可以在虚幻引擎中使用蓝图对字符串和文件进行HMACSHA加密。 1.节点说明 HMACSHA一共有5种加密方式&#xff0c;分辨是 HMAC SHA-1&#xff0c; HMAC SHA-224&#xff0c;HMAC SHA-256&#xff0c;HMAC SHA-384&#xff0c;HMAC SHA-512。 本插件对每种加密方式提供3个节点…

C++初学者指南-6.函数对象--函数对象

C初学者指南-6.函数对象–函数对象 文章目录 C初学者指南-6.函数对象--函数对象函数对象示例&#xff1a;区间查询区间内的查找区间划分(分组) 指南标准库函数对象比较算术运算 函数对象 提供至少一个成员函数重载 operator() 的对象 class Multiplier {int m_; public:// cons…

MATLAB绘制方波、锯齿波、三角波、正弦波和余弦波、

一、引言 MATLAB是一种具有很强的数值计算和数据可视化软件&#xff0c;提供了许多内置函数来简化数学运算和图形的快速生成。在MATLAB中&#xff0c;你可以使用多种方法来快速绘制正弦波、方波和三角波。以下是一些基本的示例&#xff0c;展示了如何使用MATLAB的命令来实现正弦…

centos系统mysql主从复制(一主一从)

文章目录 mysql80主从复制&#xff08;一主一从&#xff09;一、环境二、服务器master1操作1.开启二进制日志2. 创建复制用户3. 服务器 slave1操作4. 在主数据库中添加数据 mysql80主从复制&#xff08;一主一从&#xff09; 一、环境 准备两台服务器&#xff0c;都进行以下操…

入门C语言Day15——关系条件逻辑操作符

今天来学习操作符中的一些内容&#xff0c;主要讲的是关系&条件&逻辑操作符 1.关系操作符 首先要来了解一下什么是关系操作符&#xff0c;关系操作符其实就是关系运算符&#xff0c;关系运算符又和关系表达式有关。 C语言中用于比较的表达式&#xff0c;就被称为 “关…

google、windows自带语音识别中英文等实时字幕使用

2、自带实时字幕 1&#xff09;google浏览器自带 实时字幕 设置里可以设置&#xff1a; 有视频声音播放会弹出黑色文本框 下载其他语言包-比如中文&#xff1a; 测试 2&#xff09;windows11 辅助功能 实时字幕 &#xff08;直接快捷键打开&#xff1a;Win Ctrl L&#…

openmv学习笔记(24电赛笔记)

#opemv代码烧录清除详解 openmv的代码脱离IDE运行程序&#xff0c;只需要在IDE中将代码烧录道flash里面&#xff0c;断开IDE连接&#xff0c;上电之后&#xff0c;会自动执行main.py中的程序&#xff0c;IDE烧录的时候&#xff0c;会默认将程序后缀保存为 .py文件。 ​​​​​…

go语言day16 runtime包 临界资源 sync包

深入理解Java虚拟机到底是什么_java虚拟机是什么-CSDN博客 Golang-100-Days/Day16-20(Go语言基础进阶)/day17_Go语言并发Goroutine.md at master rubyhan1314/Golang-100-Days GitHub runtime 类似jvm&#xff0c;runtime包也提供了垃圾回收功能。 并且jvm实现了对线程创建销…