【发布时间】:2019-05-08 02:24:03
【问题描述】:
我在tomcat中部署了一个Web Socket Server Endpoint,如下:
@ServerEndpoint(value="/alerts/{username}/{sessionId}/{token}",
decoders = AlertDTODecoder.class,
encoders = AlertDTOEncoder.class )
public class AlertWebSocketEndpoint {
@OnOpen
public void onOpen(Session session,
@PathParam("username") String username,
@PathParam("sessionId") String sessionId,
@PathParam("token") String token) throws IOException {
String origToken = TokenCacheServiceImpl.getInstance().getToken(username, sessionId);
if ( origToken == null || !origToken.equals(token)) {
session.close();
}else {
AlertSession.getInstance().addUserSession(username, session);
}
}
@OnClose
public void onClose(Session session, @PathParam("username") String username) throws Exception {
AlertSession.getInstance().removeUserSession(username, session);
session.close();
}
}
AlertSession 是一个单例类,我在其中维护会话的缓存。
TokenCacheServiceImpl 用于缓存REDIS中每个用户对应的Token。
我不能将 Session 存储在 REDIS 中,因为它是一个不可序列化的对象,因此必须在本地内存中维护它。我希望避免这种情况,因为如果服务器重新启动或我想进行负载平衡,我不想丢失数据。
如何做到这一点?
【问题讨论】:
-
编写自己的序列化程序? redis 不一定是持久存储,因此无论如何您都可能丢失数据。
-
假设redis是持久化的。那么有没有办法存储Session对象呢?
-
最终一切都会被破坏、丢失、被盗、消磁、退役等。序列化一个
session,不管它是什么意思,然后如果它不是太大,把它存储为一个redis字符串。在 redis 中,字符串是一个带有长度前缀的二进制数组,不一定是 a-zA-z0-9。写时序列化,读时反序列化。如果您使用 .net 进行讨论,请参阅 NetDataContractSerializer。 docs.microsoft.com/en-us/dotnet/api/… 我在一个系统上工作过,它使用它来缓存任何东西。 Java??
标签: java tomcat websocket redis