Java 如何制作弹簧';在两个或多个会话之间共享信息的自定义作用域?

Java 如何制作弹簧';在两个或多个会话之间共享信息的自定义作用域?,java,spring,session,grails,Java,Spring,Session,Grails,我们有一个包含聊天的应用程序。我们正在使用Node.JS的IO套接字推送到客户端。经过身份验证后,客户端正在连接到一个房间,其id作为房间的标识符。我们之所以这样做,是因为有一些单例将一些通知推送到客户机,独立于他/她的会话。聊天室的SpringBean是会话范围。 当同一个客户端使用两个不同的浏览器登录系统时,我们面临的问题就会发生。创建了两个会话,所以有两个SpringBean在运行。由于两个bean都推送到由用户id标识的房间,因此在客户端,相同的消息会到达两次。重复消息的数量随着浏览器的

我们有一个包含聊天的应用程序。我们正在使用Node.JS的IO套接字推送到客户端。经过身份验证后,客户端正在连接到一个房间,其id作为房间的标识符。我们之所以这样做,是因为有一些单例将一些通知推送到客户机,独立于他/她的会话。聊天室的SpringBean是会话范围。 当同一个客户端使用两个不同的浏览器登录系统时,我们面临的问题就会发生。创建了两个会话,所以有两个SpringBean在运行。由于两个bean都推送到由用户id标识的房间,因此在客户端,相同的消息会到达两次。重复消息的数量随着浏览器的数量而增加

所以,我想为Spring创建一个自定义范围。此作用域必须在使用相同登录名登录的所有客户端之间共享,并且必须在使用此登录名登录的所有会话被销毁后立即销毁


我认为这个范围需要一个映射,其中包含每个登录的所有会话,并且需要监听这些会话的破坏情况。有人能帮我吗?

我找到了以下解决方案:


我创建了一个spring的singleton bean,它有一个用番石榴的MapMaker创建的地图。该映射具有弱值(有关弱引用的详细信息,请参见此处:)。然后我有一个spring会话bean。这个会话bean向singleton请求一个通过客户端id的聊天实例。单身汉,确认地图上是否有什么东西。如果没有,它将创建一个新的聊天实例,放入地图并返回它。会话bean维护此聊天实例的引用。如果用户登录到不同的浏览器,新的会话bean也会这样做。这一次,它将在映射中保存实例。当不再有会话bean引用聊天实例时,它将被垃圾收集,因为映射对它的引用较弱。

为什么不更改聊天的标识符?两个不同的浏览器应该作为两个独特的用户聊天处理,或者像GMail一样,只保留一个会话并强制注销另一个。我想节省资源。如果每个会话创建一个聊天实例(即使它是同一个用户),我将花费更多的服务器资源。