Can't make a websocket connection between react client and express server - javascript

I'm trying to make a connection between a react client and an express server with websockets. Every time I try this i get an error. I think I'm missing something.
Server code:
var http = require('http');
var ws = require('ws');
var theHttpServer = http.createServer();
var theWebSocketServer = new ws.Server({
server: theHttpServer,
verifyClient: true
});
theHttpServer.on('request', app);
theHttpServer.listen(9000,
function () {
console.log("The Server is lisening on port 9000.")
});
theWebSocketServer.on('connection', function connection(msg) {
console.log("CONNECTION CREATED");
websocket.on('message', function incoming(message) {
});
});
Client code:
let wsConnection = new WebSocket("ws://localhost:9000");
wsConnection.onopen = function(eventInfo) {
console.log("Socket connection is open!");
}
The error:
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
^
TypeError: this.options.verifyClient is not a function

You're passing verifyClient as a boolean, not a function. What you would maybe want to do is change this to:
function verifyClient(info) {
// ...Insert your validation code here
};
var theWebSocketServer = new ws.Server({
server: theHttpServer,
verifyClient: verifyClient
});

Related

How to read headers from a websocket connection

i try to send an information on the header of a webSocket, and read it on the server on connection.
things like:
Client code is as simple as:
ws = await WebSocket.connect('ws://localhost.com:36485', headers: {
'codeName': 'Something',
},);
the server code:
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({ port: 36485 });
wss.on('connection', function connection(ws) {
console.log(ws.upgradeReq.headers);
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
});
the exception that i have is :
Type Error: Cannot read property 'headers' of undefined
If you're using this ws module on NPM, then way you get access to the headers like this (taken directly from the documentation):
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function(ws, req) {
console.log(req.headers);
});
thanks for your help, for some reason its not working with 'ws' but its working fine with 'webSoket'.
var webSocketServer = require('websocket').server;
var http = require('http');
wsServer.on('request', function(request){
console.log(request.httpRequest.headers['codename']);
}

How to send broadcast to all connected client in node js

I'm a newbie working with an application with MEAN stack. It is an IoT based application and using nodejs as a backend.
I have a scenario in which I have to send a broadcast to each connected clients which can only open the Socket and can wait for any incoming data. unless like a web-browser they can not perform any event and till now I have already gone through the Socket.IO and Express.IO but couldn't find anything which can be helpful to achieve what I want send raw data to open socket connections'
Is there any other Node module to achieve this. ?
Here is the code using WebSocketServer,
const express = require('express');
const http = require('http');
const url = require('url');
const WebSocket = require('ws');
const app = express();
app.use(function (req, res) {
res.send({ msg: "hello" });
});
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
ws.on('message', function(message) {
wss.broadcast(message);
}
}
wss.broadcast = function broadcast(msg) {
console.log(msg);
wss.clients.forEach(function each(client) {
client.send(msg);
});
};
server.listen(8080, function listening() {
console.log('Listening on %d', server.address().port);
});
Now, my query is when this code will be executed,
wss.on('connection', function connection(ws) {
ws.on('message', function(message) {
wss.broadcast(message);
}
}
var WebSocketServer = require("ws").Server;
var wss = new WebSocketServer({port:8100});
wss.on('connection', function connection(ws) {
ws.on('message', function(message) {
wss.broadcast(message);
}
}
wss.broadcast = function broadcast(msg) {
console.log(msg);
wss.clients.forEach(function each(client) {
client.send(msg);
});
};
Try the following code to broadcast message from server to every client.
wss.clients.forEach(function(client) {
client.send(data.toString());
});
Demo server code,
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 2055 },()=>{
console.log('server started')
})
wss.on('connection', (ws) => {
ws.on('message', (data) => {
console.log('data received \n '+ data)
wss.clients.forEach(function(client) {
client.send(data.toString());
});
})
})
wss.on('listening',()=>{
console.log('listening on 2055')
})

How to use middleware that requires socket connection?

I am using express.io and am trying to craft a middleware that requires a connection to a remote server via two sockets. However, I am having a problem.
var net = require('net');
module.exports = function (host, port) {
return function (req, res, next) {
req._messages = net.connect(port, host);
req._commands = net.connect(port, host);
req._messages.on('data', function (data) {
req.io.broadcast('data', data.toString('ascii'));
});
req._messages.write('CF I\r'); // initialization command
next();
}
}
then in my main app:
var port = process.env.CYLON_PORT;
var host = process.env.CYLON_HOST;
var app = require('express.io').http().io();
app.use(require('./cylon/controller')(host, port));
module.exports = app;
However, I am coming across a problem. On each request, it attempts to reconnect. This causes an Error: connect ECONNREFUSED. Ideally, I would like this to connect once when the application starts and maintain that socket, but it needs to intercept each connect.
How can I use sockets in middleware?
You can try that way:
var net = require('net');
module.exports = function (host, port) {
var messagesConnection = net.connect(port, host);
var commandsConnection = net.connect(port, host);
return function (req, res, next) {
req._messages = messagesConnection;
req._commands = commandsConnection;
req._messages.on('data', function (data) {
req.io.broadcast('data', data.toString('ascii'));
});
req._messages.write('CF I\r'); // initialization command
next();
}
}
The call to require('./cylon/controller')(host, port) will start the connections and they will then be reused each time the middleware is called.
Edit: I'm wondering whether you really need to set all those new fields on you req object. You could have some files that export io, messagesConnection and commandsConnection for instance, and you could require them when needed.
Here you end up adding an even listener on messagesConnection each time the middleware is called, which is everything but good.
Edit2: What you could do instead, because you seem to be using express-io:
var net = require('net');
module.exports = function (io, host, port) {
var messagesConnection = net.connect(port, host);
var commandsConnection = net.connect(port, host);
messagesConnection.on('data', function (data) {
io.broadcast('data', data.toString('ascii'));
});
messagesConnection.write('CF I\r'); // initialization command
return function (req, res, next) {
req._messages = messagesConnection;
req._commands = commandsConnection;
next();
}
}
And in your main file:
var port = process.env.CYLON_PORT;
var host = process.env.CYLON_HOST;
var app = require('express.io').http().io();
app.use(require('./cylon/controller')(app.io, host, port));
module.exports = app;

ng-websocket and ws: client sends successfully but doesn't receive

My angularjs client websocketserver can properly send to the server, but when sending from server to client, the client doesn't register the event.
I'm using angular-websockets at the client side and ws at my express.js server
Here's my code.
server
var port = process.env.PORT || 3002;
var server = http.createServer(app); // app = express
server.listen(port);
var socketComs = require('./lib/socketcoms').connect(server);
var connect = function(server) {
var wss = new WebSocketServer({
server: server
});
wss.on('connection', function(ws) {
console.log("websocket connection open");
ws.on('message', function incoming(message) {
console.log('received', message); // THIS WORKS FINE
});
var id = setInterval(function() {
ws.send('pong', 'data 123', function(err) {
console.log('sent pong', err); // THIS IS NEVER CAUGHT BY CLIENT, err = clean
});
}, 2000); // Pong is never received
});
};
client
var connect = function() {
ws.$on('$open', function() {
console.log('wow its working');
ws.$emit('message', 'some message');
});
ws.$on('pong', function(data) {
console.log('yes', data);
});
ws.$on('$close', function(data) {
console.log('wss closed');
});
};
Can anyone see what's going wrong?
I'm using ng-websocket with PHP socket, and I have the same issue.
I just opened the ng-websocket.js and..guess what? the "ping" and "pong" events don't exist!
The "incoming" event is called "$message"...
This is how to get data from server:
ws.$on('$message', function (response) {
console.log("DATA FROM SERVER", response);

Building simple nodejs API with streaming JSON output

I am trying to build a simple node.js based streaming API. All I want to do is as I hit the server url, the output should stream a set of test data(JSON) like twitter streaming API.
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(8083);
app.get('/', function (req, res) {
res.write(io.on('connection', function (socket) {
socket.emit('item', { hello: 'world' });
}));
});
So, If i do curl http://localhost:8083/, I want output something like:
$ curl http://localhost:8083/
{hello: 'world'}
{hello: 'world'}
{hello: 'world'}
{hello: 'world'}
...
I am new to node.js and web sockets. I might be horribly wrong on the basics of how node works, let me know the best solution.
First, it's better to put the JSONStream part inside a middleware like so:
var _ = require('lodash');
// https://github.com/smurthas/Express-JSONStream/blob/master/index.js
function jsonStream(bytes) {
return function jsonStream(req, res, next) {
// for pushing out jsonstream data via a GET request
var first = true;
var noop = function () {};
res.jsonStream = function (object, f) {
f = _.isFunction(f) ? f : noop;
if (!(object && object instanceof Object)) {
return f();
}
try {
if (first) {
first = false;
res.writeHead(200, {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
}
res.write(JSON.stringify(object) + '\n');
} catch (err) {
return _.defer(f.bind(null, err));
}
f();
};
next();
};
}
Then, let's say you want to be notified via this API each time someone connects to socket.io
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
server.listen(8083);
var mediator = new EventEmitter();
io.on('connection', function (socket) {
mediator.emit('io:connection:new', socket);
});
// the second parameter, specify an array of middleware,
// here we use our previously defined jsonStream
app.get('/', [jsonStream()], function (req, res) {
function onNewConnection(socket) {
res.jsonStream({
type: 'newConnection',
message: 'got a new connection',
socket: {
id: socket.id
}
});
}
// bind `onNewConnection` on the mediator, we have to use an mediator gateway
// because socket.io does not offer a nice implementation of "removeListener" in 1.1.0
// this way each time someone will connect to socket.io
// the current route will add an entry in the stream
mediator.on('io:connection:new', onNewConnection);
// unbind `onNewConnection` from the mediator
// when the user disconnects
req.on('close', function () {
mediator.removeListener('connection', onNewConnection);
});
res.jsonStream({
type: 'welcome',
message: 'waiting for connection'
});
});
Finally, if you want to test this code without connecting to socket.io use the following simulator:
// Simulate socket.io connections using mediator
(function simulate() {
var dummySocket = {
id: ~~(Math.random() * 1000)
};
mediator.emit('io:connection:new', dummySocket);
setTimeout(simulate, Math.random() * 1000);
})();

Categories