赞
踩
当使用websocket进行实时显示数据时,由于接收数据会阻塞线程,而此时await send_text(msg)
无法发送,如果在新的线程中调用发送,是无法调用await send_text()函数的,而如果在recv_text()后再发送,因为recive_text()会阻塞,致使之后服务器不断推送的数据无法发送,所以,经过多方尝试后,可以使用心跳的方式巧妙地实现不断的推送,在web浏览器端,不断的发送心跳,而在服务器端,当接收到的是心跳的信息后,跳过转发指令,直接读取数据。
如下:
服务端:
- @app.websocket("/ws/{client_id}")
- async def websocket_endpoint(websocket: WebSocket, client_id: str):
- global manager
- global isWhile
- await manager.connect(client_id,websocket)
- print("client %s: connected." % client_id)
- try:
- while True:
- dataFromExplor = await manager.recivemessage(websocket) #从网页socket中获取到的值;
- jsonData = json.loads(dataFromExplor) #json字符串解析成json对象;
- if jsonData["cmd"] != "Heart.Beat": #若不是心跳,则需要将指令发送出去;通过心跳机制,以使recv不再完全阻塞,疏通了接收数据。
- channelPacket = packetChannelData(client_id,jsonData,{}) #以 真实数据长度(4字节) + 真实数据(json字符串) 的格式进行封装;
- manager.sendDataToWebServer(channelPacket) #通过管道将数据发送给TcpSocket线程;
- await manager.trySendFromWebServer() #尝试接收返回的数据并发送回web浏览器客户端;
- except WebSocketDisconnect:
- print("client %s exit!" % client_id)
- manager.disconnect(client_id,websocket)
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
客户端:
- var ws
- var timerId = -1
- window.onload = function()
- {
- if(timerId >= 0){
- window.clearInterval(timerId) //先关闭之前的定时器;
- }
- if ("WebSocket" in window){ //表明此浏览器支持 WebSocket!
- // 打开一个 web socket;
- var client_id = document.getElementById("username").value + "."+Date.now()
- ws = new WebSocket(`ws://192.168.110.37:8001/ws/${client_id}`);
- ws.onopen = function(){ //表明WebSocket已连接上;
- //alert("连接成功!");
- var cmdJson = {"cmd":"Fetch.Clients","params":{}}
- ws.send(JSON.stringify(cmdJson))
- timerId = self.setInterval("heartbeat()",100)
- }
- ws.onmessage = function(event){ //当服务器推送消息时,浏览器收到消息;
- var msg = event.data
- //alert(msg)
- var obj = JSON.parse(msg)
- var cmd = obj['query']['cmd']
- var reply = obj['reply'] //jsonObject;
- if(cmd == "Fetch.Clients"){
- document.getElementById("client_ids").innerHTML = JSON.stringify(reply)
- return;
- }
-
- if(cmd == "Session.Error"){
- document.getElementById("session_errmsg").innerHTML = JSON.stringify(reply)
- return ;
- }
- if(cmd == "Session.Status"){
- document.getElementById("session_status").innerHTML = JSON.stringify(reply)
- return ;
- }
- if(cmd == "Session.System"){
- document.getElementById("session_sys").innerHTML = JSON.stringify(reply)
- return ;
- }
- if(cmd == "Session.Zone"){
- document.getElementById("session_zone").innerHTML = JSON.stringify(reply)
- return ;
- }
- if(cmd == "Session.Alarm"){
- document.getElementById("session_alarm").innerHTML = JSON.stringify(reply)
- return ;
- }
- if(cmd == "Session.Profile"){
- document.getElementById("session_profile").innerHTML = JSON.stringify(reply)
- return ;
- }
- };
- ws.onclose = function(){ //关闭WebSocket连接时,可以做些处理;
- //alert("连接已关闭...");
- if(timerId >= 0){
- window.clearInterval(timerId) //先关闭之前的定时器;
- }
- };
- }
- else { // 浏览器不支持 WebSocket;
- alert("您的浏览器不支持 WebSocket!");
- }
- }
- function heartbeat(){
- var cmdJson = {"cmd":"Heart.Beat","params":{}}
- ws.send(JSON.stringify(cmdJson))
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。