Lucee Websockets Extension

Great to hear. I’ve been testing on Windows properly so no it’s not OS-specific AFAIK.

Thanks, I hope to look into it soon.

Thank you for posting the updated feedback :slight_smile:

I just tried using this and I notice that it is producing the following
json.

Object {MESSAGE: "Hello", TIMESTAMP: 1497640931522, CHANNEL: "default",
FROM: "GM"}

When THIS is what it should be producing to be valid JSON.

Object {"MESSAGE": "Hello", "TIMESTAMP": 1497640931522, "CHANNEL":
"default", "FROM": "GM"}

Please fix this or tell me how to pull just the message from the JSON.
Because evt.data.Message is undefined because of the lack of quotes.

The extension does not produce any JSON. Please post your code that produces this.

Also, please post either here, or on Github, but not on both. Thanks.

Sorry about the double.

So when I send that, I get back what looks to be a JSON object.

The example code shows it is parsing JSON.

If it doesn’t return JSON (though it looks like it’s trying), then please
tell me how I set a variable to what the “message” is.

This is the client (JavaScript) code. How do you send the message from the extension? i.e. What’s in your Listener Component’s onMessage()?

How do you send the message from the extension?

I haven’t set that up yet, but I see no reason why I can’t use cfscript to
take a form element and send it to the websocket.

i.e. What’s in your Listener Component’s onMessage()?

It’s exactly what you have in the “Example Chat” code.

I’m trying to just have it print out what is received. I was hoping that
copying the example chat would actually make it work. But right now, the
data that comes back when I alert it is “undefined”.

Please tell me how I can get the message that got sent within your chat
code and I can probably piece together the rest. This is as close to server
side websockets that I’ve been able to do. It’s a key piece to some code
I’ve been working on, but it seems that I can’t parse the data
received because it’s not valid JSON. Can you at least put quotes around
the field names so that it IS valid JSON?

I’m sorry, but you are really not giving me any information to help you. The data sent seems to be working fine for others who have used the extension, and I don’t know how you set up your app or what you put in the code.

Obviously it is not exactly as in my example or else it would have worked.

Please note that I have the setting in the Admin to preserve the key case, so my data is serialized with lower case keys, e.g. “message”, unlike your UPPER CASE KEYS, e.g. “MESSAGE”, so that might be a factor here, but I can’t help any further without seeing your code.

Obviously it is not exactly as in my example or else it would have worked.

Your code IS working exactly how the video says it’s working.

What I am trying to do is display the message on the page. The console
shows the message coming in. So I get the message. I thought it might be
JSON (espically since you are trying to parse it what seems to be JSON, but
falty).

sighs and takes a breath

Here…

This is the code…

Please note that all the other files are EXACTLY the same as the example
code except for the last line (it’s highlighted).

document.write(log.message);

This seems like it SHOULD parse the list and return me the message field.

This is the result…

As you can see, it’s undefined (because it’s not valid JSON).

To me, it seems like the most logical answer is to make it valid JSON by
having it return the message field with quotes and so on. So…

Object {MESSAGE: “Hello”, TIMESTAMP: 1497640931522, CHANNEL: “default”,
FROM: “GM”}

becomes

Object {“MESSAGE”: “Hello”, “TIMESTAMP”: 1497640931522, “CHANNEL”:
“default”, “FROM”: “GM”}

So that way, log.message (or MESSAGE in my case)

But let’s say that you don’t want it as JSON… Ok… My question then is
simple…

What line of code should I put to replace

document.write(log.message);

with so that the webpage displays “Hello” instead of “undefined”?

Oh… and before you try to say the write needs to be within the function…
It doesn’t work there either…

and the code…

So please… I’m pulling out my hair here trying to figure out how to take
your data that is returning and pull messages out of it (along with CHANNEL
and FROM and TIMESTAMP).

Am I still not explaining the issue well enough? I’m not sure how else to
explain it to get my point across.

Actually, it’s undefined because you aren’t returning a value from the log function. You’re taking the evt data and passing it to console.log, but that’s all you ever do with it.

That document.write you removed is literally the only part of the function that preserves the data. :slight_smile:

Further, writing out log.MESSAGE is going to be undefined - because you’re pulling the MESSAGE method of the log function/object - which isn’t being set.

You also wouldn’t want to set it.

Since websockets are going to be externally triggered you need to deal with them asynchronously in your javascript code. At the time your document.write(log.MESSAGE) runs, the websocket may not be initialized yet. That’s why the sample would have the document.write() within the log function - because that’s your callback for when a message is received. Your document.write(log.MESSAGE) only happens once, at page load, right now.

