socket.io redis store on openshift - node.js

I'm trying to set up socket.io on node.js to use redisstore so i can comunicate with pubsub with multiple node on the opeshift platform, but i can't manage to connect to the redis server. I'm using this cartridge.
I tried to connect with
var pub = redis.createClient(process.env.OPENSHIFT_REDIS_DB_PORT,
process.env.OPENSHIFT_REDIS_DB_HOST);
but it doesn't work (and I found out why: createClient() only accept IP addresses) and it fallback to the default port and host, then I ran rhc port-forward:
$ rhc port-forward appname
Checking available ports ... done
Forwarding ports ...
Address already in use - bind(2) while forwarding port 8080. Trying local port 8081
To connect to a service running on OpenShift, use the Local address
Service Local OpenShift
--------------- --------------- ---- ----------------------------------------------
haproxy 127.0.0.1:8080 => 127.5.149.130:8080
haproxy 127.0.0.1:8081 => 127.5.149.131:8080
s_redis_db_host 127.0.0.1:54151 => blabla.appname.rhcloud.com:54151
Press CTRL-C to terminate port forwarding
So I tought I was doing all wrong and I had to set just the port like this:
var pub = redis.createClient(process.env.OPENSHIFT_REDIS_DB_PORT);
but all I get is this
info: socket.io started
events.js:72
throw er; // Unhandled 'error' event
^
Error: Redis connection to 127.0.0.1:54151 failed - connect ECONNREFUSED
at RedisClient.on_error (/var/lib/openshift/532c3790e0b8cd9bb000006b/app-root/runtime/repo/node_modules/socket.io/node_modules/redis/index.js:149:24)
at Socket.<anonymous> (/var/lib/openshift/532c3790e0b8cd9bb000006b/app-root/runtime/repo/node_modules/socket.io/node_modules/redis/index.js:83:14)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:426:14
at process._tickCallback (node.js:415:13)
DEBUG: Program node server.js exited with code 8
I tried to connect via
telnet $OPENSHIFT_REDIS_DB_HOST $OPENSHIFT_REDIS_DB_PORT
And it works fine... Do you have any suggestions? Am I doing it wrong? (I'm still new to redis and socket.io)
(I omitted the rest of the code 'cause I know it works, I have no problem on my local machine, I just can't get the connection...)
Thanks a lot

but it doesn't work (and I found out why: createClient() only accept IP addresses) and it fallback to the default port and host
It does support Host, createClient uses net.createConnection(port, host); that does support hostname.
The following code will help you find the issue:
console.log(process.env);
var pub = redis.createClient(process.env.OPENSHIFT_REDIS_DB_PORT,
process.env.OPENSHIFT_REDIS_DB_HOST, {auth_pass: process.env.OPENSHIFT_REDIS_DB_PASSWORD});
pub.on('error', console.log.bind(console));
pub.on('ready', console.log.bind(console, 'redis ready'));
Does your openshift Redis instance requires AUTH ?

don't know if it is about a recent change on openshift, but i think the problem is in the variables. Although they work for telnet.
you can try this
var redisHost = process.env.OPENSHIFT_REDIS_HOST;
var redisPort = process.env.OPENSHIFT_REDIS_PORT;
var redisPass = process.env.REDIS_PASSWORD;
var client = redis.createClient( redisPort, redisHost );
client.auth( redisPass );

Related

Unable to connect to redis cluster with node client, what am I doing wrong?

I have spun up an AWS ElastiCache redis instance running in clustered mode, which currently has 1 shard and 2 nodes
In order to connect to it from my local machine I have opened up an SSH tunnel using my SSH config file
Host myRedisTunnel
HostName 1.2.3.4
...
LocalForward 6378 5.6.7.8:6379
the tunnel works, I can connect to my VPC successfully
$ ssh myRedisTunnel
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1060-aws x86_64)
...
I can connect to the redis cluster locally via redis-cli after opening my tunnel and passing -c as an argument for clustered mode
$ redis-cli -c -h localhost -p 6378
localhost:6378> ping
PONG
but when I try to use redis for nodejs it wont connect, it just times out, am i missing some configuration settings, or is it physically impossible to connect to my remote redis via tunnel?
const { createCluster } = require('redis')
const client = createCluster({
rootNodes: [
{ url: 'redis://localhost:6378' }
]
})
await client.connect()
const res = await client.ping()
console.log({ res })
Error: Connection timeout
at Socket.<anonymous> (node_modules/#node-redis/client/dist/lib/client/socket.js:163:124)
at Object.onceWrapper (node:events:513:28)
at Socket.emit (node:events:394:28)
at Socket._onTimeout (node:net:486:8)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7)
I have tried several nodejs clients for redis and all of them have timed out in the same way, so I know the issue has to either be that I have a config setting wrong in my nodejs redis client configuration - or it has something to do with only one of the redis ip addresses is accessible via tunnel, all the rest of the cluster would likely not be accessible unless i open tunnels for each one. Im just at a loss for how mock my production environment in development so i can write code.
As you've pointed out, you'll need to create a tunnel for each node in the cluster
The clients are using the CLUSTER NODES command in order to discover all the nodes and the cluster, and this command will return the actual IPs and ports of the nodes, not the tunnels. You can use ioredis with "NAT Mapping" to solve that.

