gpt4 book ai didi

java - Atmosphere 框架 : broadcaster broadcast message multiple times

转载 作者:太空宇宙 更新时间:2023-11-04 13:10:13 27 4
gpt4 key购买 nike

我目前正在基于此示例开发一个简单的聊天多房间:

https://github.com/Atmosphere/atmosphere-samples/blob/master/samples/chat-multiroom/

我的开发环境:

  • Tomee Plus 1.7.2 服务器
  • Atmosphere-runtime 版本 2.4.0
  • Atmosphere-cdi 版本 2.4.0
  • Java EE 1.7
  • 使用长轮询协议(protocol)

在解释我的问题之前,这里是我实现的聊天室的全局机制:

  1. 用户 A 连接到套接字“chat/all”。该 socket 允许发送或接收他和对话者之间的任何通知。

  2. 用户 A 从第一个 Web 应用程序发出聊天请求并等待(弹出旋转窗口)用户 B 的响应。

  3. 用户 B 也连接到套接字“chat/all”。用户B检查每次,从第二个网络应用程序,如果有新的聊天请求(来自数据库的 SQL 请求)。如果他发现新的请求,他可以或不接受这个请求。

  4. 用户B接受用户A的聊天请求。此时,通过套接字“chat/all”,用户 B 推送一条消息表明他接受了此消息要求。之后,用户B连接到第二个socket“chat/1”(特定聊天室的随机 ID)。他现在正在等待(像用户 B 一样弹出旋转窗口)让用户 A 连接到同一个套接字。

  5. 用户 A 收到此消息并连接到套接字“chat/1”。用户 A 现在已从服务器连接到该聊天室。该聊天室中有两个用户,我向其广播消息仅用户B通知用户A已连接并关闭弹出窗口旋转器。

当我只为一个资源广播消息时没有问题。但是当我为两个用户广播消息时,“onMessage”方法被多次调用!

这是我有关管理聊天室的代码:

@ManagedService(path = "/chat/{id_room}")
public final class ChatRoom {

//many static final private attribute

private static final Logger logger = LoggerFactory.getLogger(Chat.class);

@PathParam("id_room")
private String idChatRoom;

private final static String CHAT = "/chat/";

private final HashMap<Integer, List<String>> users = new HashMap<Integer, List<String>>();

private Universe universe;

private BroadcasterFactory broadcasterFactory = Universe.broadcasterFactory();

private AtmosphereResourceFactory resourceFactory = Universe.resourceFactory();

private ChatMessageEncoderDecoder chatEncodeDecode = new ChatMessageEncoderDecoder();

@Message(encoders = { ChatMessageEncoderDecoder.class }, decoders = { ChatMessageEncoderDecoder.class })
public final void onMessage(AtmosphereResource r, final ChatMessage message) throws UnsupportedEncodingException {
Integer chatRoomId = !NOTIFICATION_SOCKET_ALL.equals(idChatRoom) == true ? Integer.parseInt(idChatRoom) : 0;
[...]
if(...) {
[...]
}
else {
roomsList.add(idChatRoom);
boolean messageEmpty = "".equals(message.getMessage());
boolean chatConnectedWithTwoUsers = users.get(chatRoomId).size() > 1;
boolean chatConnectedWithOneUser = users.get(chatRoomId).size() == 1;
if(chatConnectedWithTwoUsers && MESSAGE_EVENT.equals(message.getEvent())) { //communication between two users to the chat room id
Users user = CDIUtil.getBean(RechercheUserService.class).getUserChat(message.getMail());
if(user != null){
try {
List<String> listUsersFromRoom = users.get(chatRoomId);
message.setUsers(listUsersFromRoom);
message.setEvent(MESSAGE_EVENT);
logger.info("{} a envoyé le message {}", message.getAuthor(), message.getMessage());

String messageToSend = chatEncodeDecode.encode(message);
broadcasterFactory.lookup(CHAT + idChatRoom).broadcast(messageToSend);

String messageUtf8 = new String(message.getMessage().getBytes(), "UTF-8");
CDIUtil.getBean(MessageRoomsService.class).createMessageContents(idChatRoom, user, messageUtf8);
} catch (IMException e) {
message.setEvent(MESSAGE_NOT_REGISTER_EVENT);
logger.error("Impossible d'enregistrer le message de l'utilisateur");
}
}
else{
message.setEvent(USER_NOT_EXIST_EVENT);
logger.error("Utilisateur Inconnu");
}
}
else if(chatConnectedWithOneUser) { //two users connected to the chat room id
users.get(chatRoomId).add(r.uuid());
logger.info("L'utilisateur {} a rejoint le chat {}", r.uuid(), idChatRoom);

AtmosphereResource resource = resourceFactory.find(users.get(chatRoomId).get(0)); //get the first user connected to the chat room

List<String> listUsersFromRoom = users.get(chatRoomId);
message.setUsers(listUsersFromRoom);
message.setEvent(CHAT_COMPLETE_EVENT);

String messageToSend = chatEncodeDecode.encode(message);
broadcasterFactory.lookup(CHAT + idChatRoom).broadcast(messageToSend, resource);
}
}
}
}

因此,当广播完成后,在界面用户上,会显示 3 条消息。例如,用户A发送消息“您好,有什么可以为您做的吗?”,用户B看到该消息3次。

我认为存在三个消息,因为三个资源在两个套接字上处于 Activity 状态。事实上,第一个套接字“chat/all”对于一个资源(用户 B)始终处于 Activity 状态,而第二个套接字“chat/1”对于两个资源(用户 A 和用户 B)始终处于 Activity 状态。共有三个资源。

有人已经面临这个问题了吗?或者有人知道如何解决它吗?

最佳答案

我也遇到了同样的问题..我已经解决了阅读此链接Multiple messages arrive as single response body or message received are incomplete的问题:

我已在 Atmosphere Servlet 内的 web.xml 中添加了这个 init-param

<init-param>
<param-name>org.atmosphere.cpr.AtmosphereInterceptor</param-name>
<param-value>org.atmosphere.client.TrackMessageSizeInterceptor</param-value>
</init-param>

在客户端,我在请求中添加了 trackMessageLength : true:

var request = { url: document.location.toString() + 'chat',
contentType : "application/json",
logLevel : 'debug',
transport : 'long-polling' ,
trackMessageLength : true,
fallbackTransport: 'long-polling'};

正如此链接中报道的那样

If you broadcast multiple messages and the underlying server buffer them in memory, your atmopshere.js callback or function can be invoked with multiple messages instead of a single message. It may not be an issue if you are using text, but if you are using JSON the parsing may fail because your callback/function gets invoked with multiple JSON messages.

我希望这对你也有用!

关于java - Atmosphere 框架 : broadcaster broadcast message multiple times,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34041708/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com