【问题标题】:Django Channels. How to respond to a WebSocket open request with a subprotocol?Django 频道。如何使用子协议响应 WebSocket 打开请求?
【发布时间】:2017-07-10 11:23:42
【问题描述】:

在 JavaScript 中,浏览器可以指定一个子协议作为 WebSocket 创建的第二个参数:

socket=new WebSocket(url, subprotocol)

使用 Chrome 进行实验,这会作为标头中的 Sec-WebSocket-Protocol 元素正确发送到服务器。

使用 Django 频道,一个简单的消费者

def ws_add(message):
    message.reply_channel.send({"accept": True,})

给出错误

与“xxx”的 WebSocket 连接失败:WebSocket 握手期间出错:发送了非空的“Sec-WebSocket-Protocol”标头,但未收到响应。

在 Django 频道的 ws_add 函数中接受该连接请求的正确方法是什么?

【问题讨论】:

    标签: python django websocket channels


    【解决方案1】:

    我遇到了同样的问题。 Websocket 规范说,如果客户端请求子协议,那么服务器必须响应让客户端知道它支持它。就我而言,子协议是“graphql-ws”

    在深入研究石墨烯代码后,最终发现这是一个简单的案例,只需将以下内容添加到设置中:

    CHANNELS_WS_PROTOCOLS = ["graphql-ws"]

    因此,只需将协议列表替换为您想要支持的任何内容即可。当然,一旦你这样做了,你实际上需要在服务器上实现子协议。

    【讨论】:

    • CHANNELS_WS_PROTOCOLS 不再支持 Channels 2.0 及更高版本。
    • 我应该添加哪些设置?
    【解决方案2】:

    您必须指定要在websocket.accept 消息中使用的子协议。例如,如果您将channels.generic.websocket.WebsocketConsumer 子类化(也适用于SyncConsumer)并使用Sec-WebSocket-Protocolmy-protocol

    class MyProtocolConsumer(WebsocketConsumer):
        def websocket_connect(self, message):
            self.base_send({"type": "websocket.accept", "subprotocol": "my-protocol"})
    

    【讨论】:

      【解决方案3】:

      如果现在有人像我一样偶然发现这个问题,我是这样解决的:

      当您像这样在消费者的连接方法上调用 self.accept() 时,您需要添加您在前端使用的 websocket 协议(在我的情况下为令牌)作为子协议参数:

      这就是我在前端创建 websocket 连接的方式:

      const websocket = new WebSocket('ws://127.0.0.1:8000/ws/', ['Token', 'user_secret_token'])
      

      这就是我的consumers.py 的样子:

      class MyConsumer(JsonWebsocketConsumer):
          def connect(self):
              self.room_group_name = 'example_room'
      
              # Join room group
              async_to_sync(self.channel_layer.group_add)(self.room_group_name, self.channel_name)
      
              # incorrect
              # self.accept()
      
              # correct
              self.accept('Token')
      

      Django 频道 2.4.0 Django 3.1.2

      【讨论】:

        猜你喜欢
        • 2012-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多