【发布时间】:2019-08-02 23:12:26
【问题描述】:
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”的组并将其添加到通道层,将客户端订阅到特定的“job_id”。组的创建是动态的。
我正在使用来自 Google 的“简单 websocket 客户端扩展”来连接到上面的 websocket。我能够与 websocket 建立连接并向其发送请求,如下图所示。
现在,由于客户端已连接并订阅了特定的“job_id”, 我正在使用“邮递员”向订阅特定“job_id”的上述连接客户端(简单的 websocket 客户端扩展)发送通知,方法是在请求中传入 job_id,如下面的黄色突出显示。
当我向“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 调用如下:
from websocket_consumer import consumers
class websocket_connect(APIView):
def post(self, request, id):
consumers.ChatConsumer.send_job_notification("hello",id)
编辑
`CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost", 6379)],
},
},
Edit-1
【问题讨论】:
-
你能把调用消费者方法的REST API中的代码贴出来吗?
-
强烈建议不要在此处发布屏幕截图,因为人们很难复制您的代码并进行尝试。请改为发布格式化代码
-
再次,我发现很难理解您的问题。您想发送工作状态更新吗?你如何获得更新?您可以通过调用 send_job_notification 并将作业状态/进度作为消息传递来从执行作业的进程中发送它们。但同样,我可能没有正确理解你
-
我尝试格式化代码 Ken 但编辑器抛出错误,所以我添加了屏幕截图。是的,你是对的,我从执行工作的过程中获取更新,这些更新被提供给 API,然后 API 调用 'send_job_notification' 作为参数传递 'message' 和 'job_id' 以将作业通知发送到连接'websocket' 客户端。希望你能理解。
-
太棒了。那么,如果您已经弄清楚了,那么您的问题是什么?问题是屏幕截图中的错误吗?如您所见,您需要删除额外的`,并且还需要导入json包
标签: python-3.x websocket redis django-channels