Azure free website NodeJS websocket no longer connecting - azure

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?

Related

Socket.IO with HTTPS over apache present?

I have a domain name.
I have a Raspberry Pi as a web-server.
I've edited domain's A record to point it to my server's IP.
Via letsencrypt I got myself a certificate and now website works on https protocol (keeping http on for debug purposes)
I'm working on a messenger app that uses socket.io but using apache+php for low level stuff
So basically apache listens to 80 and 443 and nodejs listens to 3000
Obviously if I visit my site over http - everything works fine and both server and client register connections.
If I visit it over https - Chrome throws net::ERR_CONNECTION_CLOSED error (in console when trying to connect to socket.io over port 3000. Site itself loads normally).
Client:
var socket = new io(window.location.host+":3000", { secure: true });
socket.on("connect", function() {
console.log('success')
});
Server:
const io = require("socket.io");
const server = io.listen(3000);
console.log("Server started");
server.on("connection", function (socket) {
console.log("+USER");
socket.emit("hello", "Connected");
});
I really don't want to use express or anything else for that matter to keep everything as small as possible, especially since I already have a web-server running.
How to properly set it up so users could connect to my socket.io server on port 3000 when they visit the site via https protocol?
Update:
From what it seems I think it's a CORS-thing type of a problem. User visiting website over https is trying to connect to an unsecured port (this case 3000) even though it's the same domain? I'd think that would be a no-no for a lot if not all browsers.
A solution comes to mind to just move the whole thing from apache to a nodejs server module and assign manually port 3000 as a secure one via https module but I've no idea how to do it, and I'd really want to keep my apache as a web-server because at least I'm more familiar with it than anything else.
Well I ended up creating a separate https server that I assume socket.io listens to (?)
Good thing I still have my apache as a main server. I partially answered my question using this post
https://serverfault.com/questions/745248/socket-io-combined-with-apache-ssl-server
Server
const fs = require("fs");
const https = require("https");
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/example.com/fullchain.pem')
};
var server = https.createServer(options);
server.listen(3000);
var io = require('socket.io').listen(server);
console.log("Server started");
io.on("connection", function (socket) {
console.log("+USER");
socket.emit("hello", "Connected");
socket.on("disconnect", () => {
console.log("-USER");
})
});
Client
var s = new io("https://example.com:3000", { secure: true } );
Hope this is the right way to do it

Socket.io + Azure web sockets issue

I am working on a multiplayer chess game with NodeJS and socket.IO.
I have problem hosting it on Azure tho.. I tried many different approaches, a few mentioned:
Forcing the application to only use WebSockets by adding the code below:
io.configure(function() {
io.set('transports', ['websocket']);
});
Added <webSocket enabled="false"/> in web.config file..
Note: This disables the IIS WebSockets module, which includes its own implementation of WebSockets and conflicts with Node.js specific WebSocket modules such as Socket.IO. If this line is not present, or is set to true, this may be the reason that the WebSocket transport is not working for your application.
Matching origin protocol to ensure no SSL issues.
io.configure(function() {
io.set('match origin protocol', true);
});
I now started from scratch, since I thought my server-side part was corrupt, and tried Socket.io chat example instead.
I followed the steps.
Created a new web app on Azure.
Published my files through FileZilla FTP.
Enabled Web Sockets on Azure for my app (disabled by default).
STILL THE SAME ERROR! See picture below.
Anyone? I am unsure if it's a client-side or server-side issue. It seems like it's trying to XHR-poll instead of using web sockets..
Thanks in advance.
I got it working, thank you Chris Anderson-MSFT for your help.
The weird thing that occurred for me when deploying with FTP was that my node_modules folder differed with version(s) specified in my package.json.
I solved this by connecting my web app on Azure to a local Git repository and deploying the app through git. This connects my packages recursively and matches correct versions.
I also needed to enforce my client-side socket-io to use web sockets by specifying transport method:
var socket = io({transports:['websocket']});
And this is what my server-side file ended up looking like:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 3000;
app.use(express.static('public'));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/default.html');
});
io.on('connection', function(socket) {
io.set('transports', ['websocket']);
console.log('new connection on socket.io');
socket.on('move', function(msg) {
socket.broadcast.emit('move', msg);
});
});
server.listen(port, function () {
console.log('Server listening at port %d', port);
});

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); });

Socket.IO on Heroku does NOT work without SSL

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.

Socket.io 0.7.9 connection issues

I am attempting to upgrade to socket.io 0.7.9 and have run in to problems.
I have used the basic example from the socket.io homepage. My server is:
var http = require('http'),
url = require('url'),
https = require('https'),
fs = require('fs'),
crypto = require('crypto'),
io = require('../'),
sys = require(process.binding('natives').util ? 'util' : 'sys'),
server = http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();
});
server.listen(80,"[MYIP]");
var io = io.listen(server), buffer=[];
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
It connects OK on some computers but not on others. It is the same across all browsers.
Does anyone know why this would happen? Could there be some local networking issue that causes this?
UPDATE
It appears that the people who are unable to connect from their computers are running anti virus with real time web shields that seem to block the connection. When they turn it off, it connects OK on some browsers...
I have been using socket.io and node.js for the last two months and some issues like yours happened to me too.
Firewalls are often a problem with the port 80, especially when used with a DNS (like in a corporate network) because they will temper with the headers of the socket packages. One work around could be to try another port.
My application has an apache server on the port 80 and my websocket is on the port 843, everything is working fine on Firefox and Chrome.
You can use the xhr-polling fallback option to bypass this type of errors by adding this script:
io.set('transports', ['websocket','xhr-polling']);
xhr-polling offers less real-time performance, but is really dependable and works on most browsers and network configurations.
I hope this will help you!

Resources