My server has embedded node-red. I'm trying to create new websocket listener in server. But when execute this code, websockets in node-red application stops working.
const WebSocket = require('ws');
const wss = new WebSocket.Server({
server: server,
path: '/test'
});
wss.on('connection', function connection(ws, req) {
console.log('test');
});
Websocket in node-red admin panel:
Problem is related to:
https://github.com/websockets/ws/issues/381
How access to node-red websocket and handle messages for own path?
I know this is an old thread but I thought I'd throw in that you can use the OP code in node red like this:
var WebSocket = global.get('ws');
const wss = new WebSocket.Server({
server: <your http(s) server>,
path: '/'
});
wss.on('connection', function connection(ws, req) {
node.warn('connection');
});
You just need to:
npm install ws
edit settings.js
under functionGlobalContext: add
ws:require('ws')
It does work, I'm using it like this because I couldn't get the websocket node to work in my configuration.
Related
Is there a way in which I can create and connect to a websocket server that has accepts wss rather than just ws in the path?
I am currently using the ws npm library to do something like:
const wss = new WebSocket.Server({port: 8080});
wss.on('connection', () => {
console.log('connected!');
});
Then connecting in terminal:
wscat -c ws://localhost:8080
I would connect successfully and get the correct log message.
However I am wanting/needing to connect to a wss websocket, but cannot get this to work with the ws npm library.
wscat -c wss://localhost:8080
This returns the error: error: socket hang up
Is there some way around this at all?
You need to open a HTTPS server, in order to connect to it.
This is also explained in the documentation of ws.
const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');
const server = https.createServer({
cert: fs.readFileSync('/path/to/cert.pem'),
key: fs.readFileSync('/path/to/key.pem')
});
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
ws.send('something');
});
server.listen(8080);
WS with HTTPS
You can create certificates with Let's Encrypt
I want to create webserver socket connection at random port. And I want to return server port to calling application or just print it in terminal.
The typical code to create a server connection is as below.
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 0 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
ws.send('something');
});
So I am trying to create server at port 0. I assume it will create server at random port. How do I get that random port?
I want to know the port number, as soon as server socket is created.
Now I am able to create the websocket server at random port and able to get the port number as well. Not sure if it is the right way, but it works.
const http = require('http');
const WebSocket = require('ws');
const url = require('url');
const server = http.createServer();
const wss = new WebSocket.Server({ noServer: true });
wss.on('connection', function connection(ws) {
console.log(wss);
});
server.on('upgrade', function upgrade(request, socket, head) {
const pathname = url.parse(request.url).pathname;
wss.handleUpgrade(request, socket, head, function done(ws) {
wss.emit('connection', ws, request);
});
});
server.listen(0, '127.0.0.1', function incoming() {console.log (server.address().port);});
Websocket works with http/s on port 80 or 443. The server may listen on any port it chooses, but if it chooses any port other than 80 or 443, it may have problems with firewalls and/or proxies. Browsers generally require a secure connection for WebSockets, although they may offer an exception for local devices.
I am new to websockets and just trying to get a handle of how to listen to a message from a client browser from the server and vice-versa.
I'm using a Node.js/Express setup and just want to be able to firstly listen for any messages from the client.
I've been looking at this https://github.com/websockets/ws library and have tried the examples but am not able to get this working within my localhost environment.
I'm also not clear what I need to look out for, when I'm listening for a message.
What code do I use on the client, i.e. url + port and what code do I use on the server?
const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost/path', {
perMessageDeflate: false
});
Using websockets directly might be troublesome, it's advised you use a framework to abstract this layer, so they can easily fallback to other methods when not supported in the client. For example, this is a direct implementation using Express js and Websockets directly. This example also allows you to use the same server for HTTP calls.
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const app = express();
//initialize a simple http server
const server = http.createServer(app);
//initialize the WebSocket server instance
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws) => {
//connection is up, let's add a simple simple event
ws.on('message', (message) => {
//log the received message and send it back to the client
console.log('received: %s', message);
ws.send(`Hello, you sent -> ${message}`);
});
//send immediatly a feedback to the incoming connection
ws.send('Hi there, I am a WebSocket server');
});
//start our server
server.listen(3000, () => {
console.log(`Server started on port ${server.address().port} :)`);
});
For the client, you can do something like this:
const ws = new WebSocket('ws://localhost:3000')
ws.onopen = () => {
console.log('ws opened on browser')
ws.send('hello world')
}
ws.onmessage = (message) => {
console.log(`message received`, message.data)
}
Like i have mentioned above, it is advised that you use a mature framework for websockets. Should your app be minimal and not need scaling, you can use any open source library, with socket.io being the most popular.
However, if you are talking about implementing this to be used at production level, you should know that the open source solutions do not allow for scalability, failover, message ordering etc. In that case, you’ll have to implement a realtime platform as a service tool.
Just a note, socket.io is a backend/frontend library that uses websocket but also has a number of fallbacks if the client browser does not support websocket. The example below works with ws backend.
Server
const WS = require('ws')
const PORT = process.env.PORT || 8080
const wss = new WS.Server({
port: PORT
}, () => console.log(`ws server live on ${PORT}`))
const errHandle = (err) => {
if(err) throw err
}
wss.on('connection', (socket) => {
console.log('something connected')
socket.send('you are connected', errHandle)
socket.on('message', (data) => {
console.log(`socket sent ${data}`)
socket.send('message received', errHandle)
})
})
client (browser)
(() => {
const ws = new WebSocket('ws://localhost:8080')
ws.onopen = () => {
console.log('ws opened on browser')
ws.send('hello world')
}
ws.onmessage = (message) => {
console.log(`message received ${message}`)
}
})()
edit: oh, and ws and http are different protocols. you will need a different server to serve your http files
I have built a NodeJS application and I am using Websocket to send events to Browser. Now I need to bundle the Node Application into EXE and send to client.
I tried nexe and JXCore but nexe is bundling the application but giving issue when i am trying to run it.
The JS code for Websocket is
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(1337, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
wsServer.on('request', function(request) {
var connection = request.accept(null, request.origin);
eze.ee.on("EPIC_VALIDATING_DEVICE" , function() {connection.sendUTF('VAlidate')});
The Exception stack is as follows
nexe.js:15318
wsServer = new WebSocketServer({
^
TypeError: WebSocketServer is not a function
at Array.__dirname.call.C:\Users\Raghav Tandon\WinPos\BrowserIntegrat
ion\js\RestImpl.js.http (nexe.js:15318:12)
at initModule (nexe.js:29:11)
at nexe.js:31:64
at Array.__dirname.call.C:\Users\Raghav Tandon\WinPos\BrowserIntegrat
ion\js\RestWS.js../RestImpl (nexe.js:48:20)
at initModule (nexe.js:29:11)
at Array.forEach (native)
at nexe.js:39:8
at nexe.js:46:4
at NativeModule.compile (node.js:945:5)
at Function.NativeModule.require (node.js:893:18)
Why this is not loading Webscocket module? I have tested the application as node start and it is working properly.
This is happening because of Nexe is not able to support native modules. Rather I tried Electron which works like a charm and has support for Native modules as well.
How to do socket.io implementation in Webrtc Video calling?
A little bit overload but it works: SocialVidRTC
I understand from your question that you already have a WebRTC project and some signalling mechanism in server.js , possibly websockets .
To replace this with socket.io or any other signalling as SIP / XHR / AJAX etc , you need to replace server.js with new socket.io based code for request and response .
Follow these steps :
create a https server ( since webrtc pages capture web cam input only from secure origins) for socket.io. Assign server to an variable say app.
var fs = require('fs');
var https = require('https');
var options = {
key: fs.readFileSync('ssl_certs/server.key'),
cert: fs.readFileSync('ssl_certs/server.crt'),
ca: fs.readFileSync('ssl_certs/ca.crt'),
requestCert: true,
rejectUnauthorized: false
};
var app = https.createServer(options, function(request, response){
request.addListener('end', function () {
file.serve(request, response);
}).resume();
});
app.listen(8081);
here server.key , server.crt and ca.crt are fake ssl certs and 8081 is the https port I have selected .
you can reuse the same https server for hosting the webpages also.
listen on this same port for socket.io using app defined earlier
var io = require('socket.io').listen(app, {
log: false,
origins: '*:*'
});
io.set('transports', [
'websocket'
]);
I choose only websocket but you can set other types of transport too such as
socket.set('transports', [
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
Now implement signalling specific functions and calls such as ,
io.sockets.on('connection', function (socket) {
...
socket.on('webrtc-joinchannel',function(data){
var resp=joinChannel(data);
socket.emit('resp-webrtc-joinchannel', resp);
});
...
});
Note : I am using socket.io v0.9 .
If yo want a example implementation you can view any sample projects such as here