Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getChannels returns an empty collection when called from onClose() #19

Open
jjakob opened this issue Aug 14, 2019 · 2 comments
Open

getChannels returns an empty collection when called from onClose() #19

jjakob opened this issue Aug 14, 2019 · 2 comments

Comments

@jjakob
Copy link

jjakob commented Aug 14, 2019

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
Copy link
Author

jjakob commented Aug 14, 2019

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
Copy link
Author

jjakob commented Aug 14, 2019

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;
		} 
	}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant