Socket.IO and Node.js Core Cluster - node.js

Is it possible to use Socket.IO with Node's core cluster (not the outdated module)?
I can fork multiple workers and it seems to work fine; however, when opening a connection I get the error: solve: warn - client not handshaken client should reconnect
Here's the relevant code snippet (with a few simple things like expressjs config removed):
if ( cluster.isMaster ) {
for ( var i = 0; i < numCPUs; i++ ) {
cluster.fork();
}
} else {
app.get('/', function (req, res) {
res.sendfile( __dirname + '/public/html/index.html' );
});
io.configure( function() {
var RedisStore = require('socket.io').RedisStore,
opts = { host: 'localhost', port: 8888 };
io.set('store', new RedisStore( { redisPub: opts, redisSub: opts, redisClient: opts } ));
});
app.listen( 8888 );
io.sockets.on('connection', function (socket) {
socket.emit( 'some', 'data' );
});
}
I've tried with and without using RedisStore and with the trick on this site (which I believe is obsolete now): http://www.danielbaulig.de/socket-ioexpress/
I've also looked at the code at http://www.ranu.com.ar/2011/11/redisstore-and-rooms-with-socketio.html, although I don't see how that code is any different than using MemoryStore.
All of my test connections are using Websockets (RFC 6455). This works fine if I set numCPUs to equal 1.
Node.js version 0.6.17
Socket.io version 0.9.5
Expressjs version 2.5.9
Update - include console output (note, on this attempt the connection did ultimately work, although it threw the same errors):
info - socket.io started
info - socket.io started
info - socket.io started
info - socket.io started
info - socket.io started
debug - served static content /socket.io.js
debug - client authorized
info - handshake authorized 17644195072103946664
debug - setting request GET /socket.io/1/websocket/17644195072103946664
debug - set heartbeat interval for client 17644195072103946664
debug - websocket writing 7:::1+0
warn - client not handshaken client should reconnect
info - transport end (error)
debug - set close timeout for client 17644195072103946664
debug - cleared close timeout for client 17644195072103946664
debug - cleared heartbeat interval for client 17644195072103946664
debug - discarding transport
debug - client authorized
info - handshake authorized 16098526291524652257
debug - setting request GET /socket.io/1/websocket/16098526291524652257
debug - set heartbeat interval for client 16098526291524652257
debug - websocket writing 7:::1+0
warn - client not handshaken client should reconnect
info - transport end (error)
debug - set close timeout for client 16098526291524652257
debug - cleared close timeout for client 16098526291524652257
debug - cleared heartbeat interval for client 16098526291524652257
debug - discarding transport
debug - client authorized
info - handshake authorized 13419993801561067603
debug - setting request GET /socket.io/1/websocket/13419993801561067603
debug - set heartbeat interval for client 13419993801561067603
debug - client authorized for
debug - websocket writing 1::
debug - websocket writing 5:::{"some":"data","args":[11354]}
debug - websocket writing 5:::{"some":"data","args":[36448]}
This is how the console output ends on a failure (fails about 9 times out of 10):
info - transport end by forced client disconnection
debug - websocket writing 0::
info - transport end (booted)
debug - set close timeout for client 1639301251431944437
debug - cleared close timeout for client 1639301251431944437
debug - cleared heartbeat interval for client 1639301251431944437
debug - discarding transport
debug - got disconnection packet
debug - got disconnection packet
Update - Added links to possible tickets on github:
https://github.com/LearnBoost/socket.io/issues/881
https://github.com/LearnBoost/socket.io/issues/438

It seems the issue may be related to the node module that Socket.IO comes installed with.
When I installed redis (npm install hiredis redis) and created the clients for the RedisStore using the redis module, everything suddenly worked perfectly. I've been running for over an hour with ~500 concurrent connections and haven't seen a single error, and every node process is being utilized.
hiredis#0.1.14
redis#0.7.2
Running Redis 2.6rc3 on port 6379.
Update: In Node.s 0.8, it looks like the cluster library should be considerably more mature, so the above code/issues will probably become obsolete: http://nodejs.org/docs/v0.7.8/api/cluster.html

