Thursday, May 23, 2024
 Popular · Latest · Hot · Upcoming
19
rated 0 times [  23] [ 4]  / answers: 1 / hits: 33126  / 7 Years ago, fri, july 7, 2017, 12:00:00

I took a game that my friend made and wanted to make it playable across browsers by sending keypress data between peers with WebRTC and websockets. However, I get this error in the console:




WebSocket connection to 'ws://localhost:3000/' failed: Connection closed before receiving a handshake response




My server file has the following few lines:



'use strict';

const express = require('express');
const SocketServer = require('ws').Server;
const path = require('path');

const PORT = process.env.PORT || 3000;
const INDEX = path.join(__dirname, 'index.html');

const server = express();

server.use(express.static(path.join(__dirname, 'lib')));
server.use('/assets', express.static(path.join(__dirname, 'assets')));
server.listen(PORT, () => console.log(`Listening on ${ PORT }`));

const wss = new SocketServer({ server });
var users = {};
let usernames = [];


wss.on('connection', function(connection) {

connection.on('message', function(message) {

var data;
try {
data = JSON.parse(message);
} catch (e) {
console.log(Invalid JSON);
data = {};
}

switch (data.type) {
case login:
console.log(User logged, data.name);
if(users[data.name]) {
sendTo(connection, {
type: login,
success: false
});
} else {
users[data.name] = connection;
connection.name = data.name;
usernames.push(data.name);

sendTo(connection, {
type: login,
success: true,
users: usernames
});
}

break;

case offer:
console.log(Sending offer to: , data.name);
var conn = users[data.name];

if(conn != null) {
connection.otherName = data.name;

sendTo(conn, {
type: offer,
offer: data.offer,
name: connection.name
});
}

break;

case answer:
console.log(Sending answer to: , data.name);
var conn = users[data.name];

if(conn != null) {
connection.otherName = data.name;
sendTo(conn, {
type: answer,
answer: data.answer
});
}

break;

case candidate:
console.log(Sending candidate to:,data.name);
var conn = users[data.name];

if(conn != null) {
sendTo(conn, {
type: candidate,
candidate: data.candidate
});
}

break;

case leave:
console.log(Disconnecting from, data.name);
var conn = users[data.name];
conn.otherName = null;

if(conn != null) {
sendTo(conn, {
type: leave
});
}

break;

default:
sendTo(connection, {
type: error,
message: Command not found: + data.type
});

break;
}
});


And the client side of the connection looks as follows:



const Game = require(./game);
const GameView = require(./game_view);
var HOST = location.origin.replace(/^http/, 'ws');
console.log('host: ', HOST);
console.log(process.env.PORT);

document.addEventListener(DOMContentLoaded, function() {
const connection = new WebSocket(HOST);

.....


This is the point that the error occurs and this is the caught error that I get:



bubbles
:
false
cancelBubble
:
false
cancelable
:
false
composed
:
false
currentTarget
:
WebSocket
defaultPrevented
:
false
eventPhase
:
0
isTrusted
:
true
path
:
Array(0)
returnValue
:
true
srcElement
:
WebSocket
target
:
WebSocket
timeStamp
:
213.01500000000001
type
:
error
__proto__
:
Event


I am not too familiar with server side programming and was trying to understand. I tried looking up this issue, but it seems like a variety of different things can cause this. If you want to see the repository you can see and try it yourself (uses webpack): SlidingWarfare Repo


More From » node.js

 Answers
11

The confusion starts here:



const server = express();


The express function doesn't really return a server, it returns an application. Commonly, the variable used for this is app, but that's of course nothing more than convention (i.e. not a requirement).



However, it becomes an issue when you pass the app to the WS server:



const wss = new SocketServer({ server });


That's because SocketServer requires an HTTP server instance, which server is not.



Here's a fix, without renaming your variables:



let httpServer = server.listen(PORT, () => console.log(`Listening on ${ PORT }`));
...
const wss = new SocketServer({ server : httpServer });


(because when you call .listen() on the Express instance, it will return an HTTP server instance)



Using the variable naming convention it would be this:



const app = express();

app.use(express.static(path.join(__dirname, 'lib')));
app.use('/assets', express.static(path.join(__dirname, 'assets')));

let server = app.listen(PORT, () => console.log(`Listening on ${ PORT }`));

const wss = new SocketServer({ server });

[#57173] Thursday, July 6, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
mckinley

Total Points: 15
Total Questions: 101
Total Answers: 94

Location: Liechtenstein
Member since Fri, Sep 11, 2020
4 Years ago
mckinley questions
Sun, Oct 17, 21, 00:00, 3 Years ago
Tue, Jun 15, 21, 00:00, 3 Years ago
Thu, Apr 8, 21, 00:00, 3 Years ago
;