java websocket上线后如何发送离线用户的消息?

Posted

技术标签:

【中文标题】java websocket上线后如何发送离线用户的消息?【英文标题】:How to send messages of offline user after getting online in java websocket? 【发布时间】:2015-07-07 10:41:11 【问题描述】:

我正在尝试使用 webcocket 编写聊天,对于离线用户,我使用了 java Queue,如果用户离线,我将消息保存在队列中,当用户上线时,我检查队列是否为空,如果不是,使用循环我从队列中删除每条消息。问题是它只是向用户发送最后一条消息,即使所有消息都在队列中, 这是我的 onOpen 方法:

@ServerEndpoint(value = "/chat/room/user", encoders = ChatMessageEncoder.class, decoders = ChatMessageDecoder.class)
 public class ChatEndpoint 


private final Logger log = Logger.getLogger(getClass().getName());
private static final Map<String, Queue<ChatMessage>> userMessageBuffer = new HashMap<>();

@OnOpen
public void open(final Session session,
        @PathParam("room") final String room,
        @PathParam("user") final String userId) 

    log.info("session openend and bound to room: " + room);
    // session.getUserProperties().put("room", room);
    session.getUserProperties().put("user", userId);

    Queue<ChatMessage> userMsgs = userMessageBuffer.get(userId);
    ChatMessage sendChat = new ChatMessage();

    if (userMsgs != null && !userMsgs.isEmpty()) 

        for (int i = 0; i < userMsgs.size(); i++) 

            sendChat = userMsgs.remove();
            System.out.println("size!!!!!! " + sendChat.getMessage());
            try 

                    session.getBasicRemote().sendObject(sendChat);

             catch (IOException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
             catch (EncodeException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            

        
    


有谁知道问题出在哪里?

【问题讨论】:

你知道userMsgs.size()每次for循环循环都会返回越来越小的值吗? 你的消息代理是什么? 是的,它每次都会变小 什么是消息代理? 除非您特别需要 i 来做某事,否则只需使用 while (userMsgs.size() &gt; 0) 循环而不是 for 循环。 【参考方案1】:

我没有检查完整的代码,但肯定

      for (int i = 0; i < userMsgs.size(); i++)

是你的问题。因为您使用 i++ 并检查 userMsgs.size() 作为 for 循环中的条件。因此,您将i 增加1 并将userMsgs 的大小减少1,实际上您将只能访问队列中一半的元素。

假设你最初有 8 个元素在队列中(想象一下 Admiral General Aladeen 解释圆形导弹)

               i=0 and userMsgs.size()=8
               i=1 and userMsgs.size()=7
               i=2 and userMsgs.size()=6
               i=3 and userMsgs.size()=5
               i=4 and userMsgs.size()=4 // comes out of loop.

你应该改用while循环,

  while(!userMsgs.isEmpty())
   .....
  

您说您只能向用户发送最后一条消息,可能是因为您的队列中只有 2 条消息。我知道这很少见,但根据您的代码应该是这种情况。

【讨论】:

以上是关于java websocket上线后如何发送离线用户的消息?的主要内容,如果未能解决你的问题,请参考以下文章

html5利用websocket完成的推送功能

websocket 加layim实现在线聊天系统

Java web 服务端消息推送用啥比较好

在 Tigase 中向客户端发送自定义消息

XMPPFramework - 如何获取在线和离线好友列表?

得到“???”在 XMPP 离线模式下发送表情符号时