Send messages from server (Expressjs routing) to client - javascript

I want to send messages from the server to the client and implement this in routes/index.js of my mean stack project. Does anyone know how to use socket.io here?:
router.post('/message/sendMessage', function (req, res, next) {
console.log("router.post /message/sendMessage " + req.body)
// send req.body to client
});
PS: Previously, I have used socket.io one time in the project: the client opens a socket, and then the server emits a message named id, the client receives it. In the client:
socket = io.connect();
socket.on('id', function (id) { ... })
In www (server):
io.sockets.on('connection', function (socket) {
console.log("LOG: just connected: " + socket.id);
socket.emit('id', socket.id);
socket.on('disconnect', function () {
console.log("LOG: just disconnected: " + socket.id)
})
})
But I cannot imagine how to write socket.emit inside Expressjs routing...
Edit 1: I tried to do the following to send a message to all the clients but in the console, it only displayed until before emit, and in the client it showed Failed to load resource: the server responded with a status of 500 (Internal Server Error)
router.post('/message/sendMessage', function (req, res, next) {
console.log("router.post /message/sendMessage");
console.log("before emit");
io.sockets.on('connection', function (socket) {
console.log("LOG: just connected: " + socket.id);
io.emit("message", "this is a test");
socket.on('disconnect', function () {
console.log("LOG: just disconnected: " + socket.id)
})
})
console.log("after emit");
});

Actually my question comes down to a common question: how to use socket.io inside an express routes file.
And I have found a super answer: https://stackoverflow.com/a/31277123/702977
So in www:
var io = require('socket.io').listen(server);
app.set('socketio', io);
and in index.js:
router.post('/message/sendMessage', function (req, res, next) {
console.log("router.post /message/sendMessage");
var io = req.app.get('socketio');
io.emit("message", "hi!");
res.json("hahaha")
});
If I want to send a message to a certain client, I need to pass the information like id as a parameter into router.post, and then use for example io.to(req.body.id).emit("message", req.body.message);

Related

Socket.io client cant connect to server

I have issue related to Socket.io connection to server.
Its working fine on my local, but on dev-server it cant connect.
My backend code look like this:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
server.listen(8080);
console.log('CONNECTED');
io.on('connection', function (socket) {
var handshake = socket.handshake;
console.log(handshake);
console.log("new client connected");
var redisClient = redis.createClient();
redisClient.subscribe('notification');
redisClient.subscribe('rate');
redisClient.on("message", function(channel, message) {
console.log("New message: " + message + ". In channel: " + channel);
socket.emit(channel, message);
});
socket.on('disconnect', function() {
redisClient.quit();
});
});
And my client part like this:
var socket = io.connect('http://localhost:8080');
socket.on('notification', function (data) { console.log(data) }
The error that im facing is when socket.io client tries to send to URL "http://localhost:8080/socket.io/?EIO=3&transport=polling&t=MD_W4lE" request and its failing, with error ERR_CONNECTION_REFUSED. The node server is runing i tested and also tried to change localhost to 127.0.0.1 and ipv4 address, i didnt helped.

Socket.io - Connect from client to server via https

I have created a socket.io chat application on my virtual server (Ubuntu), which runs as an systemd service and which is active running.
My server.js is located in:
/var/www/vhosts/mywebpage.de/w1.mywebpage.de/chat/
The server.js looks like this:
const io = require('socket.io')(3055);
io.on('connection', function(socket) {
// When the client emits 'addUser', this listens and executes
socket.on('addUser', function(username, room) {
...
});
// When the client emits 'sendMessage', this listens and executes
socket.on('sendMessage', function(msg) {
...
});
// Disconnect the user
socket.on('disconnectUser', function(username, room) {
...
});
});
In my website (https) I try to connect as follow:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script type="text/javascript">
var loSocket;
$(document).ready(function() {
if(typeof(loSocket) == 'undefined') {
loSocket = io('https://w1.mywebpage.de:3055', {
reconnectionAttempts: 5,
forceNew: true
});
}
});
</script>
But I can't get a valid connection.
The developer tools say this:
(failed) ERR_CONNECTION_CLOSED with initiator polling-xhr.js:264.
What could be the error ?
From what I have done in the past I would create a https server which serves the SSL cert and create the socket server using the https server you created, this will allow you to connect via https and you will need to enable secure on socketio (use this question as a ref)
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Use this code as ref on how to create a socketio server using http
You can find this code on the socket.io docs
NOTE: You will need to you https not http like shown in the example

How to separate input/output from pipe socket server in nodejs?

I have below source code about socket server/client in nodejs.
const net = require('net');
net.createServer((socket)=>{
socket.pipe(socket);
socket.on('data', (data)=>{
console.log('receive data ', data.toString());
socket.write('this is server')
});
}).listen(3000);
console.log("Chat server running at port 5000\n");
let client = new net.Socket();
client.setEncoding('utf8');
client.connect(3000, '127.0.0.1', function() {
console.log('Connected');
client.write('Hello, server! Love, Client.');
});
client.on('data', function(data) {
console.log('Received: ' + data);
});
when I run above code, the server will send the data(which is from the client) back to the client. I know this is cased by socket.pipe(socket);. I want to keep that code and am looking for a way to separate the input/output data in client side like below:
client.on('data', function(data) {
if( the data is sent from client ){
...
} else {
//this is the data generated from server
}
});
Does anyone know how to do that in nodejs client side?
Actually you can separate out the data from client and server, depending upon what messages you emit or what you listen, from that you can distinguish between client and server.
The message you emit from server are the message, you received on the client side if client is listening to that messages, the message you emit by client are the message received on server if server is listening to the messages.
Below is the code for a socket.io
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.send('<h1>SocketChat Server</h1>');
});
http.listen(3000, function(){
console.log('Listening on *:3000');
});
io.on('connection', function(clientSocket){
/* Here server is listening to client 'connectUser' message so here data is sent from client*/
clientSocket.on('connectUser', function(clientNickname, groupName) {
var message = "User " + clientNickname + " was connected." + clientSocket;
console.log(message);
clientSocket.emit('userConnected');
});
});
/* Here server is emitting message('userConnected') that will be received by client. */
From above you can see that how to distinguish the client and server messages.

