Yesterday I blogged about an issue I was having with Websockets and scopes vanishing. After some comments to the post and subsequent messages on the FW\1 Google group I decided to do a little more testing. I was trying to see under what condition were the scopes being lost.

Initial test.

First step was to have an application.cfc setup with a websocket channel.

Application.cfc content:

view plain print about
1component {
2    
3    this.name = "wstesting";
4    this.wschannels = [{name:"wstest"}];
5    this.sessionmanagement = true;
6    this.sessiontimeout = CreateTimeSpan(0,2,0,0);
7    
8}

Next up is the cfm files. These 2 blocks of code would go into separate files.

First the file to receive messages (receive.cfm):

view plain print about
1<script language="JavaScript">
2    function myHandler(msg){
3        console.dir(msg);
4    }    
5    
6</script>
7<cfwebsocket name="myws" onmessage="myHandler" subscribeto="wstest">

Then the file to send a message (send.cfm):

view plain print about
1<cfscript>
2    writeDump(var: cgi, label: 'cgi before');
3    writeDump(var: session, label: 'session before');
4    wsPublish("wstest",'my message');
5    writeOutput("<hr>");
6    writeDump(var: cgi, label: 'cgi before');
7    writeDump(var: session, label: 'session before');
8
</cfscript>

So, to set it all up. Create the 3 files. First call the receive.cfm in a browser. Then in a new browser window call the send.cfm.

What you should see is that the session dumps are the same before and after. However, the cgi dump is different. The cgi dump is all based of the wspublish call and not the original request. However, the session scope is left untouched.

Now, lets make some modifications to do the same test inside a Framework One application. If you are unfamiliar with FW\1 then some of this may not make sense. But if you are you should be able to follow along.

First, modify the the application.cfc to extend the framework. Also, add a before and after function to the app.cfc that contain the scope dumps.

view plain print about
1function before( rc ) {
2    writeDump(var: request, label: 'request before');
3    writeDump(var: cgi, label: 'cgi before');
4    writeDump(var: session, label: 'session before');
5}
6    
7    
8function after ( rc ) {
9    writeDump(var: request, label: 'request after');
10    writeDump(var: cgi, label: 'cgi after');
11    writeDump(var: session, label: 'session after');            
12}

Next create a view for the send and receive. In the receive put in the same code as the first example. The send view can be an empty file.

In the controller that would be called for the send just do a simple wspublish.

view plain print about
1public void function send( rc ) {
2    wsPublish("wstest", 'something');
3}

Now, that you have all that setup lets run the code. Just like before, first call the receive code. You should see 6 dumps that all mirror each other. Next call the send. This should throw an error. You should have 5 dumps and then the error. Take careful note of the dumps. The request dump in the after is all but gone except for one value. The CGI scope is redone just like the first example.

Now the odd part. The error that is thrown should state that "Variable SESSION is undefined."

For fun, go into the controller and remove the wspublish line. Then call the send again. This time the dumps should all work without error.

So there you go. While this doesn't correct the issue it at least gives more insite as to what is going on.

Till next time...

--Dave