django2 channels2 通过http请求推送消息至Websocket客户端

思路

  • channels 提供了在Consumer外部调用发送信息的方式,channels中每个客户端连接时会生成一个channel_name, 而channel_name对应了是哪个客户端, group_name对应的是用户组。
  • 那么可以通过把channel_name和group_name的值保存下来,在http请求的接口中进行外部调用。

实例

例子是继承AsyncJsonWebsocketConsumer的, 所以是异步的,可接受发送json格式的数据, 代码如下。

from channels.db import database_sync_to_async
from channels.generic.websocket import AsyncJsonWebsocketConsumer


@database_sync_to_async
def save_channel_name(key, channel_name, group_name):
    """
    :param key:
    :param channel_name:
    :param group_name:
    :return:
    """
    # 这里可以通过redis或数据库将对于的channel_name, group_name保存下来。
    pass


class WbConsumer(AsyncJsonWebsocketConsumer):

    async def connect(self):
        # 这
        key = self.scope['url_route']['kwargs']['peronId']  # 在websocket链接的时候获取到用户标识,可以从jwt信息中获取,可以在路由中获取某个参数作为标识
        group_name = 'group_' + key
        await save_channel_name(key, self.channel_name)
        # 当前频道添加进频道组
        await self.channel_layer.group_add(group_name, self.channel_layer)
        await self.accept()

    async def disconnect(self, code):
        print('关闭连接')

    async def receive_json(self, content, **kwargs):
        print('接收数据:', content)

        await self.send_json(content={
            'msg': '收到收到over!'
        })

	    async def test_message(self, event):
        """
        发送测试数据
        :param event: 
        :return: 
        """
        message = event['message']
        await self.send_json(message)


首先在connect方法中, 可以拿到客户端发起连接的请求路由参数,请求头等,如使用jwt认证的话,解析header里面的信息可以拿到用户ID, 以用户ID作为键将channel_namegroup_name保存起来。

  • http发起请求的接口中,可以定义:
from asgiref.sync import async_to_sync

channel_name = 'xxxx'  # 获取到之前保存的对应的channel_name
group_name = 'xxxxx'  # 获取到之前保存的对应的group_name

# 同步发送数据到组
async_to_sync(channel_layer.group_send)(group_name, {"type": "test.message"})
# 同步方式发送数据到对应websocket连接
async_to_sync(channel_layer.send)(channel_name, {"type": "test.message"})
发布了70 篇原创文章 · 获赞 143 · 访问量 34万+

猜你喜欢

转载自blog.csdn.net/ClassmateLin/article/details/104540595