Websocket在线程内部的异步循环中立即断开连接
我正在开发一个应用程序,该应用程序使用多个线程用于各种通信渠道。其中之一是Websocket,我正在使用Asyncio循环运行:
class Rotator():
def __init__(self):
# some irrelevant stuff here...
self._readThread = threading.Thread(target=self._ReadThread, daemon=True)
self._usbThread = threading.Thread(target=self._UsbThread, daemon=True)
self._webThread = threading.Thread(target=self._WebThread, daemon=True)
self._socketThread = threading.Thread(target=self._SocketThread, daemon=True)
self.InitializeRotator()
def InitializeRotator(self):
# some more irrelevant stuff here
self._readThread.start()
self._usbThread.start()
self._webThread.start()
self._socketThread.start()
# not including _ReadThread() and _UsbThread() as they are irrelevant in this context
def _WebThread(self): # including _WebThread() as illustration
handler_object = server.WebHttpRequestHandler
_httpServer = socketserver.TCPServer(("",self.webPort), handler_object)
_httpServer.serve_forever()
async def ws_handler(websocket, path):
data = await websocket.recv()
reply = f"Data recieved as: {data}!"
await websocket.send(reply)
def _SocketThread(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
start_server = websockets.serve(self.ws_handler, str(self.DHCPIP), 8000)
loop.run_until_complete(start_server)
loop.run_forever()
与此通信的前端JS代码:
var ws;
function startWebsocket() {
ws = new WebSocket('ws://192.168.200.76:8000')
ws.onopen = function(e){
console.log('Connection established')
ws.send('Connection established')
}
ws.onmessage = function(e){
console.log('websocket message event:', e)
}
ws.onclose = function(){
// connection closed, discard old websocket and create a new one in 5s
console.log('Connection lost, will reconnect in 5s...')
ws = null
setTimeout(startWebsocket, 5000)
}
}
startWebsocket();
包含前端的网页由_webthread()运行的服务器提供服务。问题在于,建立后的连接正在立即关闭。我假设问题是由异步/线程组合中的某些冲突引起的,因为我单独测试了服务器端代码,并且像魅力一样工作。我在做什么错?
I'm developing an application that uses multiple threads for various communication channels. One of them is websocket for which I'm using asyncio loop to run:
class Rotator():
def __init__(self):
# some irrelevant stuff here...
self._readThread = threading.Thread(target=self._ReadThread, daemon=True)
self._usbThread = threading.Thread(target=self._UsbThread, daemon=True)
self._webThread = threading.Thread(target=self._WebThread, daemon=True)
self._socketThread = threading.Thread(target=self._SocketThread, daemon=True)
self.InitializeRotator()
def InitializeRotator(self):
# some more irrelevant stuff here
self._readThread.start()
self._usbThread.start()
self._webThread.start()
self._socketThread.start()
# not including _ReadThread() and _UsbThread() as they are irrelevant in this context
def _WebThread(self): # including _WebThread() as illustration
handler_object = server.WebHttpRequestHandler
_httpServer = socketserver.TCPServer(("",self.webPort), handler_object)
_httpServer.serve_forever()
async def ws_handler(websocket, path):
data = await websocket.recv()
reply = f"Data recieved as: {data}!"
await websocket.send(reply)
def _SocketThread(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
start_server = websockets.serve(self.ws_handler, str(self.DHCPIP), 8000)
loop.run_until_complete(start_server)
loop.run_forever()
The frontend JS code that communicates with this is:
var ws;
function startWebsocket() {
ws = new WebSocket('ws://192.168.200.76:8000')
ws.onopen = function(e){
console.log('Connection established')
ws.send('Connection established')
}
ws.onmessage = function(e){
console.log('websocket message event:', e)
}
ws.onclose = function(){
// connection closed, discard old websocket and create a new one in 5s
console.log('Connection lost, will reconnect in 5s...')
ws = null
setTimeout(startWebsocket, 5000)
}
}
startWebsocket();
The web page that contains the frontend is served by the server run by _WebThread(). The issue is that the connection is being closed immediately after being established. I'm assuming the issue is caused by some conflict in the asyncio/thread combination, because I tested the server side code on its own and it worked like a charm. What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我重新创建了您的示例,并设法使用两个更改来修复它:
ws_handler缺少
self
参数。由于这是一个实例方法,因此实例本身将作为第一个参数传递。实际的Websocket对象将是第二个。在WS_HANDLER中,我在true 循环时添加了
。我在此处的文档中遵循了 https:// https:// websockets.readthedocs.io/en/stable/intro/tutorial1.html#bootstrap-the-server
最终结果:
我所做的其他更改是使用8000用作HTTP服务器的端口,Websocket的8001和“ localhost”,而不是192.168.200.76。但是我很确定这无关紧要
I recreated your example and managed to fix it using two changes:
ws_handler is missing the
self
parameter. Since it's an instance method, the instance itself will be passed as the first parameter. The actual websocket object will be the second one.in ws_handler I added a
while True
loop. I followed the example in the docs here https://websockets.readthedocs.io/en/stable/intro/tutorial1.html#bootstrap-the-serverfinal result:
Other changed that I made were to use 8000 as a port for the http server, 8001 for the websocket server and 'localhost' instead of 192.168.200.76. But I'm pretty sure that's not relevant