如何确定向特定的一组侦听器发送消息?

时间:2019-04-15 06:57:02

标签: django websocket django-channels

如何确定要向特定的一组侦听器发送消息?

例如,我在聊天室A中有Luke,Jason和Bruce,在聊天室B中有Lisa。每个成员都有一个消息列表屏幕,该屏幕仅显示群聊室的最后一条消息。

我在每个聊天室都有一个套接字连接,用于侦听传入的消息。来自特定聊天室的群组消息将带有消息的房间标识符。问题是,websocket如何确定仅向已订阅此聊天室的人发送消息?

此Websocket连接将从不同的房间接收消息,但只需要将消息发送给属于该特定群组聊天室的人即可。

当我从客户端建立连接时,是否需要在某个地方添加一些标识符,以便服务器端可以知道是否需要向我发送消息?

这是我的连接功能:

class GroupMessageListConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.userId = str(self.scope['query_string'])[2:-1].split("=")[1]

        # self.eventId = self.scope['url_route']['kwargs']['eventId']

        print('GroupMessageListConsumer connected self.userId:{}'.format(self.userId))

        # print('GroupMessageListConsumer connected self.userId:{}'.format(self.userId))
        # print('GroupMessageListConsumer connected self.eventId:{}'.format(self.eventId))

        # Join room group
        await self.channel_layer.group_add(
            self.userId,
            self.channel_name
        )

        await self.accept()


    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.userId,
            self.channel_name
        )

1 个答案:

答案 0 :(得分:0)

Create a separate Model Room

class Room(models.model):
    users = models.ManyToManyField(
        "User",
        related_name='rooms',
        blank=True,
        symmetrical=False)

Before getting to consumer.py, Make sure your payload consists of these three:

event_type: What caused this event? a user is sending a message? you are sending a notification to a user? Is this an alert?

data: What data is sent along?

errors: Are there any errors?

Example payloads:

{ "event_type": "send_message", "data": { "message": "Hi", "room": 143, }, "errors": None }

{ "event_type": "send_notif", "data": { "message": "You received a friend request from xxx", "type": "friend_request", }, "errors": None }

Consumer.py

class GroupMessageListConsumer(AsyncWebsocketConsumer):
    user = None
    async def connect(self):
        self.user = self.scope["user"] #authenticated user either passed in through session or by token authentication

        print("connection request received.")

        await self.accept()
        print("connection accepted")

        #channel/channel_name is the current open socket connection between your browser and the server

        # Join channel or user to his rooms
        for room in self.user.rooms:
            await self.channel_layer.group_add(
                room.id,
                self.channel_name
            )

    async def disconnect(self, close_code):
        #remove current channel from listening to messages as it is closed or disconnected
        # Leave channel from all rooms
        for room in self.user.rooms:
            await self.channel_layer.group_discard(
                room.id,
                self.channel_name
            )
        print("channel disconnected.")
        raise StopConsumer()


    async def receive(self,text_data):
        print("message received.")
        text_data_json = json.loads(text_data)
        #always maintain payload with three main fields: "event_type", "data", "errors"
        event_type = text_data_json['event_type']
        data = text_data_json['data']
        if event_type=="send_message":
            #check whether user is allowed to send messages to room 143

            #Then send the message to that room.
            await self.channel_layer.group_send(
                data["room"],
                {
                    'type': "send_message", #call the respective event "async def send_message(self, event)" see below
                    'message': {
                        'event_type': event_type,
                        'data': {"message": data["message"], "user": self.user.id},
                        'errors': None
                    }
                }
            )
        else:
            print("event_type unknown")

    async def send_message(self, event):
        message =  event['message']
        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))