Socket.IO on Heroku does NOT work without SSL - node.js

I have a chat server setup as such:
var port = Number(process.env.PORT || 5000);
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app, {'log level':1, 'match origin protocol':true})
, fs = require('fs')
io.set('authorization', function (handshakeData, callback) {
console.log(handshakeData);
callback(null, true);
});
and then I handle some events:
io.sockets.on('connection', function(socket) {
socket.emit('handshaken', {id:socket.id}); // for HTML clients
socket.on('subscribe', function(roomId) {
doSubscribe(socket, roomId);
});
socket.on('unsubscribe', function(roomId) {
doUnsubscribe(socket, roomId);
});
socket.on('chat', function(data) {
doChat(data);
});
});
The client is on a different domain.
When I use the chat server via https, then everything is working fine. All the events are received. However, when I use http, I can see that the client can receive the 'handshaken' event, but nothing else is sent or received.
I wonder if this has anything to do with the socket.io authorization not working properly with non ssl connection.
However, in local environment, I can still use non ssl http://localhost:5000 as the chat server url without any issue. Is it also possible that this is an issue with Heroku?
UPDATE 1: After some investigation, if I use http url for the chat server, the server can emit to the client. The client can connect to the server, but cannot emit anything to the server (the server does not receive any emit).
Update 2: Some further investigations revealed that the chat server, under http, does received an emit, but only 1 emit. Any emit after that is not received.

It turned out that Sophos antivirus for Mac is the culprit here. After I disabled all web protection, my chat app works fine.
The interesting point here is that Sophos only targets Chrome browser, as Firefox and Safari work without any problem.

Related

Socket.io client in NodeJS

I want to build a microservice infrastructure with nodejs services and a master service, the communication between these services should happen via socket.io, i've setup my socket.io server, but their browser client (socket.io-client) is not working in nodejs (i guess it uses some browser only APIs). Is there a way to create a nodejs socket.io (NOT WEBSOCKETS) client?
EDIT
My client side code:
import { io } from "socket.io-client";
const socket = io("127.0.0.1:3000");
socket.on("connect", () => {
console.log(socket.id);
});
socket.on("disconnect", () => {
console.log(socket.id);
});
My server side code:
import { Server } from "socket.io";
const io = new Server();
io.on("connection", (socket) => {
console.log(socket)
});
io.listen(3000);
Both are written in typescript, the package versions are:
socket.io: ^4.4.0
socket.io-client: ^4.4.0
The Problem is, that i don't get any logs in my console, so i think there is something wrong with client, because socket.io does not mention node in there client side compatiblity graph.
The problem is that you have to pass a valid URL here:
const socket = io("127.0.0.1:3000");
I have no idea why socket.io doesn't give you an error, but if you change that to:
const socket = io("http://127.0.0.1:3000");
Then, it will work.
If you set DEBUG=socket.io-client in your environment, it won't show you an error, but it will show you that it's trying to connect to:
undefined//127.0.0.1:3000
which would give you a clue, I guess.
If you set DEBUG=* in your environment, you will get a lot more debug info (so much that it's a bit hard to sort through).
Set Logging and Debugging Socket.io for more info.

Azure free website NodeJS websocket no longer connecting

I have an Android app that uses websockets via a NodeJS server hosted with Azure. For the passed six months, everything has been fine. Today, all is not fine. When I try to connect to my server, I get the response "No address associated with hostname."
I have websockets enabled in my config tab in the management console, also in the web.config file so that Node handles the websocket and not iis. I have changed nothing, toggled the websocket settings, nothing works. I have restarted the server many times. I also created a new website and migrated everything, still the same issue. I cannot get tech support from Microsoft because the website is a free one. I am aware that there is a max of 5 connections to the websocket; this is not the issue.
My server is using the 'ws' websocket module. I have taken my server.js code down to the minimum for testing. This is it now...
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: process.env.PORT || 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {});
ws.on('close', function closing(code, message) {});
if (ws.readyState == 1)
ws.send('message from the server!');
});
It still does not work. I replaced the entire file with the code below and the server responds with text in the browser. Of course, this is not websocket, but it shows that the server is able to respond to http requests.
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('Hello, world!');
}).listen(process.env.PORT || 8080);
Has anything changed with the usage of websockets? Have recent restrictions been placed I am unaware of?

Server showing multiple client connection (net nodejs)

