How to read headers from a websocket connection - javascript

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']);
}

Related

Getting error 503 on connection to secure web socket

When I'm making the connection using WSS protocol, I'm getting 503 on my back-end deployed on Heroku.
I'm using Netlify so they make me use only WSS protocol.
This is the error I'm getting:
WebSocketTester.3f92180b.js:1
WebSocket connection to 'wss://my-app-site/' failed: Error during WebSocket handshake: Unexpected response code: 503
this is my server side, i provided the cert and key:
const options = {
cert: readFileSync('./etc/ssl/certs/server.crt'),
key: readFileSync('./etc/ssl/private/key.pem')
};
const server = https.createServer(options, app);
const WebSocket = require('ws');
const wss = new WebSocket.Server({ server });
this is my client side:
if (!wsRef.current) {
wsRef.current = new WebSocket(`wss://my-site-url`);
wsRef.current.onopen = () => {
console.log('connection opened!');
}
wsRef.current.onmessage = ({ data }) => console.log(data);
wsRef.current.onclose = () => {
wsRef.current = null;
}
}
I would appreciate your help.

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

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
});

Can't connect to local Node.js secure WebSocketServer

For testing a JavaScript / html5 application, I created a local WebSocketServer with node.js and ws package. I want to use secure websockets (wss) with SSL/TLS.
Key and certificate were create for testing purposes by OpenSSL locally (self signed certificate).
The client just tries to use the native WebSocket object to connect to the (local) https Server:
var ws = new Websocket('wss://localhost:8080');
The Problem is, no browser (Firefox, Chrome, Edge) can connect to the server and they all give me different error messages.
Firefox:
Firefox can not connect to the server at wss: // localhost: 8080 /.
Chrome:
ws_client.js:7 WebSocket connection to 'wss://localhost:8080/' failed:
Error in connection establishment: net::ERR_CERT_AUTHORITY_INVALID
Edge:
SCRIPT12017: SCRIPT12017: WebSocket Error: SECURITY_ERR, Cross zone
connection not allowed
I created the certificate and key in OpenSSL (light, newest version) like this:
openssl req -new -x509 -nodes -out server.crt -keyout server.key
(source)
I checked almost every question about this (and similar) topics, e.g. this question, but none of them could provide a solution.
Please do not mark this question as a duplicate, because all similar questions contain slightly different problems!
Server Code:
var fs = require('file-system');
var pkey = fs.readFileSync('server.key', 'utf8');
var crt = fs.readFileSync('server.crt', 'utf8');
var credentials = { key: pkey, cert: crt };
var https = require('https');
var httpsServer = https.createServer(credentials);
httpsServer.listen(8080);
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({
server: httpsServer
});
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
ws.send('reply from server : ' + message)
});
});
I tried another code as server, but same errors occur:
const WebSocketServer = require('ws').Server;
var fs = require('file-system');
var ws_cfg = {
ssl: true,
port: 8080,
ssl_key: 'server.key',
ssl_cert: 'server.crt'
};
var processRequest = function(req, res) {
console.log('Request received');
};
var httpServ = require('https');
var app = httpServ.createServer({
key: fs.readFileSync(ws_cfg.ssl_key, 'utf8', (error) => {
console.log('Error reading file');
}),
cert: fs.readFileSync(ws_cfg.ssl_cert, 'utf8', (error) => {
console.log('Error reading file');
})
}, processRequest).listen(ws_cfg.port, function(){
console.log('Server running');
});
var wss = new WebSocketServer( {server: app, port: 8080, host: 'localhost', domain: 'localhost'} );
wss.on('connection', function (ws) {
console.log('Connected to a client');
ws.on('message', function (message) {
console.log('MSG received: ' + message);
});
});
There's one more thing. Always, if I add a console.log(wss); to the server Code, the output looks something like this:
WebSocketServer {
domain: null,
...some more stuff...
...cert key etc....
host: null,
path: null,
port: null } }
host, domain and port is set to null. I tried everything to set it to localhost:8080, but nothing worked out. I think this could be the source of all Problems, but can't find a way. If anyone knows an answer to this question, I would highly appreciate it.
(Using the insecure 'ws' protocol ('ws://localhost:8080') in order to connect to local node.js http server works, but I want to test the app as realistic as possible and use a secure Connection.)
-- This is not an answer, just my workaround --
For anyone having the same problems, here is what I did:
Server Code should be:
const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');
const server = new https.createServer({
cert: fs.readFileSync('localcert.cert'), //what ever you're files are called
key: fs.readFileSync('localkey.key')
});
const wss = new WebSocket.Server({ server }); // !
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('MSG received: %s', message);
});
ws.send('Hi to client');
});
server.listen(8080);
Only working in Google Chrome for now, can still not connect in Firefox.
enter chrome://flags/#allow-insecure-localhost in Google Chrome and enable.
Try to add the self-signed certificate or the generated CA to be trusted on the system that you are using.

Avoid creating onMessage function per WS client

Following ws's instructions to create a WebSocket server:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
ws.send('something');
});
An onMessage callback named incoming is created for every client, am I right?
Imagine having two million clients. This code would create two million functions. Is there a way to avoid this? Something like this would be wonderful:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('message', function incoming(ws, message) {
// Access to ws object
console.log('received: %s', message);
});
How about:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
function handleMessage(message) {
console.log('received: %s', message);
}
wss.on('message', handleMessage);

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')
})

Categories