当前位置: 首页 > news >正文

【LuatOS】基于WebSocket的同步请求框架

0x00 缘起

由于使用LuatOS PC模拟器发起快速且海量HTTP请求(1000 次/秒)时,会耗尽PC的TCP连接资源,而无法进行继续进行访问请求。故使用WebSocket搭建类似于HTTP的“同步请求相应”的通信框架,以实现与HTTP类似的功能。

0x01 服务端

服务端使用Go搭建WebSocket服务器,其代码示意如下:

package mainimport ("log""net""net/http""time"
)var upgrader = websocket.Upgrader{ReadBufferSize:  1024,WriteBufferSize: 1024,
}// HandleEchoHello 进行简单回应
func HandleEchoHello(w http.ResponseWriter, r *http.Request) {conn, err := upgrader.Upgrade(w, r, nil)if err != nil {fmt.Println("升级到WebSocket失败:", err)return}defer conn.Close()for {_, message, err := conn.ReadMessage()if err != nil {fmt.Println("读取消息失败:", err)break}receiveTimestamp := time.Now().UnixNano()sendTimestamp, err := strconv.ParseInt(string(message), 10, 64)if err != nil {sendTimestamp = 0}delayTimestampNs := float64(receiveTimestamp - sendTimestamp)delayTimestampMs := delayTimestampNs / 1000000.0res := "sendTime: " + string(message) + ", " + "receiveTime:" + strconv.FormatInt(receiveTimestamp, 10) + ", delay: " + strconv.FormatFloat(delayTimestampMs, 'f', -1, 64) + "ms"// 返回值r, _ := json.Marshal(map[string]interface{}{"message":    res,"statusCode": 200,})// 发送回客户端的消息err = conn.WriteMessage(websocket.TextMessage, r)if err != nil {fmt.Println("发送消息失败:", err)break}}
}func main() {http.HandleFunc("/", HandleEchoHello)err := http.ListenAndServe(":8080", nil)if err != nil {log.Panic("WebSocket服务器启动失败:", err.Error())return}log.Println("WebSocket服务器运行在:http://localhost:8080")
}

上述Go代码在8080端口开启了一个WebSocket服务器等待连接,客户端连接服务器后可以发送自己的纳秒时间戳测试其传输时间,若LuatOS PC模拟器不支持纳秒,可以为LuatOS PC模拟器添加高精度时间戳获取功能或者使用Lua Socket所提供的微秒。

0x02 客户端

以下代码是使用WebSocket所封装的同步请求框架,其在发送数据后必须等到服务器返回数据后才会进行下一次发送作业。

-- SyncWebScoket.lualocal SWS = {}
SWS.__index = SWSlocal tag = "SyncWebScoket"function SWS.create(address, port)local wsc_recv_buffer = {} local wsc_send_success_tag = falselocal wsc_recv_success_tag = falselocal wsc = nillocal connected = falselocal self = setmetatable({}, SWS) function self:connect()if connected thenlog.info(tag, "Already connected.")return connectedendlog.info(tag, "Connecting to " .. address .. ":" .. port)if not wsc thenwsc = websocket.create(nil, address .. ":" .. port)wsc:on(function(wsc, event, data, fin, optcode)if event == "recv" thentable.insert(wsc_recv_buffer, data)if fin == 1 then               wsc_recv_success_tag = true endendif event == "conack" then connected = trueendif event == "disconnect" thenconnected = falseendif event == "sent" thenwsc_send_success_tag = trueendend)endwsc:connect()local count = 0while not connected dosys.wait(100)count = count + 1if count >= 10 thenbreakendendif connected thenlog.info(tag, "Connected")wsc:autoreconn(true, 3000) elselog.error(tag, "Failed To Connect.")endreturn connectedend-- 断开连接方法function self:disconnect()log.info(tag, "Disconnecting from " .. address .. ":" .. port)wsc:autoreconn(false)wsc:close()wsc = nilconnected = falsereturn trueendfunction self:send(data)if not connected thenlog.error(tag, "Cannot send data, not connected.")return falseendwsc_recv_buffer = {}wsc_send_success_tag = falsewsc_recv_success_tag = falsewsc:send(data)local count = 0while not wsc_send_success_tag dosys.wait(1)count = count + 1if count >= 1000 thenbreakendendif not wsc_send_success_tag thenlog.error(tag, "Send Data Failed, Please Check The Internet.")return falseendlocal count = 0while not wsc_recv_success_tag dosys.wait(1)count = count + 1if count >= 1000 thenbreakendendif not wsc_recv_success_tag thenlog.error(tag, "Receive Data Failed.")return falseendlocal message = ""                        for _, value in ipairs(wsc_recv_buffer) do if type(value) ~= "string" thenlog.error(tag, "Error parsing WebSocket data!")return falseendmessage = message .. valueendreturn true, messageendreturn self
endreturn SWS

上述代码为基于WebSocket的同步请求框架SyncWebSocket,在main.lua的使用如下:

-- main.luaPROJECT = "sync_websocket_test"
VERSION = "1.0.0"_G.sys = require("sys")local TAG = PROJECTlocal swc = require("SyncWebScoket") Host = "127.0.0.1"
Port = "8080"local swsc = swc.create(Host, Port) sys.taskInit(function()sys.waitUntil("IP_READY")  -- 默认都等到联网成功-- 连接SyncWebSocketwhile not swsc:connect() dosys.wait(100)endlog.info(TAG, "SWSC 连接成功!")sys.publish("swsc_conok")
end)sys.taskInit(function()sys.waitUntil("swsc_conok")log.info(TAG, "开始服务端与客户端传输时间测试...")local startTime = timeplus.getnanosecond()for i = 1, 10000, 1 do -- 发送10次,测试一下传输时间local result, message = swsc:send(timeplus.getnanosecond())if result thenlog.info(TAG, tostring(i) .. " Message: " .. message)endendlocal endTime = timeplus.getnanosecond()-- 计算时间差并转换为毫秒local startTimeNum = tonumber(startTime)local endTimeNum = tonumber(endTime)-- 计算差值并转换为毫秒local timeDifferenceMs = (endTimeNum - startTimeNum) / 1000000000.0print("consumeTime: " .. endTime .. "-" .. startTime .. "=" .. tostring(timeDifferenceMs) .. "s")
end)sys.run()

上述main.lua代码展示了SyncWebSocket框架的使用方法,其中timeplus.getnanosecond()是为LuatOS编译添加的获取纳秒字符串的方法,可以替换成其他时间戳库进行测试,客户端以及服务端代码仅作为思路说明,不对其运行效果进行保证。

0x03 资源

  • LuatOS WebSoket 官方文档

0x04 后记

  • 己欲立而立人,己欲达而达人。

相关文章:

【LuatOS】基于WebSocket的同步请求框架

0x00 缘起 由于使用LuatOS PC模拟器发起快速且海量HTTP请求(1000 次/秒)时,会耗尽PC的TCP连接资源,而无法进行继续进行访问请求。故使用WebSocket搭建类似于HTTP的“同步请求相应”的通信框架,以实现与HTTP类似的功能…...

架构师考试系列(8)论文专题:信息系统安全设计

摘要 2021年4月,我公司承接了一款健康养老系统项目,旨在提供以健康养老为核心的管理平台。本文探讨了如何在系统开发中贯彻安全优先原则,保障系统的安全性和保密性。系统包括健康档案、照护计划、服务审计、健康状况跟踪、费用管理等功能模块。我作为系统架构设计师,负责了…...

浙大一附院就医:分享给大家工作久了关节疼的就医经验,腱鞘炎

症状描述:日常生活不影响,但左手手腕往前或者往后扭曲力度过大时会有痛感。 医嘱详情:腱鞘炎,可能是工作键盘打字久了导致,开了三盒药贴,一盒三片,一共9片,另外再买一个比较硬的护腕…...

如何降低 PCIe RTT?

以下是一些降低 PCIe RTT(往返时间)的方法: 硬件方面4: 优化主板设计与布局: 合理分配 PCIe 通道:确保不同的 PCIe 设备被分配到独立的、互不干扰的 PCIe 通道上。例如,如果主板上有多个 PCIe 插…...

数据结构之二叉树--前序,中序,后序详解(含源码)

二叉树 二叉树不能轻易用断言,因为树一定有空 二叉树链式结构的实现 在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。 typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType _data;struct B…...

红黑树及MySQL 基础架构

红黑树简介及左旋、右旋、变色 红黑树(Red Black Tree)是一种自平衡二叉搜索树(二叉查找树),是一种特殊的二叉搜索树,在进行插入和删除时通过特定操作保持二叉树自身的平衡,从而获得较高的查找性能。 红黑树的平衡操作通过左旋、右旋和变色来…...

大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…...

QJson-趟过的各种坑(先坑后用法)

QJson-趟过的各种坑【先坑后用法】 Chapter1 QJson-趟过的各种坑【先坑后用法】一、不能处理大数据量,如果你的数据量有百兆左右(特别是有的小伙伴还喜欢json格式化输出的),不要用Qjson,否则会报错 DocumentTooLarge二、json格式化输出1.构建…...

基于STM32的hx711称重模块使用

欢迎入群共同学习交流 时间记录:2024/11/9 一、知识点记录 1、hx711 1)HX711是一款高精度压力传感器专用的24位模数转换芯片,主要功能是将测得的微小电压信号放大到可以被微控制器读取的范围 2)工作电压2.6-5.5V 3)引…...

