Can you clarify what you mean by "two users connected to the same socket"?
If you have two websockets connected, you'll have two copies of your
consumer running, one for each socket.

Andrew

On Thu, Mar 1, 2018 at 7:52 AM, lakeshow <sjung2...@gmail.com> wrote:

> I am running into an issue using Channels where if two users are connected
> to the same socket, the consumer will run twice. When a single user is
> connected, only once.
> So in practice: when I have two users chatting with each other over
> channels, a single sent message will be run through the consumer twice,
> causing it to save twice to the database. However, if there is only one
> participant in the channel, the message will run through the consumer once
> and save once as expected.
>
> What might be the issue?
>
> Here is the consumer:
>
> class ChatConsumer(AsyncJsonWebsocketConsumer):
>     ...
>     async def receive_json(self, content):
>         """
>         Called when we get a text frame. Channels will JSON-decode the payload
>         for us and pass it as the first argument.
>         """
>         # Messages will have a "command" key we can switch on
>         command = content.get("command", None)
>         recipient = content.get("recipient", None)
>         sender = self.scope["user"]
>         try:
>             if command == "join":
>                 # Make them join the room
>                 await self.join_room(content["room"])
>                 previous_message_list = await get_saved_messages(recipient, 
> sender)
>                 for msg in previous_message_list:
>                     await self.send_json({
>                         "msg_type": MSG_TYPE_MESSAGE,
>                         "room": content["room"],
>                         "username": msg.sender.user.username,
>                         "message": msg.message,
>                     },)
>             elif command == "leave":
>                 # Leave the room
>                 await self.leave_room(content["room"])
>             elif command == "send":
>                 await self.send_room(
>                     content["room"],
>                     content["message"],
>                     content["recipient"]
>                 )
>         except ClientError as e:
>             # Catch any errors and send it back
>             await self.send_json({"error": e.code})
>     ...
>     async def send_room(self, room_id, message, recipient):
>         """
>         Called by receive_json when someone sends a message to a room.
>         """
>         # Check they are in this room
>         if room_id not in self.rooms:
>             raise ClientError("ROOM_ACCESS_DENIED")
>         # Get the room and send to the group about it
>         room = await get_room_or_error(room_id, self.scope["user"])
>         await self.channel_layer.group_send(
>             room.group_name,
>             {
>                 "type": "chat.message",
>                 "room_id": room_id,
>                 "username": self.scope["user"].username,
>                 "message": message,
>                 "recipient": recipient,
>             }
>         )
>     ...
>     async def chat_message(self, event):
>         """
>         Called when someone has messaged our chat.
>         """
>         # Send a message down to the client
>         # Save message object
>         await save_message_object(
>             sender=event["username"],
>             message=event["message"],
>             recipient=event["recipient"]
>         )
>         await self.send_json(
>             {
>                 "msg_type": MSG_TYPE_MESSAGE,
>                 "room": event["room_id"],
>                 "username": event["username"],
>                 "message": event["message"],
>             },
>         )
>
>
> So something is causing the last function--def chat_message() to run twice
> and I think it's in the consumer and not related to the client because sent
> messages will log to the console only once--as soon as the messages are
> sent over socket.send, there will be two of the same Message objects saved
> onto the db.
>
> Here is code relating to the actual save. It is in utils.py and is
> decorated using sync_to_async in order to call the sync func from an async
> consumer:
>
> @database_sync_to_asyncdef save_message_object(sender, message, recipient):
>     recipient = Profile.objects.get(user__username=recipient)
>     sender = Profile.objects.get(user__username=sender)
>     m = Message(sender=sender, message=message, recipient=recipient)
>     m.save()
>     print(datetime.datetime.now())
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users+unsubscr...@googlegroups.com.
> To post to this group, send email to django-users@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/django-users/1a8b04b5-088e-41bd-a0f1-53d326f5f8e9%40googlegroups.com
> <https://groups.google.com/d/msgid/django-users/1a8b04b5-088e-41bd-a0f1-53d326f5f8e9%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAFwN1urP471Cc%2BZSYAiW02Q0wnaoQNMgwmUgasg4HJudn_gqUw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to