[Coldbox 5.x] - Node app inside subfolder?


My question is not exactly coldbox specific, but I’m hoping someone can maybe provide some input or suggestions. I have a coldbox website running on CF 2018. I am trying to build a chat/messaging feature using socket.io / nodejs. I have my Layout file (Layout.Messages.cfm) which contains the HTML header/footer for my site and in the main content area I have a “renderview()” call that currently returns HTML that contains the UI for the messaging/chat functionality. I want to build the chat functionality in nodejs and use socket.io but I am not sure how to embed a node.js app into an existing Coldbox view. The reason I want to embed it in the view is so I can leverage the existing Layout template which contains my site header/footer.

Is there a way to do this or would I need to create a subfolder dedicated to the nodeapp and recreate the Layout template on the node side and essentially treat the nodeapp like a standalone app that lives in a subfolder of the coldbox app? One requirement is if the user is logged into the main website, then they should also be logged into the node app or authorized.

I’m clearly a bit confused and unsure of a good approach, but would love to get any feedback or suggestions on ways I can set this up.

Thanks in advance!

I’m not a node or coldbox expert, but I think the main issue is ensuring that your coldbox and nodejs servers are on different ports. Then it’s just normal javascript accessing a separate server from the same webpage. The coldbox layout and view just provide the UI formatting and structure - nodejs would manage the data interchange for the chat.

Authentication is a different issue. You might consider using cbsecurity’s jwt functionality ( https://coldbox-security.ortusbooks.com/jwt/jwt-services ) to generate a json web token that can be read by nodejs after a successful login. Search for “nodejs jwt authentication” for some options on how to handle that from the nodejs side.

On the cbsecurity side, in your login handler it’s something like:

auth.authenticate( rc.username, rc.password );

cookie._jwt = { value="#jwtService.fromUser(auth.user())#" };

relocate( url = rc._securedURL );
} else {
relocate( uri = “/admin” );

} catch ( InvalidCredentials e ) {
flash.put( “login_form_errors”, { “login” : “Invalid Credentials” } );
redirectBack( persist="_securedURL");

Note that I injected the auth and jwtservice into my login handler as properties.

property name=“auth” inject=“AuthenticationService@cbauth”;
property name=“jwtService” inject=“JwtService@cbsecurity”;

Thanks for your response. I think I was overthinking it and your response I think simplified things. I think I may need to use some reverse proxy to proxy the requests to the node app which will run on a different port as you mentioned.

You know your app better than I do, but if both the node app and cf server are on the same machine with different ports, you should be able to connect to the node server without a proxy directly from the web page. It’s a call to the same domain, just a different port. I assume the node portion is just passing text messages back and forth over websockets.

Yes, that is what I’m finding now as I started building it out. They are on the same machine and so far no reverse proxy is needed. I created a javascript file (messages.js) with something like this and it seems to be working. I essentially start the node app / express server and it is listening on port 8000. By having that first line you see in the code below it is allowing me to send messages back and forth as you said.

const socket = io(‘http://localhost:8000’);

document.querySelector(’#frmMessages’).addEventListener(‘submit’,(event)=> {
const newMessage = $.trim($("#user-message").val());
socket.emit(‘newMessageToServer’,{text: newMessage});

If you were able to get this working, would you mind sharing your code? I need to use websockets to broadcast feedback for a database processing sequence.