Reusing an existing websocket in Django Channels

血红的双手。 提交于 2019-12-11 01:11:52

问题


I'm messing around semi-seriously with Python to create a sort of a gatekeeper server between a restricted-access system and a GAE application. I'm going to start with a more general question, before potentially moving on to a specific code-related question.

Overview

The restricted-access system is set up with a command-line Python app that opens a WebSocket connection to the Django Channels app running on an intermediate server, and begins sending out regular heartbeat frames, which the Django app acknowledges. So far so good. Every now and then, the Django app is going to receive an HTTP request, which it will verify, and if it passes, it'll send out an instruction to the other system. Now, in order to make it efficient, I had the idea of re-using the existing WS connection and piggy-back the instruction frame on that.

Question

Django allows me to receive frames on the socket easily, and act on said frames. What I'm having trouble with is sending a message down the existing pipe: I cannot for the life of me call the WebsocketConsumer.send() method, even via a wrapper, from a method that is not in the consumer, but defined elsewhere and receives the consumer as a parameter (the best I could come up with so far). Is it even possible (this question points to it actually not being possible)?

Thanks in advance for any pointers. If need be, tomorrow I can update the question with my classes.


回答1:


Maybe already be too late, but what you need to do is send a message directly to the channel or group the application is listening to. Channels will route your message to the appropriate consumer method.

So assuming you want to call the send_message method in the consumer serving your other app(say channel1): you should do this:

from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync

channel_layer = get_channel_layer()
sync_to_async(channel_layer.send)("channel1", {
    "type": "send.message",
    "text": "Hello there!",
})

This can be done, anywhere in your code.

The question you linked uses tornado websockets which is quite different from Django channels. I don't know if it is possiblle using tornado but it definitely is, using Channels



来源:https://stackoverflow.com/questions/51251515/reusing-an-existing-websocket-in-django-channels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!