【问题标题】:Data rendering on Django Channels from Python websocket来自 Python websocket 的 Django 通道上的数据渲染
【发布时间】:2019-01-28 15:23:39
【问题描述】:

我正在尝试将数据从我的 python websocket 客户端发送到 Django Channels 服务器。

我正在使用python web socket client。

my-websocket.py

def on_message(ws, message):
    print (message)

def on_error(ws, error):
    print ("eroror:", error)

def on_close(ws):
    print ("### closed ###")
    # Attemp to reconnect with 2 seconds interval
    time.sleep(2)
    initiate()

def on_open(ws):
    print ("### Initiating new websocket connectipython my-websocket.pyon ###")
    def run(*args):
        for i in range(30000):
            # Sending message with 1 second intervall
            time.sleep(1)
            ws.send("Hello %d" % i)
            # ws.send(json.dumps("Hello %d" % i))
        time.sleep(1)
        ws.close()
        print ("thread terminating...")
    _thread.start_new_thread(run, ())

def initiate():
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://localhost:8000/ws/power/room/",
        on_message = on_message,
        on_error = on_error,
        on_close = on_close)
    ws.on_open = on_open

    ws.run_forever()

if __name__ == "__main__":
    initiate()

我的 Django Channels 消费者是

consumer.py

class EchoConsumer(WebsocketConsumer):

    def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'power_%s' % self.room_name

        # Join room group
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )

        self.accept()

    def disconnect(self, close_code):
        # Leave room group
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

        # Receive message from WebSocket

    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

        # Receive message from room group

    def chat_message(self, event):
        message = event['message']

        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message
        }))

错误

WebSocket HANDSHAKING /ws/power/room/ [127.0.0.1:54591]
WebSocket CONNECT /ws/power/room/ [127.0.0.1:54591]
Exception inside application: Expecting value: line 1 column 1 (char 0)
  File "C:\Program Files\Python37\lib\site-packages\channels\sessions.py", line 179, in __call__
    return await self.inner(receive, self.send)
  File "C:\Program Files\Python37\lib\site-packages\channels\middleware.py", line 41, in coroutine_call
    await inner_instance(receive, send)
  File "C:\Program Files\Python37\lib\site-packages\channels\consumer.py", line 59, in __call__
    [receive, self.channel_receive], self.dispatch
  File "C:\Program Files\Python37\lib\site-packages\channels\utils.py", line 52, in await_many_dispatch
    await dispatch(result)
  File "C:\Program Files\Python37\lib\site-packages\asgiref\sync.py", line 108, in __call__
    return await asyncio.wait_for(future, timeout=None)
  File "C:\Program Files\Python37\lib\asyncio\tasks.py", line 388, in wait_for
    return await fut
  File "C:\Program Files\Python37\lib\concurrent\futures\thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "C:\Program Files\Python37\lib\site-packages\channels\db.py", line 13, in thread_handler
    return super().thread_handler(loop, *args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\asgiref\sync.py", line 123, in thread_handler
    return self.func(*args, **kwargs)
  File "C:\Program Files\Python37\lib\site-packages\channels\consumer.py", line 105, in dispatch
    handler(message)
  File "C:\Program Files\Python37\lib\site-packages\channels\generic\websocket.py", line 60, in websocket_receive
    self.receive(text_data=message["text"])
  File "C:\Users\Suleman\PycharmProjects\power\myChannels\consumers.py", line 41, in receive
    text_data_json = json.loads(text_data)
  File "C:\Program Files\Python37\lib\json\__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "C:\Program Files\Python37\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Program Files\Python37\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
  Expecting value: line 1 column 1 (char 0)
WebSocket DISCONNECT /ws/power/room/ [127.0.0.1:54591]

从错误中可以看出,我可以在 websocket 之间进行握手,但数据未在网页上呈现。

【问题讨论】:

  • Django-Channels 是否与websocket-client 兼容?我在 .js 文件中使用重新连接 websockets,用于与 Django Channels 通信。
  • 我不知道。我在任何地方都找不到这个答案;因此,在这里寻求帮助。
  • 你好。我认为您应该使用一个框架,其中包括直接在 javascript 文件或 Django 模板中重新连接 websocket,该框架使用 websocket 桥和routing.py 连接到 Django 通道。

标签: python django websocket channels


【解决方案1】:

您可以尝试将async 添加到您的chat_message 函数as per the documentation 中,看看是否有帮助?

async def chat_message(self, event):
    """
    Called when someone has messaged our chat.
    """
    ...

如果您没有正确使用同步和异步,那么事情将不会以协调的方式执行。如果您正确使用 async 和 await,那么您的 webscocket 应该有时间建立握手并在关闭之前开始传输数据。

此外,您的 group_send 可能需要更改以包含 await,而且我认为您可能过早关闭 async_to_sync(self.channel_layer.group_send)。

# Send message to room group
async_to_sync(
   await self.channel_layer.group_send(
        room.group_name,
       {
            'type': 'chat_message',
            'message': message
        }
    )
)

【讨论】:

  • 不,它不工作,仍然面临错误-----发送:b'\x81\x87\xf5\x0e5\x9b\xbdkY\xf7\x9a.\x05'发送:b' \x88\x82\x19\xe4\xabB\x1a\x0c' ### closed ### send: b'\x81\x87`EV:( :V\x0feg' .run at 0x000001EED6A5EF28> Traceback(最近一次调用最后一次):文件“my-websocket.py”,第 24 行,运行中
  • 好的,您能否更新您的问题以反映新代码?
  • 如果我使用 Django Channels 教程的聊天程序,它可以运行,但是我无法从 web socket 客户端发送消息。
  • 再次,我不确定您是否应该使用 websocket-client。我认为您应该在 .js 文件或 Django 模板中添加重新连接 WebSocket:npmjs.com/package/reconnecting-websocket。然后你需要使用“发送”和“接收”功能。
【解决方案2】:

仔细看日志,好像是websocket连接上了:

 WebSocket CONNECT /ws/power/room/ [127.0.0.1:54591]

但是消费者 receive 方法引发 JSON 异常,当然是因为它的参数 text_data 是 None。

【讨论】:

    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 2019-10-07
    • 2019-04-29
    • 1970-01-01
    相关资源
    最近更新 更多