问题
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