通过django视图将数据发送到django渠道组

Ada*_*rsh 6 django python-3.x django-channels

TL; DR

想要这个流程:

                     ws://...
websocket client 1 <-----------> websocket client 2
                         ^
                         |
                       server (send messages via views)
Run Code Online (Sandbox Code Playgroud)

所以我有以下内容:

views.py

def alarm(request):
    layer = get_channel_layer()
    async_to_sync(layer.group_send)('events', {
    'type': 'events.alarm',
    'content': 'triggered'
    })
    return HttpResponse('<p>Done</p>')
Run Code Online (Sandbox Code Playgroud)

consumers.py

class EventConsumer(JsonWebsocketConsumer):
  def connect(self):
    print('inside EventConsumer connect()')
    async_to_sync(self.channel_layer.group_add)(
        'events',
        self.channel_name
    )
    self.accept()

  def disconnect(self, close_code):
    print('inside EventConsumer disconnect()')
    print("Closed websocket with code: ", close_code)
    async_to_sync(self.channel_layer.group_discard)(
        'events',
        self.channel_name
    )
    self.close()

  def receive_json(self, content, **kwargs):
    print('inside EventConsumer receive_json()')
    print("Received event: {}".format(content))
    self.send_json(content)

  def events_alarm(self, event):
    print('inside EventConsumer events_alarm()')
    self.send_json(
        {
            'type': 'events.alarm',
            'content': event['content']
        }
    )
Run Code Online (Sandbox Code Playgroud)

在routing.py中

application = ProtocolTypeRouter({
    'websocket': AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                chat.routing.websocket_urlpatterns,

            )
        )
    ),
})
Run Code Online (Sandbox Code Playgroud)

其中websocket_urlpatterns是

websocket_urlpatterns = [
url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
url(r'^ws/event/$', consumers.EventConsumer),
]
Run Code Online (Sandbox Code Playgroud)

urls.py

urlpatterns = [
    url(r'^alarm/$', alarm, name='alarm'),
]
Run Code Online (Sandbox Code Playgroud)

当我调用时/alarm/,只发出HTTP请求,并且消息不会发送到websocket

以下是日志:

[2018/09/26 18:59:12] HTTP GET /alarm/ 200 [0.07, 127.0.0.1:60124]
Run Code Online (Sandbox Code Playgroud)

我的目的是让django视图发送到一个组(用例将是服务器向组中的所有连接成员发送通知).

我在这里缺少什么设置.

我正在运行django频道2.1.3,redis作为后端.CHANNELS_LAYERS等都已设置完毕.

参考链接:

  1. 向django频道中的群组发送消息2
  2. github问题
  3. 渠道文档

编辑:我可以从视图中使用websocket-client发送消息

from websocket import create_connection
ws = create_connection("ws://url")
ws.send("Hello, World")
Run Code Online (Sandbox Code Playgroud)

但是可以在不使用上述内容的情况下发送(不要创建连接)吗?

源代码:chat-app

Ada*_*rsh 5

将@Matthaus Woolard的概念讲得很清楚。

所以这就是问题所在:

当我尝试从django视图发送消息时,客户端已断开连接。这是由于服务器在代码更改后重新启动而发生的。我刷新了浏览器,它开始工作。

愚蠢的错误

总结一下:

如果是同步使用者,请在connect()中添加以下内容:

async_to_sync(self.channel_layer.group_add)('events', self.channel_name)
Run Code Online (Sandbox Code Playgroud)

或将此添加为“异步消费者”:

await self.channel_layer.group_add('events', self.channel_name)
Run Code Online (Sandbox Code Playgroud)

创建如下视图:

def alarm(request):
   layer = get_channel_layer()
   async_to_sync(layer.group_send)('events', {
           'type': 'events.alarm',
           'content': 'triggered'
        })
   return HttpResponse('<p>Done</p>')
Run Code Online (Sandbox Code Playgroud)