socket.io doesn't receive data

I have a simple client server web app that is using web sockets to send / receive information. The client can connect and receives properly the config file but then when I try to send a "test' message from the client using "socket.emit('message', {my: 'data'});" it doesn't display on the server. I did check with wireshark and the packets are arriving at the server.
var sIoPort = 8181;
var host = '192.168.4.111';
var fs = require('fs');
var iniMsg = fs.readFileSync('data.json','utf8');
var http = require("http").createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
});
http.listen(sIoPort,host);
var browserServer = require('socket.io').listen(http);
browserServer.on('connection', function (socket) {
console.log('Client websocket connected');
// send the config file if available
browserServer.sockets.emit('msg',iniMsg.toString());
});
browserServer.on('message', function (message) {
console.log('received message: ' + message);
});
client side
///////////////////////////////////////////////////////////////////////////////
socket = io.connect("192.168.4.111",{"port":8181});
socket.on('connect',function() {if(DEBUG) console.log('Socket Connected');});
socket.emit('message', {my: 'data'}); // test if server receives message
socket.on('msg',function(data) {
var json = JSON.parse(data);
// add the maps to the the GUI
switch(json.type) {
case 'maps': add_maps_from_json(json, null);
break;
}
});
socket.on('disconnect',function() {if(DEBUG) console.log('Socket Disconnected');});
/////////////////////////////////////////////////////////////////////////////////
Modify the serverside listener so it's paying attention to events on a socket:
browserServer.on('connection', function (socket) {
console.log('Client websocket connected');
// send the config file if available
browserServer.sockets.emit('msg',iniMsg.toString());
socket.on('message', function (message) {
console.log('received message: ' + message);
});
});

Sending message to Socket.IO via get request

I have an express node.js server serving Socket.io. I would like the ability to make get requests to the express server that will automatically send a message to a channel.
var app = require('express').createServer()
, io = require('socket.io').listen(app)
app.listen(80);
app.get('/:channel/:message', function (req, res) {
//Code to create socket
socket.emit("sent from get", {channel:req.params.channel, message:req.params.message})
});
io.sockets.on('connection', function (socket) {
socket.on('sent from get', function (data) {
socket.broadcast.to(data.channel).emit('channel message', { message: data.message});
});
});
How to I create (and destroy) a socket connection in the app.get block?
(For clarity, I want to use this to send a quick message from a rails server when a particular object is saved, and have a message pushed to each appropriate user.)
io.sockets.in(req.params.channel).emit("channel message", {mes:req.params.message})
That will send a message to all users in the requested channel.
var chat = io.of('/chat').on('connection', function (socket) {
socket.emit('a message', { that: 'only', '/chat': 'will get' });
chat.emit('a message', { everyone: 'in', '/chat': 'will get' }); });
The following example defines a socket that listens on '/chat'

Categories

Resources