Websocket 代码适用于 Windows,但不适用于 Linux [英] Websocket code works on Windows but not Linux

查看:121
本文介绍了Websocket 代码适用于 Windows,但不适用于 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","re​​sult":true}关闭

但是当它在 Ubuntu 中运行时,当它确实打印时,它会遗漏一些打印语句:

开始开始永远运行关闭

当我在 Ubuntu 中调试代码时,我发现主线程在 self.ws.run_forever() 调用中停止并且永远不会跳转到 on_open 函数.然后它爆发了.

解决方案

您正在使用库的两个不同版本,Windows 上的版本低于 0.53 版本.从 0.53 版本开始,websocket 项目区分了绑定方法常规函数之间的回调行为.

您正在传入绑定方法(self.on_openself.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的版本:

<预><代码>>>>导入 websocket>>>websocket.__version__'0.54.0'

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