Related

SignalR with React through NodeJS proxy

I'm trying to use SignalR on a React application through a NodeJS proxy using the NPM package 'http-proxy-middleware'. However, it appears that the connection is falling to connect. Below is the console log from the react application.
[2022-11-29T23:02:24.022Z] Information: Normalizing '/hubs/Chat' to 'https://localhost:3000/hubs/Chat'.
[2022-11-29T23:02:24.022Z] Debug: Starting connection with transfer format 'Text'.
[2022-11-29T23:02:24.023Z] Debug: Sending negotiation request: https://localhost:3000/hubs/Chat/negotiate?negotiateVersion=1.
[2022-11-29T23:02:24.642Z] Debug: Selecting transport 'WebSockets'.
[2022-11-29T23:02:24.643Z] Trace: (WebSockets transport) Connecting.
WebSocket connection to 'wss://localhost:3000/hubs/Chat?id=DykJoTMv9LiYrtjYHUCQVg' failed:
[2022-11-29T23:06:24.671Z] Information: (WebSockets transport) There was an error with the transport.
[2022-11-29T23:06:24.672Z] Error: Failed to start the transport 'WebSockets': Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.
[2022-11-29T23:06:24.672Z] Debug: Skipping transport 'ServerSentEvents' because it was disabled by the client.
[2022-11-29T23:06:24.672Z] Debug: Skipping transport 'LongPolling' because it was disabled by the client.
[2022-11-29T23:06:24.672Z] Error: Failed to start the connection: Error: Unable to connect to the server with any of the available transports. Error: WebSockets failed: Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled. ServerSentEvents failed: Error: 'ServerSentEvents' is disabled by the client. LongPolling failed: Error: 'LongPolling' is disabled by the client.
Error establishing the connection: Error: Unable to connect to the server with any of the available transports. Error: WebSockets failed: Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled. ServerSentEvents failed: Error: 'ServerSentEvents' is disabled by the client. LongPolling failed: Error: 'LongPolling' is disabled by the client.
at HttpConnection._createTransport (HttpConnection.ts:407:1)
at async HttpConnection._startInternal (HttpConnection.ts:283:1)
at async HttpConnection.start (HttpConnection.ts:137:1)
at async HubConnection._startInternal (HubConnection.ts:207:1)
at async HubConnection._startWithStateTransitions (HubConnection.ts:181:1)
If I connect directly to the .NET application, which is running the server-side part of SignalR, it works fine. So it's not a problem with that.
This is the code snippet from the React App which performs the connection.
this.hubConnection = new HubConnectionBuilder()
.withUrl("/hubs/chat",{
transport: HttpTransportType.WebSockets,
logger: LogLevel.Trace
})
.withAutomaticReconnect()
.build();
this.hubConnection.start().catch(error => console.log("Error establishing the connection: ", error));
The proxy is running in NodeJS through nodemon. Below is the code.
const PORT = 8000;
const express = require('express');
const https = require('https');
const fs = require('fs')
const {createProxyMiddleware} = require('http-proxy-middleware');
const app = express();
require('dotenv').config({ path: `.env.${process.env.NODE_ENV.trim()}` });
const httpsOptions = {
key: fs.readFileSync('./certs/cert.key'),
cert: fs.readFileSync('./certs/cert.pem')
}
app.use('/hubs/chat', createProxyMiddleware({
target: process.env.REACT_APP_APISERVICEURL,
changeOrigin: false ,
secure: false,
ws: true,
logger: console
}));
var secure = https.createServer(httpsOptions, app);
secure.listen(8000, () => console.log(`Server is running on port ${PORT}`));
The proxy does work for all other API calls to the .NET Application. The React application has the proxy attribute set in the package.json. The proxy then re-writes the URL and adds an API Token header to send to the API. Hence the use of http-proxy-middleware.
I have tried the below as well, but it still produces the same result.
const signlrRProxy = createProxyMiddleware({
target: process.env.REACT_APP_APISERVICEURL,
changeOrigin: false ,
secure: false,
ws: true,
logger: console
});
app.use('/hubs/chat', signlrRProxy);
var secure = https.createServer(httpsOptions, app);
secure.listen(8000, () => console.log(`Server is running on port ${PORT}`));
secure.on('upgrade', signlrRProxy.upgrade);
I am using the latest package versions to everything.

