Websocket code works on Windows but not Linux

孤街醉人 提交于 2019-12-08 13:30:59

问题


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.


回答1:


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'


来源:https://stackoverflow.com/questions/53100975/websocket-code-works-on-windows-but-not-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!