SocketIO send message to client via API route - node.js

I have a route in my express API where I want to emit messages using a websocket to a client. In this case, the client is another Node.js app. In this Node.js app, I try to connect to the socket and print messages received. Both the API and the Node app are on different ports. Can someone help me make this work?
Here's how I pass my socket to my express routes:
const server = app.listen(PORT, () => {
console.log(`Server on port ${PORT}`);
});
const io = require("socket.io")(server);
app.set("socketio", io);
Here's my REST API route:
exports.getAll = function(req,res){
var io = req.app.get('socketio');
io.emit('hi!');
}
Here's my socket io client, it uses socket.io-client
const socket = io('http://localhost:3000');
socket.on("message", data => {
console.log(data);
});
Unfortunately, I don't receive the 'hi' message from my API.
When I call /api/getAll I don't receive the message in my client app.

When emitting an event via socket.io you have you define the event name before the data.
Example:
exports.getAll = function(req, res){
var io = req.app.get("socketio");
io.emit("message", "hi!");
}
Now you'll be able to receive the message event from the client.
Reference:
https://socket.io/docs/v4/emitting-events/

Related

How to send websocket message to client from the serverside

Hello I have two backends laravel and Nodejs
and There will be one frontend.
So if the front end requests something on laravel and laravel requests to node and Node has to send a message to the client through WebSocket.
How to do It?
Index.js
const app = require('express')();
const http = require('http');
const WebSocket = require('ws')
//initialize a simple http server
const server = http.createServer(app);
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
let sendNotification;
//initialize the WebSocket server instance
const wss = new WebSocket.Server({ server });
let socketapi = require('./socketapi')
socketapi.start(wss)
//start our server
server.listen(process.env.PORT || 5555, () => {
console.log(`Server started on port ${server.address().port} :)`);
});
socketapi.js
module.exports ={
start: (wss) => {
wss.on('connection', (ws) => {
console.log('connected!!!');
console.log(socketIds)
//connection is up, let's add a simple simple event
// triggerMessage('data');
ws.id=uuidv4()
ws.on('message', (message) => {
console.log('received: %s', message);
// ws.send(`Hello, you sent -> ${message}`);
});
}
}
}
Now I want to use this socket in the controller file and send it as I get a request.
When I export and import socket it logs as undefined.
I have stored and ws in array with particular Id and that Id was associated with data in DB so I can use that Id to get ws and send through that ws on function calling

Socket io as a service with Express REST API

I have a REST api using express server and I want to receive notifications from certain routes using Socket.io as a service.
Can I emit from withing an express route on a already running express server
and have a client listening to my api on it's root to log notifications?
What I'm trying to do:
in my route controller
exports.authenticate = (req, res) => {
... on success:
socket = io()
socket.emit('logged in', "new user logged in")
}
my socket io client:
let socket = io('localhost:3000', {cors: { origin: '*' }})
socket.on('logged in', () => {
console.log("login notification")
})
I'm running my api alone, and then I'm running my client script using node client.
but I'm not receiving anything

WebSocket in Node routes

I have a REST API backend. I'm trying to send WebSocket messages back to the client app when a site administrator invokes a route (i.e. updates user credentials);
let express = require("express");
let router = express.Router();
//update user credentials
router.put('/admin/user/:id', (req, res)=>{
// 1. Admin updates target user's profile/credentials
// 2. WebSocket message sent to target user client
// 3. Route sends res.status(200) to admin
});
I've seen a few WebSocket examples using 'ws', 'net', 'websocket' libraries, but they all show a simple event handling socket server that responds to socket messages outside of any express routes - let alone responds to a separate client.
Also, the event notification should be visible only to the target user and not all the other users connected to the socket server.
Figured it out. The WebSocket server is independent of the route.
const WebSocket = require("ws");
const wss = new WebSocket.Server({port: 5555});
// handle socket communications
wss.on('connection', (session)=> {
session.send("HELLO SESSION: "+ session.userid);
session.on('message', (message)=> {
console.log(`MSG: "${message}" recived.`);
session.send("Got it.");
});
});
// close
wss.on('close', function close() {
clearInterval(interval);
});
module.exports = wss;
Then, in the route, just include the service and use it to iterate through web socket connections like so:
let wss = require('./mysocketservice')
...
function sendAMessageTo(user, msg) {
wss.clients.forEach(function each(s) {
if(session.user = user)
session.send("still there?.. ");
}
}

One specific "socket.on()" doesn't work on client side

Server receive message from socket.emit("Wiadomosc"), but client doesn't,
but when I emit message from server io.emit("Wiadomosc"), client receive message;
There is no errors, others socket.emit() socket.on() works fine
I tried everything: copied everything from working functions and nothing.
I think that there is something wrong with me and not with code
Okey, client side:
socket = io.connect("localhost:4000", {
transports: ['websocket']
});
socket.on("Wiadomosc", function () {
console.log("wd");
});
socket.on("gotowosc", function () {
$(".gotowosc").css("display", "block");
});
//somewhere else in code
console.log(socket) //to see if it's fine, and it is
socket.emit("Wiadomosc");
the second one works fine
server side:
let express = require("express");
let app = express();
let server = app.listen(4000, function () {
console.log("listening on port 4000");
});
let socket = require("socket.io");
let io = socket(server);
io.on("connection", function (socket) {
socket.on("Wiadomosc", function () { //I did something like that to check if emit works, and it works
console.log("fine");
});
});
io.emit("gotowosc");
Emitting from a client sends to the server, not to any other client. If you want to send a message from one client to all clients, you send a message to the server and then code the server to receive it and send it to other clients.

Debugging socket.io using Smart Websocket Client

I want to manual test my websocket funcstionality.I am using socket.io and just installed a chrome to extension which allows me to connect to my server and send messages to it.
After some research I found out the sceheme that socket.io uses to send messages - 42["{event}", {data}]
I must be doing something wrong because when I try to send this message I dont trigger my callback.
Here is my server side code:
import * as express from 'express';
import * as http from 'http';
import * as socketIo from 'socket.io';
import config from './config';
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
// URL: ws://localhost:1337/socket.io/?EIO=3&transport=websocket
io.on('connection', function(client: socketIo.Client){
console.log('Client connected..');
io.on('auth', (data:any) => {
console.log(data);
});
});
//start our server
server.listen(config.port, () => {
console.log(`Server listening on port ${config.port}.`);
});
And here is the message which I am sending to my server.
42["auth","test"]
Here is a screenshot aswell.
I get the message when I connect to the websocket, but I cant trigger my callback for the 'auth' command.
I had the code wrong..
io.on('connection', function(socket:SocketIO.Socket){
console.log('Client connected..');
socket.on('auth', (data:any) => {
console.log(data);
});
});

Resources