Socketio Websocket on https does not work - node.js

I am using socket io to sent some notifications Messages to the web ui, but currently I get this error message:
https://12.123.12.12:3000/socket.io/?EIO=3&transport=polling&t=MMfbmct
0 ()
My socket.js file:
var fs = require('fs');
var app = require('https').createServer({
key: fs.readFileSync('/opt/bitnami/apache2/conf/serverKey.pem'),
cert: fs.readFileSync('/opt/bitnami/apache2/conf/serverCrt.pem')
}, handler);
var io = require('socket.io')(app);
var Redis = require('ioredis');
var redis = new Redis();
var Redis = require('ioredis');
function handler(req, res) {
res.writeHead(200);
res.end('');
}
io.on('connection', function(socket) {});
// ...
// run server on port 3000
app.listen(3000, function () {
console.log('Server running!');
});
The eventjs file tries to get the data from the socket and do stuff on the ui, this worked a while ago and I do not remember how I declared the socket variable
// I tried following declarations but none work
var socket = io('http://localhost:3000');
var socket = io('http://123.123.123.123:3000'); // sever ip
var socket = io('https://localhost:3000');
var socket = io('https://123.123.123.123:3000'); // sever ip
socket.on('signed-in-channel:App\\Events\\UserSignedIn', (data) => {
// some stuff
});
How do I declare the socket properly?

Related

Socket.io with Adonis.js

I am using Adonis 4.1.0 and Adonis-websocket is only been available for v3. Can anyone tell me workaround for using socket.io with Adonis 4.1.0?
apparently they have been working on this not long ago, it was based on socket.io but because of some issues like memory leaks and others, they decided to use websockets directly instead, check these discussions :
https://github.com/adonisjs/discussion/issues/51
https://forum.adonisjs.com/t/integrating-socket-io-with-adonis-4/519
have you tried using socket.io without relying on Adonis ? ,
something like :
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
But you should be able to do this with Adonis by now according to : https://github.com/adonisjs/adonis-websocket-protocol
Example :
const filereader = require('simple-filereader')
const msgpack = require('msgpack-lite')
const packets = require('#adonisjs/websocket-packets')
const client = new WebSocket('ws://localhost:3000/adonis-ws')
client.onopen = function () {
// TCP connection created
}
client.onerror = function () {
// TCP connection error
}
client.onmessage = function (message) {
filereader(message, function (error, payload) {
const packet = msgpack.decode(payload)
handlePacket(packet)
})
}
function handlePacket (packet) {
if (packets.isOpenPacket(packet)) {
console.log('Server ack connection. Make channel subscriptions now')
}
if (packets.isJoinAck(packet)) {
console.log('subscription created for %s', packet.d.topic)
}
}
check this for broadcast examples using WS : https://github.com/websockets/ws#broadcast-example
Create start/socket.js file and paste following code inside it.
const Server = use('Server')
const io = use('socket.io')(Server.getInstance())
io.on('connection', function (socket) {
console.log(socket.id)
})
From Virk Himself in this forum:https://forum.adonisjs.com/t/integrating-socket-io-with-adonis-4/519
create a standalone socket io configuration file in start/socket.js
const io = require('socket.io')();
io.listen(3000);
io.on('connection', function (socket) {
console.log(socket.id)
})
to start your socket io server you can configure your server.js as below
new Ignitor(require('#adonisjs/fold'))
.appRoot(__dirname)
.preLoad('start/socket') //path of socket.js
.fireHttpServer()
.catch(console.error)
now when you start your server then it will start along with socket io

uWebSockets - push events to server

