我遇到了尝试使用Spring WebSockets创建聊天的问题
春季版 - 4.3.1。
我创建了一个类ChatWebSocketHandler extending TextWebSocketHandler
。这是websockets的XML配置:
<websocket:handlers>
<websocket:mapping path="/websocket/chat" handler="chatWebSocketHandler" />
<websocket:handshake-interceptors>
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" />
</websocket:handshake-interceptors>
</websocket:handlers>
<bean name="chatWebSocketHandler" class="org.kolokolov.chat.controller.ChatWebSocketHandler" scope="prototype" />
如您所见,我为此bean定义了原型范围
这样做我期望Spring会为连接聊天的任何新用户创建一个ChatWebSocketHandler的新实例。我需要它,因为这个bean是有状态的,因为连接用户的UserProfile在建立连接时被写入它的字段。
这是代码的一部分
public class ChatWebSocketHandler extends TextWebSocketHandler {
private UserProfile user;
private static final Map<String, WebSocketSession> connections = new ConcurrentHashMap<>();
@Autowired
MessageService messageService;
public static Map<String, WebSocketSession> getConnections() {
return connections;
}
@Override
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
this.user = (UserProfile) webSocketSession.getAttributes().get("user");
connections.put(user.getNickname(), webSocketSession);
String message = String.format("%s %s", user.getNickname(), "has joined.");
broadcast(new Message(MessageType.MESSAGE, message, "[SERVER]").toJson());
broadcast(new Message(MessageType.USER_LIST, getLoggedUsersList()).toJson());
System.out.println(this + " : " + user.getNickname());
System.out.println(connections);
}
对于单个用户,一切正常,直到我尝试将第二个用户连接到聊天。
据我所知,没有为新用户创建ChatWebSocketHandler
的新实例。我将第一个System.out.println
行添加到afterConnectionEstablished
方法以确保它。
我有两个用户(开发人员和亚历克斯)的输出:
org.kolokolov.chat.controller.ChatWebSocketHandler@2c1b0d6d : Developer
org.kolokolov.chat.controller.ChatWebSocketHandler@2c1b0d6d : Alex
如您所见,查看哈希码,两个用户都使用相同的ChatWebSocketHandler实例。
为避免这种情况,我应该考虑什么?
答案 0 :(得分:0)
这是一个老问题,但仍然没有答案,所以处理它会很好。
对于具有以下代码的端点:
package com.my.company;
public class ChatWebSocketHandler extends TextWebSocketHandler {
//override needed methods
}
有一个org.springframework.web.socket.handler.PerConnectionWebSocketHandler类可以帮助您实现拥有一个处理程序连接/实例的目标。 XML配置如下:
<bean id="chatPerConnectionHandler" class="org.springframework.web.socket.handler.PerConnectionWebSocketHandler">
<constructor-arg>
<value type="java.lang.Class">com.my.company.ChatWebSocketHandler</value>
</constructor-arg>
</bean>
<websocket:handlers>
<websocket:mapping path="/chat" handler="chatPerConnectionHandler" />
<!-- your config here -->
</websocket:handlers>