我在 tomcat 中部署了一个 Web Socket 服务器端点,如下所示:
@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 是一个单例类,我在其中维护 session 缓存。
TokenCacheServiceImpl用于在REDIS中缓存每个用户对应的Token。
我不能在 REDIS 中存储 Session,因为它是一个不可序列化的对象,因此必须在本地内存中维护它。我希望避免这种情况,因为如果服务器重新启动或我想进行负载平衡,我不想丢失数据。
如何实现?
最佳答案
如果不进行大量工作,您将无法存储任意的、非可序列化
的对象。
但是如果你知道你已经存储了什么样的对象,那么你当然可以编写你自己的序列化程序。没有什么说数据必须是二进制的。您可以使用 XML、JSON 或一些虚构的存储系统。
你能限制你的应用程序只存储特定类型的对象吗?例如,如果您只存储基元(好吧,它们的盒装风格)和集合或那些东西,您可以用很少的代码来完成。如果没有,请准备好编写更多代码。
将 session 对象的代码更改为Serializable
,然后仅使用 Java 序列化来完成工作可能会更容易。
请注意,Java 序列化的 future 是不确定的。提交了一个非常旧的 JEP 以删除序列化,但是 it was withdrawn .最近的安全问题促使一些人support the removal of serialization from future Java versions .第二篇文章特别提到“[r]消除序列化是一个长期目标,并且是 Project Amber 的一部分”,但我在 Project Amber 中没有看到任何处理序列化的内容根本 .
此外,某些现有的 Java 规范(Java EE 的一部分,包括 Servlet 规范)非常需要对序列化的支持,所以......即使它已被弃用,我也看不到它很快就可以去任何地方。
关于java - 在 Redis 中存储 Web Socket session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53650556/