I have a uWebSockets server as it seems to be a lot more performance friendly than socket.io servers.
So I have a server and its connected fine and after some trouble I got the index.html client side to connect, but now I'm not able to push events to the server from the client side. What am I doing wrong?
var WebSocketServer = require('uws').Server,
express = require('express'),
path = require('path'),
app = express(),
server = require('http').createServer(),
createEngine = require('node-twig').createEngine;
var wss = new WebSocketServer({server: server});
wss.on('connection', function (ws) {
ws.on('join', function (value) {
console.log('SOMEONE JUST JOINED');
});
ws.on('close', function () {
//console.log('stopping client interval');
clearInterval(id);
});
});
server.on('request', app);
server.listen(8080, function () {
console.log('Listening on http://localhost:8080');
});
index.html
<script>
var host = window.document.location.host.replace(/:.*/, '');
var server = new WebSocket('ws://' + host + ':8080');
server.onmessage = function (event) {
updateStats(JSON.parse(event.data));
};
server.onopen = function (event) {
server.send("Here's some text that the server is urgently awaiting!");
server.send('join');
};
function something() {
console.log('WORKED');
server.send('join');
}
</script>
You don't have an event listener setup on the server side that does receive and react on the message. Like
ws.on('message', function (msg) {
// Do something with the message received from the client
});

Node js, Call WebSocket server from http server

I have a node js ( supported by express js ) http application. So I had a server.js file as follows(not there complete code).
var app = require('./app/app');
var server = http.createServer(app);
server.listen(port, host);
server.on('error', onError);
server.on('listening', onListening);
I later added websocket server to there. So it is like this now.
// app server
var app = require('./app/app');
var server = http.createServer(app);
server.listen(port, host);
server.on('error', onError);
server.on('listening', onListening);
/**
* websocker Server
*/
var WebSocket = require('ws');
var wsServer = http.createServer();
var url = require('url');
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ server: wsServer });
var express = require('express');
var wsApp = express();
var port = 1337;
wsApp.use(function (req, res) {
res.send({ msg: 'hello' });
});
wss.on('connection', function connection(ws) {
console.log((new Date()) + ' Connection from origin ');
ws.on('message', function incoming(message) {
console.log('received: %s', message);
var json = JSON.stringify({ type:'message', data: {hello : 'hello'} });
ws.send(json);
});
var json = JSON.stringify({ type:'message', data: {hello : 'hello'} });
ws.send(json);
});
wsServer.on('request', wsApp);
wsServer.listen(port, function () { console.log('Ws server Listening on ' + wsServer.address().port); });
Now these two are working happily. What I want is on a POST call to the http server, I want to trigger the web socket server to broadcast something to all clients. My problem is How I can trigger websocket server from http server?
Routes of http server is defined in app.js file. from there how can I call websocker server function?
If you encapsulate your ws functionality in one single javascript file (e.g: websocket.js) you could export your websocket object as a module.
module.exports = wss;
and then require it in your http controller
var wss = require(websocket.js)
In this case it should be easy to use wss.send({...}) wherever you like.
This peace of code is working to me:
//websocket.js
'use strict';
var io = require('socket.io');
var callme;
function Websocket(server) {
var server = io(server);
server.on('connection', function(socket){
console.log('Do something here');
});
callme = function (val) {
//you my choose a specific cliente if you want, read the socket.io doc
server.emit('I may emit it ' + val);
console.log("Called " + val);
return 'Somebody got it';
}
}
Websocket.route = function(req, res, next) {
if(typeof callme == 'function'){
res.send(callme(req.param('t')));
}else{
res.send('Websocket server is not running');
}
};
module.exports = Websocket;
On the express app definition, I put
var Websocket = require('./websocket');
app.use('/blablabla', Websocket.route);
Then, on the server js file, which run the application, I put
var server = http.createServer(app);
var s = new Websocket(server);
This last line works like the tradicional io(server); would work.
After that, when you request the address /blablabla the route will execute your websocket method.
My solution is not in production yet, let me know if somebody got an error.

Correct way to restart a socket.io server

