我正在尝试使用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();
}
}
}
}}
有人知道问题在哪里吗?
答案 0 :(得分:4)
我没有检查完整的代码,但肯定是
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条消息。我知道这很罕见,但根据你的代码应该是这种情况。