Nginx独立项目相关配置说明

配置前说明 1. 部署环境为https环境的,除华为云表态托管等都需要此配置,如cloud。 2. 部署环境为https环境的,可以使用api.js直接访问后端服务,无需此配置。 3. 转发的后台服务接口需要和后台人员沟通确认一致。详细配置说明 **…...

Nuxt3之使用lighthouse性能测试及性能优化实操

lighthouse性能测试工具 什么是 LightHouse 呢 Lighthouse 是一个开源的自动化工具,用于提高网页的质量。可以通过浏览器的开发者工具运行,也可以作为命令行工具或 Node.js 模块集成到持续集成系统中。Lighthouse 可以帮助开发者: 性能优化…...

‌webdriver.Chrome()参数简介

webdriver.Chrome()参数‌如下: ‌executable_path‌:指定ChromeDriver的路径,若未设置且系统环境变量中已配置,则会自动寻找。‌options‌:通过webdriver.ChromeOptions()创建,用于设定浏览器的启动选项&…...

Ubuntu如何更换环境中的Python版本

Ubuntu Python 版本迁移指南 卸载 Python 3.8 # 移除 Python 3.8 sudo apt remove python3.8# 清理依赖 sudo apt autoremove# 清理缓存 sudo apt clean安装 Python 3.10 # 更新软件包列表 sudo apt update# 安装软件源管理工具 sudo apt install software-properties-commo…...