listen EADDRINUSE: address already in use -> No matter what port I use?

NodeJS version: LTS 12.17 installed like this:
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt install nodejs
I have a pretty weird issue:
One of my NodeJS app suddenly reports: listen EADDRINUSE: address already in use and it doesn't help anything no matter what port # I try to change it to?
The full trace-stack looks like this:
Error: listen EADDRINUSE: address already in use 0.0.0.0:6080
at Server.setupListenHandle [as _listen2] (net.js:1313:16)
at listenInCluster (net.js:1361:12)
at doListen (net.js:1498:7)
at processTicksAndRejections (internal/process/task_queues.js:85:21)
I'm listening like this (_wl = a Winston logger instance):
> _server.listen(_port, '0.0.0.0', function () { _wl.info('SERVER STARTED! (listening on port # ' + _port + ')')});
I have just setup this AWS EC2 Ubuntu 20.04 instance - so I guess somehow it has something to do with this. It has been working for years on a lot of different instance earlier Windows (I guess I have never run it on Ubuntu earlier).
I execute like like:
1. cd into folder
2. node ./server.js (I have also tried to use Sudo)
Can it have something to do with permissions?
I have tried to allow all in /out going traffic in the server atteched Security Group.
I have check that the firewall in Ubuntu 20.04 is disabled as well.
Also, on the same server I'm running a Python app which exposes a web socket server and the NodeJS app has no issue to subscribe to this connection...
And yes - I have tried to check all ports in use at the server and only few ports are in use.
The NodeJS app also try to expose a websocket server at a given port - but no matter what port I try to use I get the error above.
Sorry!
I use express in my NodeJS apps and most of my apps contain the following line:
app.listen(port); // In this case port # 6080
Later on in the current app (in which I experience the issue described above) I initialize a web socket server as well like this:
const _server = require('http').createServer();
_server.on('request', app);
_server.listen(_port, '0.0.0.0', function () { _wl.info('WEB SOCKET SERVER STARTED! (listening on port # ' + _port + ')')});
in the code above both port and _port used the same ENV variable/setting(6080). Do to my app/Express in this case actually didn't use the app.listen(port) to anything and that Windows just choose to overrule the port's use-case when the web socket server afterwards got initialized with the same port number --> is the reason why I never have experienced any issues on Windows. But Linux/Ubuntu is more sensitive in this regard.
Cheers! :-)

Webpage not publicly accessible via port 80