It’s likely valid JSON coming back from the server. The browser is just showing you the resultant javascript object, not the JSON.

You can tell this because the log window says Object {}

If you were looking at raw JSON, it would be logged as a string:

  "{ \"MESSAGE\":\"Hello\", \"TIMESTAMP\": 1497640931522, \"CHANNEL\": \"default\",
\"FROM\": \"GM\"}"

You can further verify this in the Network panel.

This would be easier if you had your code in something like pastebin where we could copy it, but no worries, I’ll retype. Your log function is the problem.

Yours:

  var log = function(evt) {
    console.log(evt.data ? JSON.parse(evt) : evt);
    document.write(log.MESSAGE);
  };

Your “log” variable is still not your message. The only thing you’ve set it to is an anonymous function.

Try this.

  var log = function(evt) {
    var msg = evt.data ? JSON.parse(evt.data) : evt;
    console.log(msg);
    document.write(msg.MESSAGE);
  }

Just for the sake of sanity I probably wouldn’t call it log either. Something like processMessage sounds better, and eliminates confusion between console.log and log… log also implies you’re logging something which is only one of the purposes of the function.

2 Likes

Thanks. I’ll try that. The code is actually just a copy and paste from the
example given.

That worked. Thank you very much. :slight_smile:

Actually pasting the snippets here would have been easier. Clicking those links and trying to put them in context with the messages that surrounded them added much unnecessary confusion.

All these “sighs” etc. didn’t help either. We’re trying to help here and a great way to get free help in open source projects is to make it as easy as possible for the people who help you to get the relevant information.

I’m happy to learn that this was a JavaScript issue, not related to the extension.

Well, it WAS related to the example you wrote and put up. You may want to
fix it.

and sorry for the sighs… It just seems like I explained the issue multiple
times to you and you didn’t seem to understand the issue.

Fix what? The example logs the event information to the console so it’s appropriately named and does what it’s meant to do.

Nevermind. I appreciate the help you tried to give. Also, Mr. Gooch has my
thanks. He showed me how to drag out the fields I needed and now, the
“example chat” you wrote actually functions as a chat and not just part of
one.

I guess my main issue is that when you name an example “Example Chat”, it
should… you know… be a chat example. Not part of one. If you want, I will
send you what I have written over what you had so that it’s an actual chat
app using your websockets.

I limited the example to the Server portion for brevity and clarity. The chat server there is a working example. The client can be written in many different ways.

Then may I suggest you write up a simple one and include that so that
people like me can see both the client and server because for the longest
time, I was having difficulty getting the variables out until the other
person rewrote

  var log = function(evt) {
    console.log(evt.data ? JSON.parse(evt) : evt);
    document.write(log.MESSAGE);
  };

to

  var log = function(evt) {
    var msg = evt.data ? JSON.parse(evt.data) : evt;
    console.log(msg);
    document.write(msg.MESSAGE);
  }

Once he did that, I was able to extract the variables the server was
providing. This was the change I suggested so that it’s easier to pull out
those variables.

Hi @21Solutions, brand new to Lucee and haven’t worked w/ your extension yet, plan on watching the videos today or tomorrow. Quick question, I’m building a pretty complex web app and will be implementing a variety of realtime notifications, my question is, do you already know what kind of performance/scale your extension can handle? Like how many concurrent users/sockets at once on a typical server proc/RAM set up? Had planned on running a Node instance w/ Socket.io and just posting the data I needed to Socket to users from CF to Node to relay out the socket data, but if this extension is pretty stable and can handle load that’d save me a piece of stack.

Thanks!
David

The extension utilizes the Servlet container for that, e.g. Tomcat, so it really is up to the rest of the setup. The extension itself adds very little overhead, managing “channels” and retrieving Session information from Lucee.

Unfortunately I do not have any real numbers other than the following, which is an “nginx on Windows” thing, so if you front your Tomcat with nginx on Windows you should be aware:

nginx on Windows is limited to 1024 connections, and it uses 2 connections per websocket connection – one to communicate with the client and the other to communicate with the Servlet container – so once you open 512 connections you get in trouble.

The best solution that I found was to drop Windows as an OS, which is something that I’ve been wanting to do for a while anyway, but that’s not feasible for everyone, so other solutions might be using a different reverse proxy, or not at all, at least for the WebSocket connections, you can keep using nginx for your regular requests.

1 Like