项目的一种使用情况是,当用户使用userId连接到服务器时,应维护会话。如果发生任何服务器事件(添加的记录或任何业务逻辑中的事件),我们应通知连接的用户。
我正在尝试将Websocket会话保持在hazelcast中,以便在任何实例出现故障时所有应用程序实例都可以使用它。
导入com.fasterxml.jackson.databind.ObjectMapper;导入com.hazelcast.config.Config;导入com.hazelcast.core.Hazelcast;导入com.hazelcast.core.HazelcastInstance;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.springframework.session.web.socket.events.SessionConnectEvent;
@Component
public class SocketHandler extends TextWebSocketHandler {
List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
private static final Object LOCK = new Object();
private Map<String, WebSocketSession> userSessionMap = new HashMap<>();
//Session s = null;
Config cfg = new Config();
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
Map<String, SessionConnectEvent> sharedData = instance.getMap("shared");
@Override
@SuppressWarnings("unchecked")
public void handleTextMessage(WebSocketSession session, TextMessage message)
throws InterruptedException, IOException {
Map<String, String> value = new ObjectMapper().readValue(message.getPayload(), Map.class);
String userId = value.get("userId");
synchronized(LOCK) {
if(!sharedData.containsKey(userId)) {
sharedData.put(userId, session);
}
}
session.sendMessage(new TextMessage("Hello " + value.get("userId") + ". Your Trip Notifications appear below !"));
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.add(session);
}
在运行时发生以下异常。
com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable serializer for class org.springframework.web.socket.adapter.standard.StandardWebSocketSession
at com.hazelcast.nio.serialization.SerializationServiceImpl.toData(SerializationServiceImpl.java:218)
at com.hazelcast.nio.serialization.SerializationServiceImpl.toData(SerializationServiceImpl.java:203)
at com.hazelcast.map.impl.AbstractMapServiceContextSupport.toData(AbstractMapServiceContextSupport.java:68)
at com.hazelcast.map.impl.DefaultMapServiceContext.toData(DefaultMapServiceContext.java:28)
at com.hazelcast.map.impl.proxy.MapProxySupport.toData(MapProxySupport.java:1042)
at com.hazelcast.map.impl.proxy.MapProxyImpl.put(MapProxyImpl.java:101)
at com.hazelcast.map.impl.proxy.MapProxyImpl.put(MapProxyImpl.java:89)
at com.ecab.driver.socket.SocketHandler.handleTextMessage(SocketHandler.java:43)
at org.springframework.web.socket.handler.AbstractWebSocketHandler.handleMessage(AbstractWebSocketHandler.java:43)
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75)
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleMessage(LoggingWebSocketHandlerDecorator.java:56)
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleMessage(ExceptionWebSocketHandlerDecorator.java:58)
首先,WebSocketSession
不是Serializable
,因此是您的错误。
然后,从概念的角度来看,不可能持久化状态连接(例如 FTP,WebSocket等)。您应该执行的操作将保留所有连接参数,然后,如果某个节点上的连接断开,则从另一个实例重新打开该连接。