个人搭建网站教程,首次建设网站流程图,修改网站图标,宁夏高端网站建设0x00 缘起
由于使用LuatOS PC模拟器发起快速且海量HTTP请求#xff08;1000 次/秒#xff09;时#xff0c;会耗尽PC的TCP连接资源#xff0c;而无法进行继续进行访问请求。故使用WebSocket搭建类似于HTTP的“同步请求相应”的通信框架#xff0c;以实现与HTTP类似的功能…0x00 缘起
由于使用LuatOS PC模拟器发起快速且海量HTTP请求1000 次/秒时会耗尽PC的TCP连接资源而无法进行继续进行访问请求。故使用WebSocket搭建类似于HTTP的“同步请求相应”的通信框架以实现与HTTP类似的功能。
0x01 服务端
服务端使用Go搭建WebSocket服务器其代码示意如下
package mainimport (lognetnet/httptime
)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 SyncWebScoketfunction 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 8080local 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 后记 己欲立而立人己欲达而达人。