def post(self): client_id = self.request.get('from') client_obj = clients.ClientModel.get_by_id(client_id) logging.warning('client_id: %s has been disconnected' % client_id) if client_obj: video_setup.VideoSetup.remove_video_setup_objects_containing_client_id(client_id) for chat_room_obj_key in client_obj.list_of_open_chat_rooms_keys: chat_room_obj = chat_room_obj_key.get() if chat_room_obj.has_client(client_id): # Remove the client from the room. However, notice that we don't remove the room from the client's # list_of_open_chat_rooms_keys, because if the channel comes back, we want the client to automatically # join the rooms that he previously had open. chat_room_obj = chat_room_obj.txn_remove_client_from_room(client_id) # This client has disconnected from the room, so we want to send an update to the remote # clients informing them of the new room status. messaging.send_room_occupancy_to_clients(chat_room_obj, chat_room_obj.room_members_client_ids, recompute_members_from_scratch=True) else: logging.info('Room %s (%d) does not have client %s - probably already removed' % (chat_room_obj.chat_room_name_normalized, chat_room_obj.key.id(), client_id)) http_helpers.set_http_ok_json_response(self.response, {})
def post(self): message_obj = self.session.post_body_json message_type = message_obj['messageType'] presence_state_name = message_obj['messagePayload']['presenceStateName'] currently_open_chat_room_id = message_obj['messagePayload']['currentlyOpenChatRoomId'] client_obj = self.session.client_obj client_id = client_obj.key.id() # We only update the user presence in the case that this is posted to as an acknowledgement # of a heartbeat. If we were to update presence state in other cases, then the memcache and other timeouts # that are synchronized to the heartbeat timing would be incorrect (eg. This function is also called when # the user changes rooms so that they receive an updated list of room members, but that doesn't mean # that their channel is currently up an running -- the channel is only proven to be up if we have received # an ackHeartBeat message from the client, as the client sends ackHeartBeat as a response to a # synAckHeartBeat message that is sent on the channel) if message_type == 'ackHeartbeat': # Get the previous presence state, so that we can detect if a user was offline, which would mean # that they need to be added back to all of the rooms that they previously had open. previous_presence_state = client_obj.get_current_presence_state() # Important to update the presence state before adding the client to the rooms, so that they will not # be immediately removed from the rooms in the event that we generate a new room members list (which # would remove offline clients) at the same time that we are attempting to add the client back to all of the # rooms that he previously had open. client_obj.store_current_presence_state(presence_state_name) if previous_presence_state == 'PRESENCE_OFFLINE': # Since the client was offline, they (should) have already been removed from all rooms that they # previously had open. Add them back to all rooms since we now know that they are alive. logging.info('Client %s had state %s, and is now getting added back to all previously ' 'open rooms. New client state is %s' % (client_id, previous_presence_state, presence_state_name)) AddClientToRoom.add_client_to_all_previously_open_rooms(client_obj) # Chat room that the client is currently looking at needs an up-to-date view of # clients and their activity. Other rooms do not need to be updated as often since the client is not looking # at these other rooms right now. Send the client an updated list of the currently viewed room members. if currently_open_chat_room_id is not None: chat_room_obj = chat_room_module.ChatRoomModel.get_by_id(currently_open_chat_room_id) if message_type == 'ackHeartbeat' and client_id not in chat_room_obj.room_members_client_ids: # This should not happen, as the above code should have added the client back to any rooms # that they opened as soon as he sent a message during a time when his state was # considered PRESENCE_OFFLINE. logging.error("client_id %s not in chat room %s even though he is requesting an update for that " "room." % (client_id, currently_open_chat_room_id)) messaging.send_room_occupancy_to_clients(chat_room_obj, [client_id,], recompute_members_from_scratch=False) http_helpers.set_http_ok_json_response(self.response, {})
def post(self): post_body_json = json.loads(self.request.body) client_id = post_body_json['clientId'] room_id = post_body_json['chatRoomId'] chat_room_obj = chat_room_module.ChatRoomModel.get_by_id(room_id) chat_room_obj = chat_room_obj.txn_remove_client_from_room(client_id) client_obj = clients.ClientModel.get_by_id(client_id) if client_obj: client_obj.txn_remove_room_from_client_status_tracker(chat_room_obj.key) messaging.send_room_occupancy_to_clients(chat_room_obj, chat_room_obj.room_members_client_ids, recompute_members_from_scratch=True) http_helpers.set_http_ok_json_response(self.response, {})
def add_client_to_room(chat_room_obj, client_id): logging.debug('add_client_to_room called for client_id %s and room %s' % (client_id, chat_room_obj)) client_obj = clients.ClientModel.get_by_id(client_id) if chat_room_obj.key in client_obj.list_of_open_chat_rooms_keys: client_was_previously_in_this_room = True else: client_was_previously_in_this_room = False (new_client_has_been_added, chat_room_obj) = chat_room_obj.txn_add_client_to_room(client_id) client_obj.txn_add_room_key_to_client_status_tracker(chat_room_obj.key) if new_client_has_been_added: # Send a notification to all room members that a new client has joined the room messaging.send_room_occupancy_to_clients(chat_room_obj, chat_room_obj.room_members_client_ids, recompute_members_from_scratch=True) if client_was_previously_in_this_room: AddClientToRoom.tell_client_they_were_re_added_to_room_after_they_have_been_absent(client_id, chat_room_obj)