WebSocket connection to 'ws://localhost:8000/' failed - node.js

I'm making a node JS server with WebSocket server on it.
Here is how I make the WS server:
const server = new WebSocket.Server({ server: app })
server.on('connection', (ws, request) => {
// some code
}
app.listen(8000, () => console.log('server is running'))
But on client side, there is an error:
WebSocket connection to 'ws://localhost:8000/' failed
It is important for me to make a WS server from node JS app, because this way I can see clients' cookies.

Related

Socketio not connecting on postman socket connection ui on localhost

Could not connect to localhost:3000
17:02:53
Error: Unexpected server response: 404
Handshake Details
Request URL: http://localhost:3000/socket.io/?EIO=3&transport=websocket
Request Method: GET
Status Code: 404 Not Found
My express server listen on 3000 port and socketio http on 443 port, i am able to connect socket by hosting this on ec2 instance and using ec2 ip with port number on postman socket connection ui, but on localhost connection always failed with above error on postman socket beta ui.
You need to call listen only once. If you pass your http/https server to express, app.listen() is enough. (except you want to listen on 2 different ports.. For testing, let's call it only once.)
For accessing it on localhost try setting it explicitly with the parameter hostname in app.listen().
Example:
async function startServer() {
const app = express();
const credentials = {key: key, cert: crt};
const httpsServer = createServer(credentials,app);
const io = socketIO(httpsServer);
await require('./loaders').default({ expressApp: app, socketIO: io });
// Let's only call listen once for testing purposes. If you call
// listen on the express app, your https server will automatically listen
// to the same configuration.
// httpsServer.listen(4000);
const port = 3000
const hostname = 'localhost'
// explicitly let the app listen on localhost. If hostname is not
// provided, it will take the first found ipv4 interface
app.listen(port, hostname, err => {
if (err) {
Logger.error(err);
process.exit(1);
return;
}
Logger.info(`
################################################
🛡️ Server listening on https://${hostname}:${port} 🛡️
################################################
`);
});
}
Now you should be able to connect your socket. If it still does not work try
to use http module instead of https for better isolating your problem.
Note that your server now only will be accessible using localhost and not over ip. Both may only be possible when running 2 server instances with different hostnames.
async function startServer() {
const app = express();
const credentials = {key: key, cert: crt};
const httpsServer = createServer(credentials,app);
const io = socketIO(httpsServer);
await require('./loaders').default({ expressApp: app, socketIO: io });
httpsServer.listen(443);
app.listen(config.port, err => {
if (err) {
Logger.error(err);
process.exit(1);
return;
}
Logger.info(`
################################################
🛡️ Server listening on port: ${config.port} 🛡️
################################################
`);
});
}
This is my app.ts file, I am using Ubuntu. so 443 port is not allowed, i changed this port to 4000, now the app listen on the 3000 and socket http server on 4000, but socketio not able to connect with socket url localhost:3000

How to use nodejs ws module on secure site

I'm using the following code to connect to WebSockets on a node js app for HTTP, but to doesn't work in HTTPS. What do I need to change? Is there a secure version of the node js ws module?
const WebSocket = require('ws');
webSocketServer.on('connection', (webSocket) => {
webSocket.on('message', (message) => {
...
});
});
Pays to read the nodejs ws module documentation sometimes:
let webSocketServer;
if (!local) {
const server = https.createServer({
cert: fs.readFileSync("/... server.crt"),
key: fs.readFileSync("/... server.key")
});
webSocketServer= new WebSocket.Server({ server });
server.listen(8080);
}
else webSocketServer = new WebSocket.Server({ port:8080 });
On the client-side, you need to call it with wss:// instead of ws://

Cant connect to WebSocket Node.JS

i'm making a game that use WebSockets and this is the code that i use to start a WebSocket server:
const server = require("http").Server(app);
const port = 3005;
server.listen(port, () => {
console.log('Server started on port: ' + port);
});
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ server })
wss.on('connection', function connection(ws) {});
And this code i use for connecting a user to the WebSocket:
this.SERVER_URL ='ws://localhost/?fvukovic'; <-- fvukovic is the user
this.ws = new WebSocket(this.SERVER_URL, ["test"]);
this.ws.onopen = () => {
console.log('open');
};
This works perfectly, but when i push that on server and i change the ip address to 195.201.119.221 which is the ip of the server, port is still 3005, i cant connect to it anymore..
I get this error:
WebSocket connection to 'ws://195.201.119.221:3005/?fvukovic' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT
Do i need something more when i put the the app on a real server?

Socket.io client : Websocket Connection failed : Connection closed before receiving a handshake response

