繁体   English   中英

在Redis中存储Web套接字会话

[英]Storing Web Socket sessions in Redis

我在tomcat中部署了一个Web套接字服务器端点,如下所示:

    @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中缓存与每个用户相对应的令牌。

我不能将会话存储在REDIS中,因为它是一个不可序列化的对象,因此必须将其维护在本地内存中。 我希望避免这种情况,因为如果服务器重启或不想进行负载平衡,我都不会丢失数据。

如何做到这一点?

如果不进行大量工作,您将无法存储任意的,不可serializable对象。

但是,如果您知道已经存储了哪种对象,那么您当然可以编写自己的序列化器。 没有什么可以说数据必须是二进制的。 您可以使用XML,JSON或某些组合存储系统。

您可以限制您的应用程序,使其仅存储某些类型的对象吗? 例如,如果您仅存储基元(以及其装箱的样式)和集合或这些内容,则只需很少的代码即可完成此操作。 如果没有,请准备编写更多代码。

将会话对象的代码更改为可Serializable ,然后仅使用Java序列化来完成工作可能会更容易。

请注意,Java序列化的未来是不确定的。 归档了一个非常老的JEP来删除序列化,但是它被撤回了 最近的安全问题促使一些人支持从将来的Java版本中删除序列化 第二篇文章特别提到“实现序列化是一个长期目标,并且是Project Amber的一部分”,但我在Project Amber中看不到任何涉及序列化的内容

另外,某些现有的Java规范(包括Servlet规范在内的Java EE的一部分)几乎需要对序列化的支持,因此...即使不赞成使用它,我也看不到它会在任何地方出现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM