Websocket 代码适用于 Windows,但不适用于 Linux [英] Websocket code works on Windows but not Linux
问题描述
我正在运行相同的代码;以下适用于 Windows,但可以在 Ubuntu (16.04) 上正常运行.
导入websocket导入json类什么(对象):def __init__(self):self.ws = websocket.WebSocketApp('wss://beijing.51nebula.com/',on_message=self.on_ws_message,on_open=self.on_open)def rin_forever(self):打印(开始永远运行")self.ws.run_forever()def on_ws_message(self, ws,message):打印(消息)self.ws.close()def _send_msg(self, params):call = {"id": 1, "method": "call",参数":参数}self.ws.send(json.dumps(call))def on_open(self, ws):打印(启动打开功能")self._send_msg([1, "登录", ["",""]])如果 __name__ == '__main__':ws=WhatEver()打印(开始")ws.rin_forever()打印(关闭")
我已经尝试重新安装所有模块(包括相同版本的 Python 和 websocket
在 Windows 和 Ubuntu 之间),此代码在 Windows 系统上的打印是正确的:
开始开始永远运行启动打开功能{"id":1,"jsonrpc":"2.0","result":true}关闭
但是当它在 Ubuntu 中运行时,当它确实打印时,它会遗漏一些打印语句:
开始开始永远运行关闭
当我在 Ubuntu 中调试代码时,我发现主线程在 self.ws.run_forever()
调用中停止并且永远不会跳转到 on_open
函数.然后它爆发了.
您正在使用库的两个不同版本,Windows 上的版本低于 0.53 版本.从 0.53 版本开始,websocket
项目区分了绑定方法和常规函数之间的回调行为.
您正在传入绑定方法(self.on_open
和 self.on_ws_message
),此时 ws
参数为 未传入.这些方法显然可以通过它们的实例访问 websocket,可能是因为预期的用例是 从套接字类创建一个子类.
不幸的是,项目没有记录这一点,并且更改 似乎给更多人带来了问题.
因此,对于 0.53 及更高版本,从回调中删除 ws
参数:
class WhatEver(object):def __init__(self):self.ws = websocket.WebSocketApp('wss://beijing.51nebula.com/',on_message=self.on_ws_message,on_open=self.on_open)# ...def on_ws_message(self, message):打印(消息)self.ws.close()# ...def on_open(self):打印(启动打开功能")self._send_msg([1, "登录", ["", ""]])
您可以通过启用日志记录来发现此类问题;websocket
模块将它在回调中遇到的异常记录到 logger.getLogger('websocket')
记录器.查看这些问题的一种快速方法是启用跟踪:
websocket.enableTrace(True)
只为该日志对象添加一个日志处理程序,为该对象打开 logging.DEBUG
级别的报告,此外还启用完整的套接字数据回显.
或者您可以使用 logging.basicConfig()
函数:
导入日志logging.basicConfig()
它可以让您查看 logging.ERROR
级别的消息和更高级别的消息.
使用后一个选项,代码的未更正版本打印出来:
开始开始永远运行错误:websocket:错误来自回调<绑定方法 WhatEver.on_open of <__main__.WhatEver object at 0x1119ec668>>:on_open() 缺少 1 个必需的位置参数:'ws'关闭
您可以通过打印websocket.__version__
来验证您安装的websocket-client
的版本:
I'm running the same code; the following works in Windows, but will run correctly on Ubuntu (16.04).
import websocket
import json
class WhatEver(object):
def __init__(self):
self.ws = websocket.WebSocketApp(
'wss://beijing.51nebula.com/',
on_message=self.on_ws_message,
on_open=self.on_open
)
def rin_forever(self):
print("start run forever")
self.ws.run_forever()
def on_ws_message(self, ws,message):
print (message)
self.ws.close()
def _send_msg(self, params):
call = {"id": 1, "method": "call",
"params": params}
self.ws.send(json.dumps(call))
def on_open(self, ws):
print("start open function")
self._send_msg([1, "login", ["",""]])
if __name__ == '__main__':
ws=WhatEver()
print("start")
ws.rin_forever()
print("close")
I've tried to reinstalled all modules (including the same version of Python and websocket
between both Windows and Ubuntu), the print of this code is correct on the Windows system:
start
start run forever
start open function
{"id":1,"jsonrpc":"2.0","result":true}
close
But when it run in Ubuntu, while it does print, it misses some print statements:
start
start run forever
close
When I debug the code in Ubuntu, I found that the main thread stops in the self.ws.run_forever()
call and never jumps to the on_open
function. Then it breaks out.
You are using two different versions of the library, with the version on Windows being older than version 0.53. As of version 0.53, the websocket
project differentiates callback behaviour between bound methods and regular functions.
You are passing in bound methods (self.on_open
and self.on_ws_message
), at which point the ws
argument is not passed in. Those methods are apparently expected to have access to the websocket already via their instance, probably because the expected use-case is to create a subclass from the socket class.
This is unfortunately not documented by the project, and the change appears to have been causing problems for more people.
So for version 0.53 and newer, drop the ws
argument from your callbacks:
class WhatEver(object):
def __init__(self):
self.ws = websocket.WebSocketApp(
'wss://beijing.51nebula.com/',
on_message=self.on_ws_message,
on_open=self.on_open
)
# ...
def on_ws_message(self, message):
print(message)
self.ws.close()
# ...
def on_open(self):
print("start open function")
self._send_msg([1, "login", ["", ""]])
And you can discover issues like these by enabling logging; the websocket
module logs exceptions it encounters in callbacks to the logger.getLogger('websocket')
logger. A quick way to see these issues is to enable tracing:
websocket.enableTrace(True)
which adds a logging handler just to that logging object, turns on logging.DEBUG
level reporting for that object and in addition enables full socket data echoing.
Or you can configure logging to output messages in general with the logging.basicConfig()
function:
import logging
logging.basicConfig()
which lets you see logging.ERROR
level messages and up.
With using the latter option, the uncorrected version of the code prints out:
start
start run forever
ERROR:websocket:error from callback <bound method WhatEver.on_open of <__main__.WhatEver object at 0x1119ec668>>: on_open() missing 1 required positional argument: 'ws'
close
You can verify the version of websocket-client
you have installed by printing websocket.__version__
:
>>> import websocket
>>> websocket.__version__
'0.54.0'
这篇关于Websocket 代码适用于 Windows,但不适用于 Linux的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!