Django - 频道2.0:无法连接到消费者

时间:2018-02-14 04:45:42

标签: django python-3.x django-channels

我在从频道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函数中的print语句结果:

RedisChannelLayer(hosts=[{'address': ('localhost', 6379)}])

消费者中的print语句未执行,我没有收到任何错误消息。 我使用的是Python 3.5.3,频道2.0.2和频道 - redis 2.0.2

编辑:当我使用我的旧项目使用频道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 ...

时丢失了

1 个答案:

答案 0 :(得分:1)

来自文档: “请记住,通道层只支持异步方法,因此您可以从自己的异步上下文中调用它”或“您需要使用async_to_sync”。由于您发送的消费者继承自同步类(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"
})

修改

是的,你是现场的:

  

当我使用频道2 ...

时,您会注意到“工作人员 - 在频道上聆听”丢失了

由于您正在使用ChannelNameRouter,因此您必须运行一个worker来处理自定义命名通道上的事件。你可以这样做:

./manage.py runworker somename

如果您以后添加更多命名频道,那就简单了:

./manage.py runworker somename othername yetanothername

并且不要忘记执行上述async_to_sync业务,仍然需要它。