I'm building an web app(nodejs, port: xxx0) which interacts with an another app(nodejs, port:xxx5) which is serving as the socket.io server. My socket.io client code goes well in my web app. All works well in my local as the connections refers to the server as io.connect('http://localhost:xxx5/')
But the same is not working when i promote it to higher env as the connection string is as io.connect('https://domainName/')
When my app is trying to connect, I'm receiving the below error:
websocket.js:112 WebSocket connection to 'wss://domainName/socket.io/?EIO=3&transport=websocket' failed: Connection closed before receiving a handshake response
Am I missing anything?
When I try hitting the server(higher env) via socket.io tester, I get the response as No sockets Found and immediately then An error occurred while reconnecting
NOTE:. The server instances are registered in an api gateway in higher env.
Server.js
const app = require('express')()
const port = process.env.PORT || xxx5
const server = app.listen(port)
const io = require('socket.io').listen(server)
let ns = io.of('/namespace')
ns.on('connection', (socket) => {
logger.info('User connected')
socket.emit('messages', {new:2,[{title:'Hi'},{title:'Test'}]})
})
Client.js
import io from 'socket.io-client'
const socket = io(`https://domainName/namespace`, { transports:
['websocket'], rejectUnauthorized: true})
// const socket = io('http://localhost:xxx5/namespace', { transports:
['websocket'], rejectUnauthorized: true})
// above commented url is in local
socket.on('connect', () => {
logger.info("Connected")
})
socket.on('messages', (data) => {
logger.info(`New messages : ${data.new}`)
})
socket.on('error', (error) => {
logger.error(`Error encountered : ${error}`)
})
Is your application running as a priveleged user? Any TCP/UDP socket less than 1024 is considered and IANA reserved port and required elevated priveleges to bind as a listening service.
Using cURL can also aid in providing the necessary handshake: (See reference of websocket handshake process here; https://en.m.wikipedia.org/wiki/WebSocket#Protocol_handshake)
sh
$ curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: echo.websocket.org" -H "Origin: http://domainname " http://domainname

TCP socket client through proxy on nodejs

I need to make tcp socket connection to smtp server. Is it possible to connect through proxy server on nodejs? Is there any npm modules available to use? I couldn't find any at all.
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write('I am here!');
});
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
console.log('DATA: ' + data);
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
net.socket, tls.connect and dgram have no proxy support.
The simplest way to use it with proxy is to replace some libc functions with proxychains or something similar.
var client = require('tls')
.connect(443, 'www.facebook.com', function() {
console.log('connected');
client.write('hello');
})
.on('data', function(data) {
console.log('received', data.toString());
})
.on('close', function() {
console.log('closed');
});
proxychains node fit.js
connected
received HTTP/1.1 400 Bad Request
...
closed
Other than 'net' you don't need another module to make a socket connect to a host through a proxy server as long at the proxy server supports HTTPS traffic.
Create a socket connection to the proxy server
Send an HTTP CONNECT message to inform the proxy server of the host and port you want to connect to
If the proxy server responds with an HTTP 200 response then the proxy server established a socket connection to your desired target and is now relaying the traffic between the sockets
If the proxy server responded with any HTTP response other than 200 then the connection was not established.
Even though this process starts with HTTP it doesn't mean it wouldn't work for SMTP traffic. The initial HTTP message is just used to negotiate the connection, after that its just raw traffic. A proxy server might look at the port or host you want to connect to and disallow it. For example, block connections to ports below 80 or below 443 such as port 25 so it really depends on the proxy server if the connection will be allowed.
Yes, it is possible with one of these NPM modules:
http-proxy-agent: An HTTP(s) proxy http.Agent implementation for HTTP endpoints
https-proxy-agent: An HTTP(s) proxy http.Agent implementation for HTTPS endpoints
pac-proxy-agent: A PAC file proxy http.Agent implementation for HTTP and HTTPS
socks-proxy-agent: A SOCKS (v4a) proxy http.Agent implementation for HTTP and HTTPS
HTTPS Proxy Example:
var url = require('url');
var WebSocket = require('ws');
var HttpsProxyAgent = require('https-proxy-agent');
// HTTP/HTTPS proxy to connect to
var proxy = process.env.http_proxy || 'http://168.63.76.32:3128';
console.log('using proxy server %j', proxy);
// WebSocket endpoint for the proxy to connect to
var endpoint = process.argv[2] || 'ws://echo.websocket.org';
var parsed = url.parse(endpoint);
console.log('attempting to connect to WebSocket %j', endpoint);
// create an instance of the `HttpsProxyAgent` class with the proxy server information
var opts = url.parse(proxy);
var agent = new HttpsProxyAgent(opts);
// finally, initiate the WebSocket connection
var socket = new WebSocket(endpoint, { agent: agent });
socket.on('open', function () {
console.log('"open" event!');
socket.send('hello world');
});
socket.on('message', function (data, flags) {
console.log('"message" event! %j %j', data, flags);
socket.close();
});
I hope this helps.

Resources