El código de Websocket funciona en Windows pero no en Linux

Estoy ejecutando el mismo código; Lo siguiente funciona en Windows, pero se ejecutará correctamente en 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") 

He intentado reinstalar todos los módulos (incluida la misma versión de Python y websocket entre Windows y Ubuntu), la impresión de este código es correcta en el sistema de Windows:

 start start run forever start open function {"id":1,"jsonrpc":"2.0","result":true} close 

Pero cuando se ejecuta en Ubuntu, mientras se imprime, pierde algunas declaraciones de impresión:

 start start run forever close 

Cuando depuro el código en Ubuntu, encontré que el hilo principal se detiene en la llamada self.ws.run_forever() y nunca salta a la función on_open . Entonces estalla.

Está utilizando dos versiones diferentes de la biblioteca, y la versión en Windows es anterior a la versión 0.53. A partir de la versión 0.53, el proyecto websocket diferencia el comportamiento de la callback entre los métodos enlazados y las funciones regulares .

Está pasando los métodos enlazados ( self.on_open y self.on_ws_message ), en cuyo punto no se pasa el argumento ws . Al parecer, se espera que esos métodos tengan acceso al websocket a través de su instancia, probablemente porque el caso de uso esperado es crear una subclase a partir de la clase socket .

Desafortunadamente, esto no está documentado en el proyecto y el cambio parece haber estado causando problemas a más personas .

Entonces, para la versión 0.53 y más reciente, elimine el argumento ws de sus devoluciones de llamada:

 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", ["", ""]]) 

Y puede descubrir problemas como estos habilitando el registro; El módulo websocket registra las excepciones que encuentra en las devoluciones de llamada al logger.getLogger('websocket') . Una forma rápida de ver estos problemas es habilitar el rastreo:

 websocket.enableTrace(True) 

que agrega un controlador de registro solo a ese objeto de registro, activa el logging.DEBUG nivel logging.DEBUG para ese objeto y, además, permite el eco completo de los datos de socket.

O puede configurar el registro para dar salida a los mensajes en general con la función logging.basicConfig() :

 import logging logging.basicConfig() 

que le permite ver los mensajes de nivel logging.ERROR y arriba.

Con el uso de la última opción, se imprime la versión no corregida del código:

 start start run forever ERROR:websocket:error from callback >: on_open() missing 1 required positional argument: 'ws' close 

Puede verificar la versión de websocket-client que ha instalado imprimiendo websocket.__version__ :

 >>> import websocket >>> websocket.__version__ '0.54.0'