Zookeeper Leader Auto Failover

We are using spark standalone cluster 3 zookeepers in HA mode.I am seeing this issue in zookeeper.log.
Exception causing close of session 0x0 due to java.io.IOException: Len error 1195725856
Closed socket connection for client /10.23...... (no session established for client)
Zookeeper leader is getting auto failed over from one server to another server and hence followed by this, spark master is getting auto failed over
Also Some clients are getting continually disconnected/reconnected with this error.
How to fix
Full Log:
[myid:3] - WARN [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn#354] - Exception causing close of session 0x0 due to java.io.IOException: Len error 1195725856
[myid:3] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn#1001] - Closed socket connection for client /10....... (no session established for client)
[myid:3] - ERROR [LearnerHandler-/159.1.......:LearnerHandler#562] - Unexpected exception causing shutdown while sock still open
[myid:3] - WARN [LearnerHandler-/159.1......:LearnerHandler#575] - ******* GOODBYE /159.1..... ********
[myid:3] - INFO [WorkerReceiver[myid=3]:FastLeaderElection#542] - Notification: 1 (n.leader), 0x29000000ed (n.zxid), 0xa (n.round), LOOKING (n.state), 1 (n.sid), 0x29 (n.peerEPoch), LEADING (my state)
[myid:3] - INFO [LearnerHandler-/159........:LearnerHandler#263] - Follower sid: 1 : info : org.apache.zookeeper.server.quorum.QuorumPeer$QuorumServer#e144103
[myid:3] - INFO [LearnerHandler-/159.......LearnerHandler#318] - Synchronizing with Follower sid: 1 maxCommittedLog=0x29000000ed minCommittedLog=0x2800000007 peerLastZxid=0x29000000ed
[myid:3] - INFO [LearnerHandler-/159.......:LearnerHandler#395] - Sending DIFF

Not able to connect to Hipchat with errbot ? getting permission denied for socket .

While connect error bot with self hosted . Getting this error while doing it -
10:40:34 DEBUG sleekxmpp.xmlstream.xmlst RECV: <proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls" />
10:40:34 DEBUG sleekxmpp.features.featur Starting TLS
10:40:34 INFO sleekxmpp.xmlstream.xmlst Negotiating TLS
10:40:34 INFO sleekxmpp.xmlstream.xmlst Using SSL version: TLSv1
10:40:34 DEBUG sleekxmpp.xmlstream.xmlst Event triggered: socket_error
10:40:34 ERROR sleekxmpp.xmlstream.xmlst **Socket Error #13: Permission denied**
10:40:34 DEBUG sleekxmpp.xmlstream.xmlst reconnecting...
This is config which i am using for same .
BACKEND = 'Hipchat' # Errbot will start in text mode (console only mode) and will answer commands from there.
BOT_DATA_DIR = r'/Users/XXX/errbot/errbot/data'
BOT_EXTRA_PLUGIN_DIR = '/Users/XXXX/errbot/errbot/plugins'
BOT_LOG_FILE = r'/Users/XXXX/errbot/errbot/errbot.log'
BOT_LOG_LEVEL = logging.DEBUG
BOT_ADMINS = ('#XXXXX', ) # !! Don't leave that to "CHANGE ME" if you connect your errbot to a chat system !!
# The identity, or credentials, used to connect to a server
BOT_IDENTITY = {
'username': 'XXXX', # The JID of the user you have created for the bot
'password': 'XXXXX', # The corresponding password for this user
'token': 'XXXXXX',
'endpoint' : 'https://xxxx.xxxx.com',
}
Can someone please let me know what i am doing wrong in above config ?
Or please also suggest any other bot (in python) that works with self hosted Hipchat .
Hipchat Server removed external access to the XMPP ports on the 2.0.7 release, in favor of supporting only communication over port 443 (using XMPP's BOSH protocol).
Depending on your server version, you might be able to enable them back by running hipchat network --enable-xmpp-ports.
https://confluence.atlassian.com/hipchatkb/external-xmpp-ports-5222-5223-disabled-by-default-in-hipchat-server-2-0-7-859442760.html has more information on this topic.

canvasengine Tiled_server Error: ENOENT, open './map.json'

This is my problem:
I try start Canvasengine example server and I get this error.
root#vps185158:/# node /var/www/canvas/canvasengine/examples/tiled_server/server/server.js
info - socket.io started
debug - client authorized
info - handshake authorized ogjRNMePBqcD_ZIkFVFK
debug - setting request GET /socket.io/1/websocket/ogjRNMePBqcD_ZIkFVFK
debug - set heartbeat interval for client ogjRNMePBqcD_ZIkFVFK
debug - client authorized for
debug - websocket writing 1::
/node_modules/canvasengine/core/engine-common.js:373
if (err) throw err;
^
Error: ENOENT, open './map.json'
at Error (native)
map.json is there, but nodejs can't find that file.
Server have Debian 7, nodejs, Socket.io and CanvasEngine 1.3.0
Looking at the code, you should either copy map.json to your working directory (which seems to be /, so I wouldn't necessarily recommend that) or start the server from its respective directory:
$ cd /var/www/canvas/canvasengine/examples/tiled_server/server/
$ node server
(although this may require setting $NODE_PATH)

Delayed socket.io response, and "warn - websocket connection invalid"

I am running a nodeJS + Express + socket.io + httpd application on an AWS EC2 instance.
Upon loading the page, the logger provides this information:
GET / 200 2ms - 1.23kb
GET /javascripts/script.js 304 1ms
debug - served static content /socket.io.js
GET /stylesheets/style.css 304 1ms
GET /stylesheets/style.css 304 1ms
GET /images/052.png 304 1ms
GET /Candara.ttf 304 1ms
debug - client authorized
info - handshake authorized EgWLPeyO2uiCTSui01CP
debug - setting request GET /socket.io/1/websocket/EgWLPeyO2uiCTSui01CP
debug - set heartbeat interval for client EgWLPeyO2uiCTSui01CP
warn - websocket connection invalid
info - transport end (undefined)
debug - set close timeout for client EgWLPeyO2uiCTSui01CP
debug - cleared close timeout for client EgWLPeyO2uiCTSui01CP
debug - cleared heartbeat interval for client EgWLPeyO2uiCTSui01CP
At this point, things will halt for about 5 seconds, after which:
debug - setting request GET /socket.io/1/xhr-polling/EgWLPeyO2uiCTSui01CP?t=1376937523124
debug - setting poll timeout
debug - client authorized for
debug - clearing poll timeout
debug - xhr-polling writing 1::
debug - set close timeout for client EgWLPeyO2uiCTSui01CP
debug - setting request GET /socket.io/1/xhr-polling/EgWLPeyO2uiCTSui01CP?t=1376937523490
debug - setting poll timeout
debug - discarding transport
debug - cleared close timeout for client EgWLPeyO2uiCTSui01CP
After this point, things start working well as far as I can tell, and events are fired and received without delays (if an event is fired before the 5 seconds delay described above, they will not be processed until after the delay has completed). The problem is how to remove that 5 seconds delay.
The client-side JS looks like this:
window.onload = function () {
var socket = io.connect("http://xxx.us-west-2.compute.amazonaws.com", {resource: "/socket.io"});
The server-side JS looks like this:
var express = require('express');
var app = express();
var io = require("socket.io").listen(app.listen(3000));
My httpd.conf file looks like this:
ProxyPreserveHost On
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location />
allow from all
</Location>
How can I avoid the initial delay and establish a healthy connection to socket.io?
I fixed the problem by restricting the allowed transport methods to "xhr-polling" and "jsonp-polling". I believe this is because Apache/2.2.25 doesn't offer support for the others.
The relevant code was added server-side:
io.set("transports", ["xhr-polling", "jsonp-polling"]);

Resources