【发布时间】:2019-03-02 15:12:52
【问题描述】:
TL;DR
想要这个流程:
ws://...
websocket client 1 <-----------> websocket client 2
^
|
server (send messages via views)
所以我有以下内容:
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>')
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']
}
)
在routing.py中
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns,
)
)
),
})
websocket_urlpatterns 在哪里
websocket_urlpatterns = [
url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
url(r'^ws/event/$', consumers.EventConsumer),
]
urls.py
urlpatterns = [
url(r'^alarm/$', alarm, name='alarm'),
]
当我调用 /alarm/ 时,只发出 HTTP 请求,消息不会发送到 websocket
以下是日志:
[2018/09/26 18:59:12] HTTP GET /alarm/ 200 [0.07, 127.0.0.1:60124]
我的目的是让 django 视图发送到一个组(用例是服务器向组中所有连接的成员发送通知)。
我在这里缺少什么设置。
我正在使用 redis 作为后端运行 django 频道 2.1.3。 CHANNELS_LAYERS 等已全部设置完毕。
参考链接:
编辑: 我可以使用视图中的websocket-client 发送消息
from websocket import create_connection
ws = create_connection("ws://url")
ws.send("Hello, World")
但是不使用上面的可以发送吗(不想创建连接)?
源码:chat-app
【问题讨论】:
-
我想到了一些事情:1)如果创建了一个项目,你是否签入了redis? 2)如果您(仅用于测试)使用 InMemoryLayer 是否有效?
-
是的,我可以看到在 redis 中为每个聊天室(组)创建的排序集,并且根据此讨论,通道 2 中不正式支持使用 InMemoryLayer:github.com/django/channels/issues/1039
-
对于本地开发,支持 InMemory(毕竟它是用于单元测试的),但不支持生产。所以要明确一点 1)你用你的 WebSocket 客户端连接到你的消费者 2)你点击警报端点 3)没有消息完成你已经打开的 WebSocket 连接?
-
是的。 Done 作为 HttpResponse 从视图返回。然而,“内容”不会传播到已经打开的 websocket 连接。为了清楚起见,添加了流程图
-
HTTP 警报视图是如何链接的,它是否在通道/daphne 运行时中运行?您是否尝试过通过频道应用程序链接 http 视图? channels.readthedocs.io/en/latest/topics/…
标签: django python-3.x django-channels