java - 在 Redis 中存储 Web Socket session

标签 java tomcat websocket redis

我在 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/

相关文章:

java - 错误: gradle and gms google-services

java - 在API中使用静态工厂方法

Apache mod_proxy_ajp 模块过早地将流量发送到备用后端服务器

python - 通过 Python 套接字/WebSocket 客户端发送/接收 WebSocket 消息

java - 如何在JFrame中设置默认图标?

java - Hashtable contains() 不读取 char 类型

linux - 如何在默认端口(80)上托管 tomcat

spring - "Unable to locate Spring NamespaceHandler for XML schema namespace"仅在可执行 jar 中发生

node.js - 使用 siege 测试 node.js 服务器时出现问题

javascript - 什么可能导致socket.io服务时间过长?