Can someone point me to how i would add a Socket IO Client to my javascript web application to be informed when topical activity occurs within select NodeBB categories
-
I've successfully leveraged the NodeBB API to relay topical data into our web application. We do this for select groups.
For example we have a category of topics for news items. When a news item topic is added to this category, we want to display a "ticker update" in our web application.
Right now I need a timer that drives a refresh so that i can ask for an update to the news category. I'd rather be notified asynchronously (via a socket io message) that an update is ready.
I've used socket io in the past to deliver asynchronous notifications from a backend service into a React web application. I think I've heard that NodeBB supports such asynchronous delivery of noficiations.
Please provide guidance to help me get asynchronous notification (via socket io) up and running.
Thanks.
-
Assuming you have already connected to the nodebb socket.io server all you need to do to listen for new topics is below.
socket.on('event:new_topic', function (data) { console.log('a new topic was posted', data); });
You get the socket object by establishing a connection. https://github.com/NodeBB/NodeBB/blob/master/public/src/sockets.js#L15-L25
-
@baris I'll try it immediately.. I love how you take me to exactly the code snippets i need. Ty!
As an aside, is there also some decent documentation on this interface?
I am looking at the rich API reference, and not seeing it at first, or second, glance.
-
Thanks @baris You guys are really an excellent team.. Thanks for the fast response.. I'll give it a crank.
-
As an aside, where should I look for the following critical configuration detail:
window.socket = io(config.websocketAddress, ioParams);
Would it just be as follows:
window.socket = io("http://localhost:4567", ioParams);
Or do I need to augment that URL?
Assuming that my NodeBB is on localhost at 4567, what would my websocketAddress be?
I dont see the "config file" that is used to populate related parameters:
const ioParams = { reconnectionAttempts: config.maxReconnectionAttempts, reconnectionDelay: config.reconnectionDelay, transports: config.socketioTransports, path: config.relative_path + '/socket.io', query: { _csrf: config.csrf_token, }, };
-
Hmm.. I dont see that folder in the git tree.. nor in the cloned tree
-
@baris That helps.
I've seeded the code as follows:
import { io } from "socket.io-client"; const websocketAddress = "http://localhost:4567"; const ioParams = { reconnectionDelayMax: 10000, auth: { token: "123" }, query: { "my-key": "my-value" } }; export const socket = io(websocketAddress, ioParams); socket.on("connect", () => { console.log("yay"); })
I currently see this:
-
So I'm not sure why I'm seeing the CORS problem. As you see in the figure below I actually exercise the "api/categories" route just fine..
This is because I've configured CORS in the ACP.
Yet the socket IO connection is complaining..
Do you see something wrong with my client code? -
Try using http://127.0.0.1:4567 as your url in config.json and access the site with that url as well. I think chrome treats localhost as xorigin.
If you need to access the socket.io server from a different origin then you need to setup
socket.io:origins
option in config.json. You can find more info about that here -
This is my current config.json:
{ "url": "http://localhost:4567", "secret": "9e7759e1-4cef-4eed-9a98-dbc7768e0b2b", "database": "mongo", "mongo": { "host": "127.0.0.1", "port": "27017", "username": "votf", "password": "votf", "database": "learning_center", "uri": "" }, "port": "4567" }
I see the documentation on socket.io:origins:
It says "A hash with socket.io settings"..
Does this really just mean a json object as follows:
{ "url": "http://localhost:4567", "secret": "9e7759e1-4cef-4eed-9a98-dbc7768e0b2b", "database": "mongo", "mongo": { "host": "127.0.0.1", "port": "27017", "username": "votf", "password": "votf", "database": "learning_center", "uri": "" }, "port": "4567", "socket.io": { "origins": "http://127.0.0.1:3000", }, }
My web app runs on port 3000. Nodebb runs on port 4567.
When I make that change to config.json, my error changes to the following:
Also with a slight variant on the origins:
{ "url": "http://localhost:4567", "secret": "9e7759e1-4cef-4eed-9a98-dbc7768e0b2b", "database": "mongo", "mongo": { "host": "127.0.0.1", "port": "27017", "username": "votf", "password": "votf", "database": "learning_center", "uri": "" }, "port": "4567", "socket.io": { "origins": "http://localhost:3000,http://127.0.0.1:3000,http://localhost:*" } }
-
Maybe try with
{ "url": "http://127.0.0.1:4567", "secret": "9e7759e1-4cef-4eed-9a98-dbc7768e0b2b", "database": "mongo", "mongo": { "host": "127.0.0.1", "port": "27017", "username": "votf", "password": "votf", "database": "learning_center", "uri": "" }, "port": "4567", "socket.io": { "origins": "http://127.0.0.1:*", }, }
You also need to send a csrf_token in the query string like we do during connection https://github.com/NodeBB/NodeBB/blob/master/public/src/sockets.js#L20-L22
-
ah. maybe the CSRF token is the magic.. i actually did try the http://127.0.0.1:*.. How do I know, what value that CSRF token should have? Do I find that in the config.json? Do I set it to the "secret" in config.json?
In the file you linked above, you set it to the following:
"csrf_token": "0f80459650aa8085dcb0c87e714ae3517f17b9426c17354f03251fb44c0737d310b5b4779a380047c67e1107538d4ad85731284d14d64ed4429603e4317da456",
But that doesnt feel right. I had no clue how you created that token, so I didnt bother trying to set that.
-
@baris Got it.. ty .. thats starting to hang together for me!! will give that a go.
-
@baris
Well I'm crawling towards correct.. I am now using the token found in the call to /api/configI'm also using a config.json that has been set as follows:
{ "url": "http://localhost:4567", "secret": "9e7759e1-4cef-4eed-9a98-dbc7768e0b2b", "database": "mongo", "mongo": { "host": "127.0.0.1", "port": "27017", "username": "votf", "password": "votf", "database": "learning_center", "uri": "" }, "port": "4567", "socket.io": { "origins": "http://127.0.0.1:*" } }
I still see a 403
My current test client code:
import { io } from "socket.io-client"; const websocketAddress = "http://127.0.0.1:4567"; const ioParams = { reconnectionDelayMax: 10000, auth: { token: "123" }, query: { "_csrf": "3aa60581b3f0fdf2091d68a3851bb62a1a1f3e6bd4a9774c8bf10873baf1a984845725af217817d41d3985ebce3df211cd98d6173651840adcf41f453c19a5c0" } }; export const socket = io(websocketAddress, ioParams); socket.on("connect", () => { console.log("yay"); })
I've also updated the Access-Control-Allow-Origin in the ACP as follows (not really knowing what to do):
Previously, all I needed in the ACP was the first parameter: http://localhost:3000 (that allowed me to get the NodeBB API calls working)
-
I just reviewed how I set up my own "dev socket io server" in the past. I did so with the following cors setting (in this case this was strictly a dev server, so "*" was ok).
But I'm pretty sure the 403 is because we've not hit the right CORS magic that is compatible with how NodeBB is configuring the SocketIO server..
Its the NodeBB server that is returning 403.
This is what I see in terms of the socket io cors setup in the NodeBB codebase.
Perhaps this suggests that I must also add a "cors" option to the "socket.io" object in config.json
Something like the following?
{ "url": "http://localhost:4567", "secret": "9e7759e1-4cef-4eed-9a98-dbc7768e0b2b", "database": "mongo", "mongo": { "host": "127.0.0.1", "port": "27017", "username": "votf", "password": "votf", "database": "learning_center", "uri": "" }, "port": "4567", "socket.io": { "origins": "http://127.0.0.1:*", "cors": "http://127.0.0.1:*" } }
Though I just tried that, with a couple different settings for "cors" .. and none of that worked.
-
Not sure where to go next.. i've tried a number of variations.. seems like what I have should work, yet my socketio connection request is rejected because of CORS.