gpt4 book ai didi

java - Spring 使用 websocket handler bean 作为单例,尽管它的原型(prototype)范围

转载 作者:太空宇宙 更新时间:2023-11-04 12:25:42 25 4
gpt4 key购买 nike

我在尝试使用 Spring WebSockets 创建聊天时遇到问题。
Spring 版本 - 4.3.1。
我创建了一个扩展 TextWebSocketHandler 的 ChatWebSocketHandler 类。以下是 websocket 的 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 的原型(prototype)范围。
这样做时,我期望 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 方法中以确保这一点。我得到了两个用户(开发人员和 Alex)的输出:

org.kolokolov.chat.controller.ChatWebSocketHandler@2c1b0d6d : Developer
org.kolokolov.chat.controller.ChatWebSocketHandler@2c1b0d6d : Alex

正如您所见,查看哈希码,两个用户使用相同的 ChatWebSocketHandler 实例。
为了避免这种情况,我应该考虑什么?

最佳答案

这是一个老问题,但仍然没有答案,所以解决它会很好。

对于具有以下代码的端点:

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>

关于java - Spring 使用 websocket handler bean 作为单例,尽管它的原型(prototype)范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38419169/

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