How to host a socket.io server and a http server together? - javascript

I have a Socket.io server and a basic HTTP server that I coded together, but the problem is that the HTTP-server tries to serve requests that socket.io should serve.
Code:
//Dependences
var sio = require('socket.io');
var http = require("http");
var NewRequestHandler = require('./NewRequestHandler').Handler;
var DisconnectHandler = require('./DisconnectHandler').Handler;
var AuthorisationRequestHandler = require('./AuthorisationRequestHandler').Handler;
//The backlog of resources
var ResourceBackLog;
var ResourceRequestHandler = require("./ResourceRequestHandler").Handler;
//Reports the IP adress and Port that it will run on.
console.log('IP address: ' + process.env.IP);
console.log('Port: ' + process.env.PORT);
//Creates and configures a new http.server instance.
var Server = new http.Server();
//Starts both the http and socket.io server.
var io = sio.listen(Server.listen(process.env.PORT, process.env.IP, ResourceBackLog, function(error) {
if (error) {
console.log("Error: " + error);
} else if (!error) {
console.log("Server started sucsessfully.");
Server.on('request', ResourceRequestHandler);
console.log("Server now ready for requests.");
}
}));
//Handles the connect and authorisation bit
io.sockets.on('connection', function(socket) {
console.log('New Connection');
socket.on('auth', function(Keys) {
console.log('Autorisation Request Recived');
AuthorisationRequestHandler(socket, Keys, function() {
socket.on('NewRequest', function(Request) {
NewRequestHandler(socket, Request);
});
socket.on('diconnect', function() {
DisconnectHandler(socket);
});
});
});
});
The ResourceRequestHandler is the file that serves resources by checking the URL then opening the file at that location,
but it also serves /socket.io requests.

I would have Socket.io listen on another port and have the regular http server direct requests to it that way you can be sure they won't interfere with each other.
// create server
io = http.createServer();
io.on('uncaughtException', function(exception) {
console.log(exception);
});
io.listen(4001);

http.createServer(RequestHandler) and new http.Server(RequestHandler) work

Based on Socket.IO 0.9.6.
It is important to attach your custom request listener before the socket.io one. Socket.IO will then serve the requests it can and delegate all the others to your own request listener.
The algorithm in socket.io/lib/manger.js, is as follows.
In constructor:
1. remove all the existing request listeners.
2. attach Socket.IO request listener.
On request:
1. try to handle the request.
2. if Socket.IO cannot handle it, it delegates the request to the original listeners - those which were earlier removed in the constructor.

Related

Express-generator, Socket.io Event issuing multiple times

