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.
Related
I can set the port on the Web socket server as shown below.
const wss = new WebSocketServer({
port: rrPort,
});
(I tried set with 'host' and 'path' but it doesn't work.)
Now I have to set specific ip on the Web socket server.
I have two LAN so also IPs.
I wanna set with one of IPs but I can't.
I can get web socket server ip with connected PC as shown below.
const ip = ws._socket.remoteAddress.slice(7);
You need to set the ip when you create http server which you pass to WebSocketServer to use.
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(...);
// this is where you set the ip to listen to
server.listen(8080, '192.168.0.1', function() {
});
wsServer = new WebSocketServer({
httpServer: server,
port: 1234
});
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 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
http-client.js:
const http = require('http');
http.get
(
{
port : 9001,
host : 'localhost'
},
(res) =>
{
//...
}
);
tcp-server.js:
const net = require('net');
let server = new net.Server();
server.listen(9001, 'localhost', (err) =>
{
console.log('Started listening', server.address());
});
server.on('connection', (sock) =>
{
console.log(`Connected ${sock.remoteAddress}:${sock.remotePort}`);
});
I run node tc-server.js and then when I run node http-client.js I see output like:
Started listening { address: '127.0.0.1', family: 'IPv4', port: 9001 }
Connected 127.0.0.1:59506
I close http-client.js and run node http-client.js again. I see: Connected 127.0.0.1:59508
I close server and run again, and run the client again, I see Connected 127.0.0.1:59510
So the socket.remotePort is increasing all the time. What I don't understand is why those numbers for ports, I was expecting to see 9001 for port number since that's where the http request was being sent and successfully reached the listening tcp server.
Both sides of a TCP conversation have to have an address and a port. E.g., clients use ports too. What your console.log was telling you was that the client connected to your port 9001 using its port 59506. When your server sends packets to the client, it addresses them with the client's address and that port number, so the TCP layer of the network stack on the client knows what process to send the packet to. (More in the Wikipedia article on TCP.) You see the number increasing just as a byproduct of how your client system assigns available ports to connections.
You don't normally need to care about the client's port.
I used websocket interface to connect to websocket server . what if i want send data that i receive from the websocket server through my websocket interface to client connected to me through http server , should i use socket.io ?
so at the end i will have socket.io attached to to http server and websocket interface to get data and in case of message come will be send to client through socket.io . is that the best setup ?
Code Example :
// Require HTTP module (to start server) and Socket.IO
var http = require('http'),
io = require('socket.io');
var WebSocket = require('ws');
var ws = new WebSocket('ws://localhost:5000');
// Start the server at port 8080
var server = http.createServer(function (req, res) {
// Send HTML headers and message
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end('<h1>Hello Socket Lover!</h1>');
});
server.listen(8080);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
ws.on('open', function open() {
ws.send('something');
});
ws.on('message', function (data, flags) {
// here the data will be send to socket.io
});
// Add a connect listener
socket.on('connection', function (client) {
// Success! Now listen to messages to be received
client.on('message', function (event) {
console.log('Received message from client!', event);
});
client.on('disconnect', function () {
clearInterval(interval);
console.log('Server has disconnected');
});
});
Yes, your design is correct.
However, one thing that you should keep in mind is take care of sending the message to the correct client after authentication. In my opinion, it is very easy to make this mistake, partially because of the simplicity of messaging using websockets.