I am trying to make a server which listens on a internet facing port and forwards incoming http requests to an internal express server listening at another port. Following is the relevant part of the code I'm using.
var net = require('net');
var server = net.createServer();
server.listen(addr.from[3], addr.from[2], function(){
console.log('Server listening');
});
server.on('connection',function(from){
console.log('Client connected from '+ from.remoteAddress);
var to = net.createConnection({
host: addr.to[2],
port: addr.to[3]
});
from.pipe(to);
to.pipe(from);
from.on('error',function(err){
winston.error('Error at unix box'+err);
to.end();
});
to.on('error',function(err){
winston.error('Error at middleware server'+err);
from.end();
});
from.on('end',function(){
console.log('Client disconnected ');
to.end();
});
to.on('end',function(){
console.log('Middleware disconnected');
from.end();
});
});
The problem I'm encountering is that, when I open "ip:port" in the browser (which would be the internet facing port) I'm getting messages multiple "client connected from xxxxxx" msgs on the console. Can anyone help me understand why this is happening?
Whenever browser connects to a website it usually makes two requests: normal and to retrieve favicon.
Funny thing, is that the favicon request is not even displayed in browser developer tools.
To verify, you need to extract the request made, print it to server, and then observe why you get multiple requests. For that, connection might be too early, try hooking request event instead:
server.on('request', funtion(req, res) { console.log(req.url); });

Adobe AIR- connection issues with socket.io

I have a desktop app in Adobe Air (flex).
I have used flashSocket.io library in my app to communicate with socket.io on node.js server.
It works perfectly for most of the clients.
But for some random client the flex app is not able to create a connection with the socket.io server. It constantly throws connection error and close error on flex. The clients are not behind any firewalls or proxy server.
The console has warning like
Web Socket Connection Invalid
I guess this for those clients who are not able to connect.
Since its working for majority of the users i don't know where should i look into. Also, i am unable to reproduce this on my side.
Here's the Server Code:
var io = require('socket.io').listen(app);
app.listen(8080, function() {
console.log('%s listening at %s', app.name, app.url);
});
io.configure(function() {
io.set('transports', ['flashsocket']);
io.set('flash policy port', 843);
});
Flex code:
socket = new FlashSocket("http://domain.com:8080/");
socket.addEventListener(FlashSocketEvent.CONNECT, onConnect);
socket.addEventListener(FlashSocketEvent.MESSAGE, onMessage);
socket.addEventListener(FlashSocketEvent.CLOSE, onDisconnect); //only close and connect_error event is always fired for certain clients
socket.addEventListener(FlashSocketEvent.CONNECT_ERROR, onConnectError);
Any help would be highly appreciated.
Use a different port, we're using 443.

Socket.io and modern browsers aren't working

I'm having some weird issues with socket.io and modern browsers. Surprisingly, with IE9 works fine because fallbacks to flashsocket which appears to work better.
In my server (with express)
var io = socketio.listen(server.listen(8080));
io.configure('production', function(){
console.log("Server in production mode");
io.enable('browser client minification'); // send minified client
io.enable('browser client etag'); // apply etag caching logic based on version number
io.enable('browser client gzip'); // gzip the file
io.set('log level', 1); // reduce logging
io.set('transports', [ // enable all transports (optional if you want flashsocket)
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
});
On the browser I can see in the Network tab (on Chrome) that a websocket is stablished and get in 101 Switching Protocols in Pending mode. After that, appears xhr-polling and jsonp-polling (what happend to flashsocket ? )
The worst part is that info don't go back and forth. I have this on connection:
io.sockets.on('connection', function (socket) {
// If someone new comes, it will notified of the current status of the application
console.log('Someone connected');
app.sendCurrentStatus(socket.id);
io.sockets.emit('currentStatus', {'connected': true);
});
And on client:
socket.on('currentStatus', function (data){ console.log(data) });
However I only be able to see that log when I turn off the server which is launched with:
NODE_ENV=production node server.js
What am I doing wrong?
Finally, after really banging my head against a wall, I decided to test in several environments to see if it was a Firewall issue since the machine is behind several ones.
It turned out that no one but me had the problem so I checked the Antivirus (Trend Micro) and after disabling, Chrome/Firefox were able to make their magic.
Moral of the story
Besides what it says here - Socket.IO and firewall software - whenever you face an issue that nobody in the internet seems to have (ie, not logged on github nor the socket.io group) it's probably caused by your Antivirus. They are evil. Sometimes.
You should just be having the socketio listen on the app itself.
Also, I have never need to do all of the server side configuration with the socket that you are doing - socket.io should work out of the box on most browsers without doing that. I would try first without configuring.
Also, on the server, you should emit from the socket that is passed to the callback function rather than doing io.sockets.on.
var io = socketio.listen(app);
io.sockets.on('connection', function (socket) {
// If someone new comes, it will notified of the current status of the application
console.log('Someone connected');
app.sendCurrentStatus(socket.id);
socket.emit('currentStatus', {'connected': true);
});
on the client, you need to connect first:
var socket = io.connect();
socket.on('currentStatus', function (data){ console.log(data) });
If you want to see an example of two way communication using socket.io, check out my Nodio application.
The server side:
https://github.com/oveddan/Nodio/blob/master/lib/Utils.js
And the client side:
https://github.com/oveddan/Nodio/blob/master/public/javascripts/Instruments.js

Resources