10

Context/Background: A client is connected via web-socket. Server stores WebSocket session and few other identifiers in a Map for later use. Server receives some data from a queue which need to be send to client via web-socket. Using session from Map I am able to send it to the client. So far all good.

This all works fine for single node but not with multiple nodes (no need for clustering), reason being WebSocket session is not Serializable hence the deliemma :(. I was hoping to store the WebSocket Session in a Postgresql database for later use but am struck at Serialization.

What I tried: Someone else asked kind of similar question at non serializable session websocket java ee. I tried creating a wrapper around Tomcat's Session and provide readObject writeObject but unfortunately WsSession doesn't allow state to be set/read.

Tried using library https://github.com/EsotericSoftware/kryo but wasn't successful in Serializing my wrapper for WsSession.

My Environment: JDK 1.8.0_31, Tomcat 8.0.20, Spring 4.1.5.RELEASE, Debian Wheezy.

Thanks for your help.

Update: while trying to Serialize using Kryo I get following exception

com.esotericsoftware.kryo.KryoException: java.util.ConcurrentModificationException
Serialization trace:
classes (sun.misc.Launcher$AppClassLoader)
applicationClassLoader (org.apache.tomcat.websocket.WsSession)
at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:101) ~[kryo-3.0.1-SNAPSHOT.jar:?]

I also tried XStream http://x-stream.github.io/ and it does serialize to xml, however when de-serializing I get following exception

---- Debugging information ----
message             : Could not call     java.security.CodeSource.readObject()
cause-exception     : java.lang.RuntimeException
cause-message       : null
class               : java.security.CodeSource
required-type       : java.security.CodeSource
converter-type      : com.thoughtworks.xstream.converters.reflection.SerializableConverter
path                :  /org.apache.tomcat.websocket.WsSession/applicationClassLoader/parent/defaultDomain/codesource/java.security.CodeSource
line number         : 30863
class[1]            : java.security.ProtectionDomain
converter-type[1]   :     com.thoughtworks.xstream.converters.reflection.ReflectionConverter
class[2]            : sun.misc.Launcher$ExtClassLoader
class[3]            : sun.misc.Launcher$AppClassLoader
class[4]            : org.apache.tomcat.websocket.WsSession
version             : 1.4.8

Update 1: Change the design such that websocket session doesn't need to be serialized.

facundofarias
  • 2,973
  • 28
  • 27
Aurvoir
  • 267
  • 3
  • 12
  • Have you looked at Spring Sessions http://projects.spring.io/spring-session/ it replaces the session implementation and persists to Redis. Even if this isn't exactly what you want, perhaps the source will be of interest. – muttonUp Mar 08 '15 at 23:34
  • Yes, I did glossed over spring session documentation but couldn't find any interesting lead to have session available in non-web (http) context . I need to have it available in an ActiveMQ consumer. Will keep looking into it. A colleague suggested to try combining WebSocket endpoint with Q consumer. Not the ideal design but I will give it a try too. – Aurvoir Mar 09 '15 at 01:30
  • The spring Session is serializable, so thats a start. – muttonUp Mar 09 '15 at 12:46
  • 1
    I couldn't easily figure out the inner workings, it requires redis in the mix too so I ended up changing my design such that each node is listening to topic as compared to queue and each node has it's own set of cache containing active websocket sessions. Yes, similar message is received by n nodes but only one with active websocket will be able to deliver which meets the requirements. – Aurvoir Mar 16 '15 at 03:00

0 Answers0