我有一个业余爱好,那就是建造自动船。我现在使用Vuejs前端和Django后端构建了一个GUI。在此GUI中,我可以在地图上看到船,并向其发送命令。这些命令通过ZeroMQ sockets发送,效果很好。
我正在使用Django channels将命令从Websocket的前端发送到后端,然后从那里通过ZeroMQ套接字发送。我的消费者(效果很好)如下所示:
import zmq
from channels.generic.websocket import WebsocketConsumer
from .tools import get_vehicle_ip_address, get_vehicle_steer_socket
context = zmq.Context()
class SteerConsumer(WebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.forward_steer_socket = get_vehicle_steer_socket(context, get_vehicle_ip_address())
def connect(self):
self.accept()
def receive(self, text_data):
print("Passing on the commands from the frontend:", text_data, "to the boat")
self.forward_steer_socket.send_string(text_data)
[此外,我还通过ZeroMQ套接字从船上收到了位置信息,并将其保存到数据库中。我在一个单独的脚本中运行它,并且前端仅每2秒轮询一次后端以进行更新。这是接收船只信息的脚本:
import os
import django
import zmq
os.environ['DJANGO_SETTINGS_MODULE'] = 'server.settings'
django.setup()
# Socket to receive the boat location
context = zmq.Context()
location_socket = context.socket(zmq.SUB)
location_socket.setsockopt(zmq.CONFLATE, True)
location_socket.bind('tcp://*:6001')
location_socket.setsockopt_string(zmq.SUBSCRIBE, '')
while True:
boat_location = location_socket.recv_json()
print(boat_location)
# HERE I STORE THE BOAT LOCATION in the DB
我现在想将此location_socket
添加到Consumer
,以便Consumer
还可以接收ZeroMQ套接字上的船位置,并通过WebSocket将其发送到前端。
我当然可以简单地将location_socket
添加到其Consumer
方法的__init__()
中,如下所示:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.forward_steer_socket = get_vehicle_steer_socket(context, get_vehicle_ip_address())
self.location_socket = context.socket(zmq.SUB)
self.location_socket.setsockopt(zmq.CONFLATE, True)
self.location_socket.bind('tcp://*:6001')
self.location_socket.setsockopt_string(zmq.SUBSCRIBE, '')
但是我显然不能在while True
中包括Consumer
循环。所以从这里我不确定该怎么办。我实际上不知道这是否可能,因为Django Channels似乎是专门为websockets设计的。我想我可以开始使用多线程或多处理库,但这对我来说是未知的领域。
有人知道是否以及如何在Django Channel中制作ZeroMQ侦听器?
可以通过以下命令直接从分隔的脚本中向消费者发送消息:
当新客户端在https://channels.readthedocs.io/en/latest/topics/channel_layers.html#using-outside-of-consumers中连接到您的消费者时,您将拥有该客户端唯一的SteerConsumer
。要将消息发送给该使用者,您只需执行(在示例中为单独的脚本):
self.channel_name
并在
from channels.layers import get_channel_layer channel_layer = get_channel_layer() channel_layer.send("channel_name", { "type": "chat.message", "text": "Hello there!", })
方法内添加以处理此消息:
SteerConsumer