I'm trying to restart a socket.io server. I start the server and get a welcome message for new connections, but when I close and restart the server I get no further welcome message.
Hopefully I'm missing something simple :\
var http = require('http').Server
var socketIO = require('socket.io')
var socketIOClient = require('socket.io-client')
var port = 3000
var url = 'ws://localhost:' + port
function newServer(serverName, cb)
{
var server = http().listen(port, function()
{
console.log(serverName, 'listening')
var io = socketIO(server)
var clientSocket = socketIOClient(url,
{ reconnection: false })
clientSocket.on('connect', function()
{
// never get 'two connect'
console.log(serverName, 'connect')
io.close()
})
clientSocket.on('disconnect', function()
{
console.log(serverName, 'disconnect')
cb()
})
})
}
function startServerOne(cb)
{
newServer('one', cb)
}
function startServerTwo(cb)
{
newServer('two', cb)
}
startServerOne(startServerTwo)
The parameter I was looking for was "forceNew". It's undocumented in socket.io-client documentation.
This seems to force the socket.io-client to create a new manager instead of using the cached one (which I assume is connected to a server that's no longer running).
The option is described on the socket.io blog and can be seen in the code here with a discussion of the issue here
Full working example:
var http = require('http').Server
var socketIO = require('socket.io')
var socketIOClient = require('socket.io-client')
var port = 3000
var url = 'ws://localhost:' + port
function newServer(serverName, cb)
{
var server = http().listen(port, function()
{
console.log(serverName, 'listening')
var io = socketIO(server)
var clientSocket = socketIOClient(url,
{
reconnection: false,
//////////////////////////////
// this forces a new connection!
forceNew: true
//////////////////////////////
})
clientSocket.on('connect', function()
{
// never get 'two connect'
console.log(serverName, 'connect')
io.close()
})
clientSocket.on('disconnect', function()
{
console.log(serverName, 'disconnect')
cb()
})
})
}
function startServerOne(cb)
{
newServer('one', cb)
}
function startServerTwo()
{
newServer('two', function()
{
console.log('high five everyone')
})
}
startServerOne(startServerTwo)
When you restart the server you kill all connections. Clients should actively reconnect.
You should take a look towards auto-reconnect configuration of client sockets

Nodejs - Socketio not working with https server, what could be the reason?

I tried debugging using http server, and socket.io worked, however when I try to use https socket.io stopped working
// create server for http and https
//var httpserver = http.createServer(app).listen('3000', '127.0.0.1');
var https_server = https.createServer(options, app).listen('4000', '127.0.0.1');
// let the backend listens to this server
UserServer.listen(https_server);
//UserServer.listen(httpserver);
exports.listen = function(server){
io = socketio.listen(server);
io.sockets.on('connection', function(socket){
console.log("Socket is connected, sweet ");
});
}
When
var httpserver = http.createServer(app).listen('3000', '127.0.0.1');
UserServer.listen(httpserver);
Print out
Socket is connected, sweet "
When
var https_server = https.createServer(options, app).listen('4000', '127.0.0.1');
UserServer.listen(https_server);
There are no output
Here are my set up for https
var express = require('express'),
https = require('https'),
fs = require('fs');
var options = {
key: fs.readFileSync('./key.pem', 'utf8'),
cert: fs.readFileSync('./cert.pem', 'utf8')
};
I was able to display the https page, so I am guessing https setup was not the problem
Any advice would be appreciated, thanks
First of all, you need to run Node.js Server with SSL.
Server.js
var fs = require('fs');
var options = {
key: fs.readFileSync('ssl/private/domain.com.key'),
cert: fs.readFileSync('ssl/certs/domain.com.crt'),
ca: fs.readFileSync('ssl/certs/domain.com.cabundle')
};
// You can do this easily if you are on windows
// var options = { pfx: fs.readFileSync('/home/mydir/secure.pfx'); };
var app = require('https').createServer(options, handler),
io = require('socket.io').listen(app);
//Recommended Production settings
io.enable('browser client minification'); // send minified client
io.enable('browser client etag'); // apply etag caching logic based on version number
io.enable('browser client gzip'); // gzip the file
io.set('log level', 1); // reduce logging
io.set('flash policy port', 3300); //==> override Flash Policy Port
io.set('transports', [ // enable all transports (optional if you want flashsocket)
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
function handler(req, res) {
res.writeHead(200);
res.end("welcome sir!");
};
io.sockets.on('connection', function (socket) {
socket.on('message', function (data) {
socket.broadcast.emit('message', data);
});
});
app.listen(3300);
Client.js
//socketAddress is server uri ex. https://www.domain.com:3300
var socket = io.connect(socketAddress, {'flash policy port':3300} );
socket.on('connect', function (data) {
//....
});
socket.on('message', function (data) {
//....
});

Resources