Lucee websockets extension in three node cluster

Is there a recommended way of handling a clustered environment with the websocket extension? Our application is currently routed through Amazon Elastic Load Balancer and goes into three nodes. The issue we are having in testing is that the each node is not in sync with one another. We have tried to solve this issue by firing up a single EC2 instance and having all websocket requests go to a subdomain (ws.example.com) but the issue with this is that now the sessionScope does not contain the users current session, it is null. Maybe there is another creative way to handle this that I am not thinking of.

Do you cluster the Session scope right now between the nodes? If so, how?

Yes we are using a clustered session scope. This is what we have in Application.cfc:

	this.sessionManagement=true;
	this.setClientCookies=true;
	this.sessionStorage="cfsessions";
	this.sessionCluster=true;

TBH I didn’t do any testing with clusters yet. I was hoping that it would work out of the box, though I didn’t keep those hopes high.

I will have to think about that and run some tests. A little busy ATM though.

I’ve been wondering about this as well. I don’t expect the sub-domain trick to work due to the way Tomcat maps the contexts. I’m guessing that Lucee requires the same Tomcat mapping for all instances in your cluster, but I could be wrong about that. There might be a way to make it work.

In terms of session syncing, I’m guessing that the sessionScope argument passed into Listener Component callbacks is a read-only copy of the session. @21Solutions - Is it a copy or a reference? Can it be modified? If it’s a copy, when was the copy made (before each callback or when the connection was open).

Also, keep in mind that the code you execute in your Listener Callbacks cannot access the session scope directly, ie Session.myVar. I wish there was a way to configure the extension to make this possible. My understanding is that there is no way to make the extension work this way.

Not sure what makes you think that?

It’s a reference, and it can be modified. You can easily test these things.

I am going to test one other thing today. I think having a second virtual host in Apache listening on a different port other than the standard ones ex. https://www.example.com:1234 and then proxying the request to the websocket server may work. That would avoid the subdomain all together and keep the original domain. I will report back my findings later.

Thanks for clarifying… I believe I already tested this, and I do recall seeing changes to the session scope after being modified in a websocket. However, I’m wondering if there could be issues writing to the session that have to do with with concurrency and gaining exclusive access to the session scope. For example, can you create an exclusive session lock like this:

lock action="exclusive" type="session" timeout="10" throwontimeout="true" { ... }

Would this session lock be respected by the cluster? If not, can you create named exclusive locks that are respected by the cluster?

Also, in a clustered environment, since the session is stored somewhere (ehcache, memcache, etc.), are changes to the session being saved after each callback is executed?

You can use your session database to perform a lock across a cluster:

<cftransaction action="begin" isolation="serializable">
<cfquery name="sessionlock" datasource="cfsessions">
  select cfid from cf_session_data where cfid=<cfqueryparam value="#cfid#"> for update
</cfquery>
....
</cftransaction>
1 Like

@Yamaha32088, any luck on getting this to work?

I did get it to work but it was very hacky and insecure so I scrapped that idea. I haven’t had time to revisit it since.