【问题标题】:Storing Web Socket sessions in Redis在 Redis 中存储 Web Socket 会话
【发布时间】: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


【解决方案1】:

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

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

你能限制你的应用程序只存储某些类型的对象吗?例如,如果你只存储原语(好吧,它们的盒装风格)和集合或那些东西,你可以用很少的代码来做到这一点。如果没有,请准备编写更多代码。

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

请注意,Java 序列化的未来是不确定的。提交了一个非常旧的 JEP 以删除序列化,但 it was withdrawn。最近的安全问题促使一些人使用support the removal of serialization from future Java versions。第二篇文章特别提到“[r]移动序列化是一个长期目标,并且是 Project Amber 的一部分”,但我在 Project Amber 中没有看到任何涉及序列化的内容 .

另外,某些现有的 Java 规范(Java EE 的一部分,包括 Servlet 规范)几乎需要支持序列化,所以......即使它已被弃用,我也看不到它很快就会去任何地方。

【讨论】:

    猜你喜欢
    • 2021-03-17
    • 2015-02-20
    • 2012-10-08
    • 2019-03-10
    • 2015-01-14
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多