Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
100
rated 0 times [  101] [ 1]  / answers: 1 / hits: 8782  / 4 Years ago, fri, april 24, 2020, 12:00:00

trying to deploy my app with ws on Heroku. On my local machine everything worked out well but after deploying on Heroku I get a handshake error with response status 200



Here's my server code:



const WebSocketServer = require('ws').Server;
const moment = require('moment');
const app = require('./app');

const wss = new WebSocketServer({ app });

const connections = new Set();

wss.on('connection', (ws) => {
connections.add(ws);

ws.on('message', (message) => {
const time = moment(new Date()).format('HH:mm');
const messageData = {
time,
message,
};
for (const connection of connections) {
connection.send(JSON.stringify(messageData));
}
});

ws.on('close', () => {
connections.delete(ws);
});
});


And my client code:



const HOST = location.origin.replace(/^http/, 'ws');
const ws = new WebSocket(HOST);

ws.onmessage = (e) => {
//
};

messageForm.addEventListener('submit', (e) => {
//
ws.send(message);
//
});

More From » node.js

 Answers
1

The ws Server constructor does not accept an app option, so your wss isn't actually listening to anything. If this exact code did work locally, it's hard to see how.



Since you're attempting to connect to a WebSocket that shares the same path as your page, the express app ends up handling the WebSocket client request and responds with your page HTML.



Your HTTP exchange ends up looking something like this — first the browser loads the page:



GET /page HTTP/1.1
Accept: text/html


HTTP/1.1 200 OK
Content-Type: text/html

<html> …


Then the page makes a new WebSocket(…), resulting in a WebSocket upgrade request:



GET /page HTTP/1.1
Connection: Upgrade
Upgrade: websocket


HTTP/1.1 200 OK
Content-Type: text/html

<html> …


You should see why this would fail: that's not a WebSocket response. Express thinks the request is a regular HTTP GET request and responds with your page's HTML. The browser's WebSocket implementation sees a response that does not conform to the WebSocket spec and rightly throws an error. It reports status 200 because the server did respond with a HTTP 200 status code — even though it was an accident.



The correct way to attach a ws Server to a HTTP server is to either:




  1. Pass in the http.Server (not the express app) to ws.Server's server option



    var app = express(),
    server = http.createServer(app),
    wss = new ws.Server({ server });

    server.listen(process.env.PORT);

  2. Or manually attach an upgrade listener to your http.Server and call wss.handleUpgrade.



[#4034] Thursday, April 23, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
tyemathewj

Total Points: 484
Total Questions: 107
Total Answers: 111

Location: Equatorial Guinea
Member since Sun, Feb 14, 2021
3 Years ago
;