Django - Channels 2.0:无法连接到消费者
Django - Channels 2.0: Unable to connect to consumer
在从频道 1.x 迁移到 2.x 之前,我正在做一些测试;我的原始代码将 csv 文件的值提取到数据库中。但是我目前无法与消费者建立连接。
settings.py
ASGI_APPLICATION = "UbiosData.routing.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost", 6379)],
},
},
}
routing.py
from channels.routing import ProtocolTypeRouter, ChannelNameRouter
from .consumers import TestConsumer
application = ProtocolTypeRouter({
"channel": ChannelNameRouter({
"somename": TestConsumer,
}),
})
consumers.py
from channels.consumer import SyncConsumer
class TestConsumer(SyncConsumer):
def websocket_connect(self, event):
print("websocket_connect")
self.send({
"type": "websocket.accept",
})
def websocket_receive(self, event):
print("websocket_receive")
self.send({
"type": "websocket.send",
"text": event["text"],
})
def test_send(self, message):
print("Entering consumer")
print(message["text"])
views.py
def test_channels(request):
channel_layer = get_channel_layer()
print(channel_layer)
channel_layer.send("somename", {
"type": "test.send",
"text": "test"
})
return render(request, "data/data_index.html")
test_channels
函数中打印语句的结果:
RedisChannelLayer(hosts=[{'address': ('localhost', 6379)}])
消费者中的打印语句没有执行,我没有收到任何错误消息。
我正在使用 Python 3.5.3、通道 2.0.2 和通道-redis 2.0.2
编辑: 这是我使用 Channels 1.1.6 使用旧项目启动开发服务器时的输出:
Starting Channels development server at http://127.0.0.1:8000/
Channel layer default (asgi_redis.core.RedisChannelLayer)
Quit the server with CONTROL-C.
2018-02-16 16:46:48,604 - INFO - worker - Listening on channels http.request, ingest_equipment, ingest_values, websocket.connect, websocket.disconnect, websocket.receive
2018-02-16 16:46:48,606 - INFO - worker - Listening on channels http.request, ingest_equipment, ingest_values, websocket.connect, websocket.disconnect, websocket.receive
2018-02-16 16:46:48,608 - INFO - worker - Listening on channels http.request, ingest_equipment, ingest_values, websocket.connect, websocket.disconnect, websocket.receive
2018-02-16 16:46:48,609 - INFO - worker - Listening on channels http.request, ingest_equipment, ingest_values, websocket.connect, websocket.disconnect, websocket.receive
2018-02-16 16:46:48,611 - INFO - server - HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2018-02-16 16:46:48,611 - INFO - server - Using busy-loop synchronous mode on channel layer
2018-02-16 16:46:48,611 - INFO - server - Listening on endpoint tcp:port=8000:interface=127.0.0.1
这是我使用 Channels 2.0.2 启动带有新项目的服务器时的输出:
Starting ASGI/Channels development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
2018-02-16 17:05:08,331 - INFO - server - HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2018-02-16 17:05:08,332 - INFO - server - Configuring endpoint tcp:port=8000:interface=127.0.0.1
2018-02-16 17:05:08,334 - INFO - server - Listening on TCP address 127.0.0.1:8000
你会注意到当我使用频道 2 时 "worker - Listening on channels" 不见了...
来自文档:
"Remember that channel layers only support async methods, so you can either call it from your own asynchronous context" 或 "you’ll need to use async_to_sync"。由于您要发送给的消费者继承自同步 class (SyncConsumer),我认为第二个选项是您想要的。所以添加
from asgiref.sync import async_to_sync
再改
channel_layer.send("somename", {
"type": "test.send",
"text": "test"
})
到
async_to_sync(channel_layer.send)("somename", {
"type": "test.send",
"text": "test"
})
编辑:
是的,你是 spot-on:
You'll notice that "worker - Listening on channels" is missing when I use Channels 2...
由于您使用的是 ChannelNameRouter,因此您必须 运行 一个工作人员来处理 custom-named 频道上的事件。你可以这样做:
./manage.py runworker somename
如果您以后添加更多命名频道,也同样简单:
./manage.py runworker somename othername yetanothername
并且不要忘记按照上述方式进行 async_to_sync 业务,它仍然是必需的。
在从频道 1.x 迁移到 2.x 之前,我正在做一些测试;我的原始代码将 csv 文件的值提取到数据库中。但是我目前无法与消费者建立连接。
settings.py
ASGI_APPLICATION = "UbiosData.routing.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost", 6379)],
},
},
}
routing.py
from channels.routing import ProtocolTypeRouter, ChannelNameRouter
from .consumers import TestConsumer
application = ProtocolTypeRouter({
"channel": ChannelNameRouter({
"somename": TestConsumer,
}),
})
consumers.py
from channels.consumer import SyncConsumer
class TestConsumer(SyncConsumer):
def websocket_connect(self, event):
print("websocket_connect")
self.send({
"type": "websocket.accept",
})
def websocket_receive(self, event):
print("websocket_receive")
self.send({
"type": "websocket.send",
"text": event["text"],
})
def test_send(self, message):
print("Entering consumer")
print(message["text"])
views.py
def test_channels(request):
channel_layer = get_channel_layer()
print(channel_layer)
channel_layer.send("somename", {
"type": "test.send",
"text": "test"
})
return render(request, "data/data_index.html")
test_channels
函数中打印语句的结果:
RedisChannelLayer(hosts=[{'address': ('localhost', 6379)}])
消费者中的打印语句没有执行,我没有收到任何错误消息。 我正在使用 Python 3.5.3、通道 2.0.2 和通道-redis 2.0.2
编辑: 这是我使用 Channels 1.1.6 使用旧项目启动开发服务器时的输出:
Starting Channels development server at http://127.0.0.1:8000/
Channel layer default (asgi_redis.core.RedisChannelLayer)
Quit the server with CONTROL-C.
2018-02-16 16:46:48,604 - INFO - worker - Listening on channels http.request, ingest_equipment, ingest_values, websocket.connect, websocket.disconnect, websocket.receive
2018-02-16 16:46:48,606 - INFO - worker - Listening on channels http.request, ingest_equipment, ingest_values, websocket.connect, websocket.disconnect, websocket.receive
2018-02-16 16:46:48,608 - INFO - worker - Listening on channels http.request, ingest_equipment, ingest_values, websocket.connect, websocket.disconnect, websocket.receive
2018-02-16 16:46:48,609 - INFO - worker - Listening on channels http.request, ingest_equipment, ingest_values, websocket.connect, websocket.disconnect, websocket.receive
2018-02-16 16:46:48,611 - INFO - server - HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2018-02-16 16:46:48,611 - INFO - server - Using busy-loop synchronous mode on channel layer
2018-02-16 16:46:48,611 - INFO - server - Listening on endpoint tcp:port=8000:interface=127.0.0.1
这是我使用 Channels 2.0.2 启动带有新项目的服务器时的输出:
Starting ASGI/Channels development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
2018-02-16 17:05:08,331 - INFO - server - HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2018-02-16 17:05:08,332 - INFO - server - Configuring endpoint tcp:port=8000:interface=127.0.0.1
2018-02-16 17:05:08,334 - INFO - server - Listening on TCP address 127.0.0.1:8000
你会注意到当我使用频道 2 时 "worker - Listening on channels" 不见了...
来自文档: "Remember that channel layers only support async methods, so you can either call it from your own asynchronous context" 或 "you’ll need to use async_to_sync"。由于您要发送给的消费者继承自同步 class (SyncConsumer),我认为第二个选项是您想要的。所以添加
from asgiref.sync import async_to_sync
再改
channel_layer.send("somename", {
"type": "test.send",
"text": "test"
})
到
async_to_sync(channel_layer.send)("somename", {
"type": "test.send",
"text": "test"
})
编辑:
是的,你是 spot-on:
You'll notice that "worker - Listening on channels" is missing when I use Channels 2...
由于您使用的是 ChannelNameRouter,因此您必须 运行 一个工作人员来处理 custom-named 频道上的事件。你可以这样做:
./manage.py runworker somename
如果您以后添加更多命名频道,也同样简单:
./manage.py runworker somename othername yetanothername
并且不要忘记按照上述方式进行 async_to_sync 业务,它仍然是必需的。