python-字符串中大写字母转小写,小写字母转大写

平时我们进行大小写转换基本都是使用upper和lower函数,使用方法: s Hello,Python123#大写转小写 s.lower() -->hello,python123#小写转大写 s.upper() -->HELLO,PYTHON123但是如果想把字符串中的大写字母转成小写,小写字母转成大写&a…...

前端学习之ES6+

1.ES6是什么 ES6,全称是ECMAScript 6,是JavaScript语言的下一代标准,由ECMA国际组织在2015年6月正式发布。ES6也被称作ECMAScript 2015,从这个版本开始,ECMA组织决定每年发布一个新的ECMAScript版本,以使J…...

yolov10的几种权重文件

1.官方提供的几种模型权重文件 YOLOv10官网提供的权重文件是训练好的网络各层的权值,这些权值是通过训练集训练出来的。‌一旦网络训练完成,应用时只需加载这些权值,而不再需要原始的训练集。这意味着,如果你已经配置好了环境&am…...

FPGA视频GTH 8b/10b编解码转PCIE3.0传输,基于XDMA中断架构,提供工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案我已有的 GT 高速接口解决方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图输入Sensor之-->芯片解码的HDMI视频数据组包基于GTH高速接口的视频传输架构GTH IP 简介GTH 基本结构GTH 发送和接收处理…...

C++类和对象 (下)

文章目录 前言一. 再探构造函数初始化列表特性总结练习 二. 类型转换2.1 隐式类型转换2.2 临时对象具有常性2.3 explicit关键字2.4 多参数类型转化 三. static成员概念特性练习 四. 友元概念特性 五. 内部类概念特性 六. 匿名对象概念特性 七. 对象拷贝时的编译器优化END 前言 …...

网络层5——IPV6

目录 一、IPv6 vs IPv4 1、对IPv6主要变化 2、IPv4 vs IPv6 二、IPv6基本首部 1、版本——4位 2、通信量类——8位 3、流标号——20位 4、有效载荷长度——16位 5、下一个首部——8位 6、跳数限制——8位 7、源 、 目的地址——128位 8、扩展首部 三、IPv6地址 1…...

【wpf】ResourceDictionary 字典资源的用法

如果你的字典资源是写在启动项目的App.xaml里 <Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source"pack://application:,,,/YourNonStartupProject;component/Resources/SharedResour…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...