Reputation: 653
I have used express
and ws to create an https server and a websockets server that run from the same Node process and the same port (443) on an Ubuntu 18.04 server.
My server.js can be boiled down to this:
const express = require('express');
const https = require('https');
const Websocket = require('ws');
const app = express();
app.use(/* ... Express routes */);
const credentials = /* SSL Certificate */;
const httpServer = https.createServer(credentials, app);
const wsServer = new WebSocket.Server({ server: httpServer });
wsServer.on('connection', (ws, req) => {
// Handle incoming websocket messages
});
httpServer.listen(443);
I need to be able to make http requests to this app on https://example.com and send messages to wss://example.com from browser clients over the public internet. This all works correctly.
I also need to be able to send messages FROM the http server, TO the websockets server. On the http server, the client code looks something like this:
const WebSocket = require('ws');
const ws = new WebSocket("wss://example.com");
ws.onopen = () => {
ws.send( JSON.stringify({ msg: "hello from the http server" }) );
}
Again, this works perfectly fine. However, it is counter intuitive to me that the http server needs to go out to the internet to communicate with the websockets server.
On my development machine, it works perfectly well to have the server on localhost:3000
and the websockets server on ws://localhost:3000
and they communicate with one another.
Is there a way I can have external clients send/receive websocket messages from wss://example.com
, whilst the local http server communicates "directly" with the websocket server which is running on the same port and process?
I am imagining that this would avoid the http server calling out to the public internet (and a DNS server) and incurring latency.
I have tried the following (in the code where the http server connects to the websockets server)
const ws = new WebSocket("wss://localhost");
const ws = new WebSocket("ws://localhost");
Referring to the server as localhost
or 127.0.0.1
as I would on my development machine gives an SSL error if I use wss://
...
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames
...and a "cannot connect" error if I use ws://
on port 80
code: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 80
I've had a look for answers to the question but I'm not finding anything. I'm aware I may be using the wrong terminology to search however!
Upvotes: 1
Views: 4263
Reputation: 163262
I have used express and ws to create an https server and a websockets server that run from the same Node process and the same port (443) on an Ubuntu 18.04 server.
Not really... it's just one HTTPS server, with your Web Sockets running on top of it. Web socket connections start out as an HTTP request, and then are "upgraded" to web sockets.
One underlying server, bound to a TCP port, which connections that are handled either by the web socket library or your handler for the HTTP requests, depending on the request method and protocol.
I also need to be able to send messages FROM the http server, TO the websockets server. On the http server, the client code looks something like this:
This doesn't make any sense. They're the same application, right?
Simply call whatever functions you need, from the other functions handling your web socket data rather than making additional HTTP requests.
However, it is counter intuitive to me that the http server needs to go out to the internet to communicate with the websockets server.
It doesn't sound like it's "going out to the internet". It's more likely that you're making a connection locally when this occurs. Still, not efficient when you can just call the code directly.
Upvotes: 2