Код Websocket работает на Windows, но не на Linux - PullRequest
0 голосов
/ 01 ноября 2018

Я использую тот же код; следующее работает в Windows, но будет работать правильно в 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")

Я попытался переустановить все модули (включая одну и ту же версию Python и websocket между Windows и Ubuntu), печать этого кода в системе Windows верна:

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

Но когда он запускается в Ubuntu и печатает, он пропускает некоторые операторы печати:

start
start run forever
close

Когда я отлаживал код в Ubuntu, я обнаружил, что основной поток останавливается в вызове self.ws.run_forever() и никогда не переходит к функции on_open. Тогда это вспыхивает.

1 Ответ

0 голосов
/ 01 ноября 2018

Вы используете две разные версии библиотеки, причем версия в Windows старше, чем версия 0.53. Начиная с версии 0.53, проект websocket различает поведение обратного вызова между связанными методами и обычными функциями .

Вы передаете связанные методы (self.on_open и self.on_ws_message), в этот момент аргумент ws равен и не передан в . Предполагается, что эти методы, как ожидается, будут иметь доступ к веб-сокету уже через свой экземпляр, возможно, потому, что ожидаемый вариант использования заключается в создании подкласса из класса сокетов .

К сожалению, это не задокументировано проектом, и изменение , похоже, вызывает проблемы у большего количества людей .

Так что для версии 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):
        print(message)
        self.ws.close()

    # ...

    def on_open(self):
        print("start open function")
        self._send_msg([1, "login", ["", ""]])

И вы можете обнаружить подобные проблемы, включив ведение журнала; модуль websocket регистрирует исключения, с которыми он сталкивается при обратных вызовах к регистратору logger.getLogger('websocket'). Быстрый способ увидеть эти проблемы - включить трассировку:

websocket.enableTrace(True)

, который добавляет обработчик ведения журнала только к этому объекту ведения журнала, включает logging.DEBUG отчеты об уровне для этого объекта и, кроме того, обеспечивает полное отображение данных сокета.

Или вы можете настроить ведение журнала для вывода сообщений в целом с помощью функции logging.basicConfig() :

import logging

logging.basicConfig()

, который позволяет вам видеть logging.ERROR сообщения уровня и выше.

При использовании последней опции, неисправленная версия кода печатается:

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

Вы можете проверить установленную версию websocket-client, напечатав websocket.__version__:

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