I have the following code written with Node/Koa, which is serving to port 80:
const
koa = require('koa'),
route = require('koa-route'),
network = koa(),
common = require('koa-common'),
PORT = 80;
// enable logger middleware
network.use(common.logger('dev'));
// enable static middleware
network.use(common.static(__dirname + '/public'));
network.use(route.get('/', index));
network.use(route.get('/about', about));
function *index() {
this.body = "<h1>Is this message on my computer, or on yours...?</h1>";
}
function *about() {
this.body = "<h2>How about now...</h2>";
}
var server = network.listen(PORT, function () {
console.log('Listening on port %d', server.address().port);
});
I have reserved an address (168.192.1.91) for the host computer, set up port forwarding to this address on port 80, made an exception in the Windows 10 firewall for port 80 when connected to via any protocol, and tested with You Get Signal:
which confirms that the port is currently open. When I browse to localhost:80 I can see the default page. However, when I type the computer's public IP address into the browser (I'm typing in the one that I've partially obscured, which I believe should be the correct one):
this page fails to load with the following error:
This site can’t be reached
109.[...] took too long to respond.
Try:
Reloading the page
Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_TIMED_OUT
and there is no activity in the Koa log (which logs fine when I browse to there via localhost:80). Any ideas what could be blocking the connection?
I have also tried adding the host address as a second parameter like this:
const HOST = "127.0.0.1";
var server = network.listen(PORT, HOST, function () {
console.log('Listening on port %d', server.address().port);
});
This works for the loopback address, but when I specify my public IP I get this error:
C:\Sites\order-server>node --harmony cheese.js
events.js:154
throw er; // Unhandled 'error' event
^
Error: listen EADDRNOTAVAIL [My public IP here]:80
at Object.exports._errnoException (util.js:890:11)
at exports._exceptionWithHostPort (util.js:913:20)
at Server._listen2 (net.js:1221:19)
at listen (net.js:1270:10)
at net.js:1379:9
at _combinedTickCallback (node.js:386:13)
at process._tickCallback (node.js:407:11)
at Function.Module.runMain (module.js:449:11)
at startup (node.js:142:18)
at node.js:939:3
Maybe koa by default only binds to 127.0.0.1 so you can try binding to any host explicitly with .listen(80, '0.0.0.0')
Otherwise if the firewall ant the port forwarding is configured accordingly, the problem could be that your Internet Provider is blocking incoming connections somewhere. You could try useing an Port over 1024, if it only blocks Ports below.

Run first Nodejs app on cpanel godaddy hosting

I'm trying to run my first Node.js application, but I'm having trouble. This could be an error with the firewall on CPanel, but I'm not sure.
I'm running Node.js version 5.0.0
And this is my js:
var net = require('net');
var server = net.createServer(function (socket) {
socket.write('Open Serverrn');
socket.pipe(socket); });
server.listen(674, 'my.ip.add.ress');
console.log('Server running at http://my.ip.add.ress:674/');
And final : this is my notification :
node test.js
Error is:
Server running at http://my.ip.add.ress:674/
events.js:141
throw er; // Unhandled 'error' event
^
Error: listen EACCES my.ip.add.ress:674
at Object.exports._errnoException (util.js:860:11)
at exports._exceptionWithHostPort (util.js:883:20)
at Server._listen2 (net.js:1221:19)
at listen (net.js:1270:10)
at net.js:1379:9
at doNTCallback3 (node.js:461:9)
at process._tickCallback (node.js:367:17)
at Function.Module.runMain (module.js:459:11)
at startup (node.js:136:18)
at node.js:972:3
When I open my console with port 674, it's always loading and timing out after a few seconds. Why is that? Plz help me this issue.
I do not believe GoDaddy has Node.js support, as per this: How to install nodejs application in Godaddy server
Common hosts for Node apps would be:
Digital Ocean, Nodejitsu (owned by GoDaddy anyway), Modulus, Heroku, Joyent, and AWS, I believe.
You need to use port higher than 1024. To bind lower ports you need root privileges or allow program to bind via setcap - can't be implimented at GoDaddy or other shared hosting.

Nodejs net does not throw error when trying to connect to a host thats not listening

I'm trying to test whether a remote host is listening or not using Node.js net module:
var net = require('net')
var client = net.connect({port:3000, host:remoteHostIP},function(){
});
client.on('error', function(err){
console.log("Error: "+err.message);
});
I would expect that net.connect would throw an error if it can't connect but that's not the case.
Also client.on('error') does not throw an error.
How can I check if the connection has been possible?
It will throw an error when the connection times out which is about one minute of no data transfer.
Error: connect ETIMEDOUT <ip>:3000
Use client.setTimeout() to fire a callback if there's no activity within the allocated time.
The code posted in the question works fine:
node app.js
Error: connect ECONNREFUSED
The issue has been caused by a Virtualbox VM for Docker (running on the developer machine) which had portforwarding configured for port 3000 and grabbed the net connect request for localhost.

Resources