I have create a node app using express generator. I have integrated socket.io in the application. Since express generator has their own way of creating express server i have followed this procedure to successfully integrate the Socket connection with listening server and made the io available throughout the application via res.io instance.
FILE: bin/www
#!/usr/bin/env node
var app = require('../app').app;
var debug = require('debug')('www:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = require('../app').server;
/app.js
//Express handler
var app = express();
// Socket configuration
var server = require('http').Server(app);
var io = require('socket.io')(server);
app.use(function(req, res, next){
res.io = io;
next();
});
...
module.exports = {app: app, server: server};
But the problem is when i m emitting an event as shown below. My client is reading the data multiple times.
routes/index.js
var clients = 0;
var nsp = res.io.of('/default-namespace');
nsp.on('connection', function (socket) {
clients++;
console.log(clients + ' clients connected!');
socket.on('disconnect', (reason) => {
clients--;
console.log(clients + ' clients connected!');
});
nsp.emit("socketToMe", "New User connected. Current clients:"+ clients);
});
My listener has the following code:
home.pug
var socket = io('/default-namespace');
socket.on('socketToMe', function (data) {
$('#data-div').append($('<li>').text(data));
});
Whenever i refresh the browser in another instance like incoginito my main browser is showing multiple events for the data. Like this
New User connected. Current clients:1
New User connected. Current clients:2
New User connected. Current clients:1
New User connected. Current clients:2
New User connected. Current clients:1
New User connected. Current clients:1
Not sure what is wrong. Can anyone help me on this?
Nodejs is event driven.The res object is not a global variable.
Express middleware runs for every request.
var clients = 0;
var nsp = res.io.of('/default-namespace');
nsp.on('connection', function (socket) {
clients++;
console.log(clients + ' clients connected!');
socket.on('disconnect', (reason) => {
clients--;
console.log(clients + ' clients connected!');
});
nsp.emit("socketToMe", "New User connected. Current
clients:"+clients);
});
Let me explain what happens above.A user requests and req handler is fired and you access the res object and you listen for events.
So for each request, you are listening for socket 'connection' event.That means you are setting multiple event listeners with the same name.Every time you make a request you set a new listener.
You are supposed to set only a single 'connection' listener.
This explains emitting the same event multiple times.
app.use(function(req, res, next){
res.io = io;
next();
});
Instead of using the above middleware function,listen directly on io instance

client code in node js

I am new to Nodejs and am trying to set up a server client connection using sockets. Below is my code. Server is working OK but client is not connecting.
Please can anyone help me figure out the mistake.
Much Thanks
jessi
Server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
io.on('data', function(data) {
console.log('DATA from client is: ' + data);
// Close the client socket completely
});
server.listen(4200);
console.log('Monitoring server listening on port 4200');
Client.js
var HOST = '127.0.0.1';
var PORT = 4200;
var express = require('express');
var app = express();
var client = require('http').createServer(app);
var io = require('socket.io')(client);
client.connect(PORT, HOST, function()
{
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// Write a message to the socket as soon as the client is connected,
// the server will receive it as message from the client
io.write('I am Chuck Norris!');
});
// 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);
// Close the client socket completely
client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
For the client you use the socket.io-client package instead. The client side doesn't require the use of the Express portion since you're not recreating a web server on the client. If you look at your current code you're essentially recreating the Socket server which isn't what you want to do.
All that is necessary is to create a new Socket.io client and register your various event handlers.
var socket = require('socket.io-client')('localhost:4200');
socket.on('data', function(data) {
// handle incoming data
console.log(data);
});

Can't connect to wss:// (Error in connection establishment: net::ERR_CONNECTION_CLOSED)

I have VPS with LAMP. I have free signed SSL certificate from Startssl.com (ssl certificate working correctly)
With http:// protocol I can connect to ws://chat.example.com:1337/some-variable but when I replace protocol http:// to https:// then I can't connect to wss://chat.example.com:1337/some-variable
When I try to connect to wss:// I'm getting error Error in connection establishment: net::ERR_CONNECTION_CLOSED
Why?
// http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
"use strict";
// Optional. You will see this name in eg. 'ps' or 'top' command
process.title = 'node-chat';
// Port where we'll run the websocket server
var webSocketsServerPort = 1337;
// websocket and http servers
var webSocketServer = require('websocket').server;
var http = require('http');
var $ = require("jquery");
/**
* HTTP server
*/
var server = http.createServer(function(request, response) {
// Not important for us. We're writing WebSocket server, not HTTP server
});
server.listen(webSocketsServerPort, function() {
console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
});
/**
* WebSocket server
*/
var wsServer = new webSocketServer({
// WebSocket server is tied to a HTTP server. WebSocket request is just
// an enhanced HTTP request. For more info http://tools.ietf.org/html/rfc6455#page-6
httpServer: server
});
EDIT
I have source from http://ahoj.io/nodejs-and-websocket-simple-chat-tutorial
To critique my answer better, as the last one was a mistake and I didn't mean to submit it until after I finished digging, try this:
// Private key and certification
var options = {
key: fs.readFileSync('cert/server.key'),
cert: fs.readFileSync('cert/server.crt')
};
var server = https.createServer(options, function(request, response) {
console.log((new Date()) + ' Received HTTP(S) request for ' + request.url);
}

How can I have faye-websockets code running in the browser?

I'm new with node.js/express and all and I want to be able to notify any clients in browser about a new message received from some algorithm in the back-end. The publisher algorithm connect to the websocket and writes the message.
As far as I've looked there were examples which recommended websockets but I haven't been able to run that code in browser only in console.
Example client code:
var WebSocket = require('faye-websocket');
var ws = new WebSocket.Client('ws://localhost:1234');
var http = require('http');
var port = process.env.PORT || 1235;
var server = http.createServer()
.listen(port);
// receive a message from the server
ws.on('message', function(event) {
alert(JSON.parse(event.data));
});
Thank you
Found the answer after some trial/error iterations.
The algorithm now does a POST to an URL which in turn triggers a write to sockets for all connected clients via socket.io.
Client code:
var socket = io('http://localhost:7777');
socket.on('message', function (msg) {
document.body.insertAdjacentHTML( 'beforeend', '<div id="myID">'+msg+'</div>' );
});
And on the server, when client connects I retain it's socket into an array so I can write to each one:
Server code:
io.on('connection', function(socket){
console.log('a user connected: '+socket.id);
var id = clientCount++;
clientSockets[id] = socket;
socket.on('disconnect', function(){
console.log('user disconnected');
delete clientSockets[id];
socket = null
});
});
app.post('/alerts', function(req, res) {
req.accepts(['json', 'application']);
console.log("Algo did a POST on /alerts!");
// send the message to all clients
//console.log(req.body);
for(var i in clientSockets) {
clientSockets[i].send(JSON.stringify(req.body));
}
res.send(200);
});
In conclusion, I'm not using faye-websockets but instead socket.io

Node.js websocket-server and tcp-server connection

Related to this question Browser with JavaScript TCP Client I asked whether I can connect from a browser to a tcp server. I found out that it won't work so I asked for another solution. '0101' provided me to built up two servers. One tcp server for a c++ application that connects to and one websockets server that receives data from the browser. I have originally built up each one of them, but I don't know how to connect them so I can receive data from the browser in the c++ application.
Here is the websockets-server:
var ClientListe = {};
// Anzahl der Verbundenen Clients
var ClientAnzahl=0;
// Websocket-Server
var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({host: '127.0.0.1',port: 80});
wss.on('connection', function(ws)
{
// Client-Anzahl hochzählen
ClientAnzahl++;
// Client-Verbindung mit in die Client-Liste Aufnehmen
ws['AUTH'] = ClientAnzahl;
ClientListe[ws['AUTH']] = ws;
// Ausgabe
console.log('client '+ClientAnzahl+' verbunden...');
ws.on('message', function(message)
{
console.log('von Client empfangen: ' + message);
for(client in ClientListe)
{
ClientListe[client].send('von Server empfangen: ' + message);
}
});
ws.on('close', function()
{
// Client aus der ClientListe Löschen
delete ClientListe[ws['AUTH']];
// Nachricht der Trennung an die Console ausgeben
console.log('Client '+ ws['AUTH'] +' getrennt.');
});
});
and here is the tcp server:
// Load the TCP Library
net = require('net');
// Keep track of the chat clients
var clients = [];
// Start a TCP Server
net.createServer(function (socket) {
// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort;
// Put this new client in the list
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome " + socket.name + "\n");
broadcast(socket.name + " joined the server\n", socket);
// Handle incoming messages from clients.
socket.on('data', function (data) {
broadcast(socket.name + " message: " + data, socket);
});
// Remove the client from the list when it leaves
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the server.\n");
});
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
}).listen(80);
// Put a friendly message on the terminal of the server.
console.log("TCP Server running at localhost port 80\n");
Both are copied out of the internet for testing some cases
Create a TCP server (NodeJS example)
var net = require("net");
var server = net.createServer(function(c) { //'connection' listener
console.log('server connected');
c.on('end', function() {
console.log('server disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.listen(8124, function() { //'listening' listener
console.log('server bound');
});
Then in the same file (optionally of course) create a WS server with different port number
var WebSocketServer = require("ws").Server;
var wss = new WebSocketServer({
port: 8080
});
wss.on("connection", function(ws) {
console.log("CONNECTED");
// ws.on("message"), ws.on("close"), ws.on("error")
});
Now you should have two servers, one for regular sockets and another one for WebSockets.
// As I mentioned in the previous question and Pete as well, it is a lot better to use WebSockets in C++ as well instead of creating two servers...
Drop the TCP server and make the C++ client connect to the websockets server instead. You'll need to implement the websockets protocol on top of your TCP connection at the C++ end (all you really need is a bit of pre-amble to negotiate the websocket). You have problems here with both servers trying to use port 80.
By the way, you should also consider using HTTPS for the websocket instead of HTTP since it avoids problems with proxy traversal. But get the HTTP case working first as this will be more complicated to implement on the C++ end.

Categories

Resources