Edit: Overhauling the question and example, to try and narrow in on this. In local development I had avoided this issue by having ws
and http
each handled by their own server on their own port, and I'm running into some issues trying to get set on OpenShift, where I'm limited to a single port.
I'm trying to set up a simple Websocket based chat system using Node on OpenShift, and I'm clearly doing something wrong - I've set up a simple server which delivers my index page as expected, but when that page requests a Websocket connection, the server tries to answer it as a regular HTTP request instead of upgrading the connection as expected.
Live Version
Server:
var ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var ws = require( 'ws' ).Server;
var http = require( 'http' );
var path = require( 'path' );
var fs = require( 'fs' );
// Create main HTTP server for the application
var httpServer = http.createServer( function( request, response ){
console.log( 'REQUEST: ' + request.url );
var filename = path.join( process.cwd(), request.url );
fs.exists( filename, function( exists ){
fs.readFile( filename, 'binary', function( err, file ){
if ( err ){
console.log( 'FILE ERROR: ' + request.url );
response.writeHead( 500, {"Content-Type": "text/plain"} );
response.write( "500 - File Error\n" + err + "\n" );
response.end();
return;
}
response.writeHead( 200 );
response.write( file, 'binary' );
response.end();
} );
} );
} ).listen( port, ip, function(){
console.log( 'Server is listening at http://' + ip + ':' + port );
} );
// Create WebSocket server and begin listening
wsServer = new ws( { server: httpServer } );
wsServer.on( 'connection', function( connection ){
console.log( 'New websocket connection...' );
connection.on( 'message', function( message ){
connection.set( 'Received: ' + message );
} );
connection.send( 'wele!' );
});
Edit: Overhauling the question and example, to try and narrow in on this. In local development I had avoided this issue by having ws
and http
each handled by their own server on their own port, and I'm running into some issues trying to get set on OpenShift, where I'm limited to a single port.
I'm trying to set up a simple Websocket based chat system using Node on OpenShift, and I'm clearly doing something wrong - I've set up a simple server which delivers my index page as expected, but when that page requests a Websocket connection, the server tries to answer it as a regular HTTP request instead of upgrading the connection as expected.
Live Version
Server:
var ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1';
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var ws = require( 'ws' ).Server;
var http = require( 'http' );
var path = require( 'path' );
var fs = require( 'fs' );
// Create main HTTP server for the application
var httpServer = http.createServer( function( request, response ){
console.log( 'REQUEST: ' + request.url );
var filename = path.join( process.cwd(), request.url );
fs.exists( filename, function( exists ){
fs.readFile( filename, 'binary', function( err, file ){
if ( err ){
console.log( 'FILE ERROR: ' + request.url );
response.writeHead( 500, {"Content-Type": "text/plain"} );
response.write( "500 - File Error\n" + err + "\n" );
response.end();
return;
}
response.writeHead( 200 );
response.write( file, 'binary' );
response.end();
} );
} );
} ).listen( port, ip, function(){
console.log( 'Server is listening at http://' + ip + ':' + port );
} );
// Create WebSocket server and begin listening
wsServer = new ws( { server: httpServer } );
wsServer.on( 'connection', function( connection ){
console.log( 'New websocket connection...' );
connection.on( 'message', function( message ){
connection.set( 'Received: ' + message );
} );
connection.send( 'wele!' );
});
Client / Index Page:
<!DOCTYPE html>
<html>
<head>
<script>
window.addEventListener( "load", function( event ){
var socket = new WebSocket( 'ws://exalted-instanttabletop.rhcloud.');
} );
</script>
</head>
<body>
<div id="log">Connecting...</div>
</body>
</html>
Share
Improve this question
edited Feb 10, 2015 at 6:29
Dashiel N
asked Feb 8, 2015 at 1:47
Dashiel NDashiel N
3192 silver badges13 bronze badges
3
- 1 Do you understand that a webSocket connection starts as an HTTP request with some custom headers and then when both sides agree, the protocol is switched from HTTP to webSocket? So, you just need a handler looking at all the ining HTTP requests for the websocket upgrade header and then you can pass that socket off to your webSocket code. If you use socket.io in both client and server, it handles all this for you by just hooking into your http server to do just that. You don't create a separate webSocket server per se. – jfriend00 Commented Feb 8, 2015 at 7:07
-
1
Yup. I understand in the general sense that that's how it should be done, but I've only found the one example I linked above, and it's not clear to me from that what I'm doing wrong - my initial
ws://
request hits the standard response portion of my HTTP server, and what I'm trying to figure out is what I should be doing to let it upgrade properly. – Dashiel N Commented Feb 8, 2015 at 15:53 - Updated the question pletely to clarify the issue that I'm having and give a simpler but more plete code example. – Dashiel N Commented Feb 10, 2015 at 6:28
2 Answers
Reset to default 4Here is a link to a very simple example application that uses the same Node.js server to accept and process both WS and HTTP connections. This should help get you started: https://github./openshift-quickstart/openshift-nodejs-http-and-websocket-example
var ipaddress = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var WebSocketServer = require('ws').Server
var http = require('http');
var server = http.createServer(function (request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write("Wele to Node.js on OpenShift!\n\n");
response.end("Thanks for visiting us! \n");
});
server.listen(port, ipaddress, function () {
console.log((new Date()) + ' Server is listening on port 8080');
});
wss = new WebSocketServer({
server: server,
autoAcceptConnections: false
});
wss.on('connection', function (ws) {
console.log("New connection");
ws.on('message', function (message) {
ws.send("Received: " + message);
});
ws.send('Wele!');
});
console.log("Listening to " + ipaddress + ":" + port + "...");
As it turns out, the issue I was having here was that Openshift has predefined that websocket
connections must e in on port 8000
, but are then forwarded to port 8080
on my gear, so my server needed to be listening on a different port than my client was explicitly connecting to, which is super counter-intuitive.
A mostly unrelated question I found on here ultimately lead me to an article from Openshift that lays out the details.