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))
在上面的代码中,我试图做的是将客户端连接到套接字,并通过使用" subscribe“方法创建一个名为"job_id”的组将客户端订阅到特定的“subscribe”,并将其添加到通道层。组的创建是动态的。
我正在使用下面的“简单的websocket客户端扩展”从谷歌连接到上面的websocket。我可以与websocket建立连接并向其发送请求,如下图所示。
现在,由于客户端已连接并订阅了特定的" job_id ",我使用"Postman“将通知发送到上面连接的客户端(简单的websocket客户端扩展),通过在请求中传递job_id来订阅特定的"job_id”,如下面以黄色突出显示的。
当我对"REST-API“执行post操作时,我调用的是"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)],
},
},
}`如您所见,'Redis‘服务也在运行
编辑-1\f25-1\f6
发布于 2019-03-13 06:38:01
您不能直接从外部代码调用使用者中的方法,因为您需要将特定的使用者实例连接到客户端。这是通道层的工作,通过使用消息传递系统或代理作为reddi来实现。在我看来,你已经在朝着正确的方向前进了,除了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视图中,您可以简单地调用它:ChatConsumer.send_job_notification(message, job_id)
https://stackoverflow.com/questions/55122184
复制相似问题