lucee-websocket icon indicating copy to clipboard operation
lucee-websocket copied to clipboard

getChannels returns an empty collection when called from onClose()

Open jjakob opened this issue 6 years ago • 2 comments

This should be documented in the Websocket API docs. As mentioned in #11, before #11 was fixed, onClose would return an error:

lucee.runtime.exp.NativeException: The WebSocket session [1] has been closed and no method (apart from close()) may be called on a closed session at org.apache.tomcat.websocket.WsSession.checkState(WsSession.java:782) at org.apache.tomcat.websocket.WsSession.getUserProperties(WsSession.java:727) at net.twentyonesolutions.lucee.websocket.WebSocket.getChannels(WebSocket.java:456) at net.twentyonesolutions.lucee.websocket.connections.ConnectionManager.unsubscribeAll(ConnectionManager.java:193) at 
...

This was due to onClose also calling unsubscribeAll (which is redundant?). It'd also be good to document all methods that can and can't be used from e.g. onClose and all other handlers.

jjakob avatar Aug 14 '19 19:08 jjakob

getChannels could be made to work in onClose, as the following works and gets me the channel id:

var channels = Variables.ws.connMgr.getChannels(); // connectionManager
var id = arguments.websocket.getId();

// keys are channel ids, value is the number of subscribers
for (chanId in channels) {
	if (channels[chanId] > 0) {
		var chan = Variables.ws.connMgr.getChannel(chanId);
		if (isNull(chan)){
			this.log("getchannel returned null!")
		} else {
			// we can't for loop over getsubscribers because it's a java.util.HashMap and lucee can't cast it to [collection], so we use java's iterator
			var wssetiter = chan.getSubscribers().iterator();
			while (wssetiter.hasNext()) {
				if (wssetiter.next().getId() == id){
					// found our channel id
					var myId = chanId;
					break;
				} 
			}
			// no channel id found (not subscribed to any channels)
			var myId = null;
		}
	}
}

jjakob avatar Aug 14 '19 20:08 jjakob

By the way, this is the exception that's thrown when trying to for loop over what getSubscribers returns:

lucee.runtime.exp.CasterException: Can't cast Object type [java.util.HashSet] to a value of type
 [collection]. stack trace: lucee.runtime.exp.CasterException: Can't cast Object type [java.util.HashSet] to a value of type [collection]                                                                  
        at lucee.runtime.op.Caster.toCollection(Caster.java:3959)                                                                                                                                          
        at lucee.runtime.util.ForEachUtil.forEach(ForEachUtil.java:65)                                                                                                                                     

This is probably a bug too, as getSubscribers is unusable without resorting to Java trickery as in the code above. Code that should work (place it in the above post's code), but throws the above exception:

	var wsset = chan.getSubscribers()
	for (ws in wsset) {
		if (ws.getId() == id){
			// found our channel id
			var myId = chanId;
			break;
		} 
	}

jjakob avatar Aug 14 '19 20:08 jjakob