consumer.py
# accept websocket connection
def connect(self):
self.accept()
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
command = text_data_json['command']
job_id = text_data_json['job_id']
if command == 'subscribe':
self.subscribe(job_id)
elif command == 'unsubscribe':
self.unsubscribe(job_id)
else:
self.send({
'error': 'unknown command'
})
# Subscribe the client to a particular 'job_id'
def subscribe(self, job_id):
self.channel_layer.group_add(
'job_{0}'.format(job_id),
self.channel_name
)
# call this method from rest api to get the status of a job
def send_job_notification(self, message, job_id):
channel_layer = get_channel_layer()
group_name = 'job_{0}'.format(job_id)
channel_layer.group_send(
group_name,
{
"type": "send.notification",
"message": message,
}
)
# Receive message from room group
def send_notification(self, event):
message = event['message']
# Send message to WebSocket
self.send(text_data=json.dumps(
message))
在上面的代码中,我试图做的是将客户端连接到套接字,并通过使用“订阅”方法创建一个名为“job_1”的组并将其添加到 channel 层,将客户端订阅到特定的“job_id”。组的创建是动态的。
我正在使用下面来自 Google 的“简单 websocket 客户端扩展”来连接到上面的 websocket。我能够与 websocket 建立连接并向其发送请求,如下图所示。
现在,由于客户端已连接并订阅了特定的“job_id”, 我正在使用“ postman ”通过在请求中传递 job_id 来向订阅特定“job_id”的上述连接客户端(简单的 websocket 客户端扩展)发送通知,如下面黄色突出显示。
当我向“REST-API”发帖时,我正在调用“consumer.py”文件的“send_job_notification(self, message, job_id)”方法以及图中所示的“job_id”为“1”下面是黄色的
完成所有这些后,我没有看到任何消息发送到连接的客户端,该客户端订阅了“REST-API”调用的“job_id”。
任何帮助将不胜感激,因为它已经拖延了很长时间。
编辑:
感谢 Ken 的建议,将方法设置为“@staticmethod”是值得的,但 Ken 我如何让 API 向连接的客户端发送作业状态更新,因为我的长期运行作业会在某个进程中运行并发送更新消息通过 REST-API 返回后端,然后需要将更新发送到正确的客户端(通过 websockets)。
我对套接字消费者的 API 调用如下:
从 websocket_consumer 导入消费者
类 websocket_connect(APIView):
def post(self, request, id):
消费者.ChatConsumer.send_job_notification("hello",id)
编辑
`CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost", 6379)],
},
},
编辑-1
最佳答案
您不能直接从外部代码调用消费者中的方法,因为您需要将特定的消费者实例连接到您的客户端。这是通过使用消息传递系统或代理(如 reddis)实现的 channel 层的工作。
据我所知,您已经朝着正确的方向前进,除了 send_job_notification
是一个需要实例化消费者的实例方法。改为将其设为静态方法,这样您就可以在没有消费者实例的情况下直接调用它
@staticmethod
def send_job_notification(message, job_id):
channel_layer = get_channel_layer()
group_name = 'job_{0}'.format(job_id)
channel_layer.group_send(
group_name,
{
"type": "send.notification",
"message": message,
}
在您的 API View 中,您可以将其简单地称为:
ChatConsumer.send_job_notification(message, job_id)
关于python-3.x - 从 rest api 或服务器向特定的 django websocket 客户端发送响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55122184/