Another update:
The problem occurs when running on localhost as well. Since I figured out the problem comes from the proxy server, here's its code :
var serverBouncer = bouncy(function(req, res, bounce) {
var path = req.url;
var url = req.headers.host;
if (typeof url !== "string")
return;
var urlArray = url.split('.');
var bouncePort = port;
if (!isNaN(urlArray[0]))
bouncePort = parseInt(urlArray[0]);
else if (String(urlArray[0]).toLowerCase() === "www" && !isNaN(urlArray[1]))
bouncePort = parseInt(urlArray[1]);
bounce(bouncePort);
});
serverBouncer.listen(80);
Update:
I found where the problem came from!!! But I still need to find the solution... There seems to be issues with using newer versions of Socket.io (>= 1.0) with a proxy server (bouncy, in my case).
I recently updated Socket.IO from v0.9.16 to v1.4.5, as well as adding Express to the mix. However, now I cannot open multiple (number seems to vary) tabs in Chrome and Firefox without experiencing strange issues (Edge is the only one to work well). It either hangs, or partially loads html and other resources before it hangs.
After waiting, I often get the error :
Failed to load resource: the server responded with a status of 400 (Bad Request)
When I close one of the tab that's been hanging, it unblocks the other tabs that were also hanging.
The issues were not present before going through with the changes listed above.
I've been doing research for 2 full days and just now decided to post this, as I know it's very vague and I'm probably not providing enough information. As much as I'd like to, it would take a very long time to remember and list everything I tried during that time.
Using Windows 10 with Chrome v51.0.2704.103, Firefox v43.0.1. The server (CentOS) is using node v6.2.2 with mainly the following modules :
express#4.14.0
npm#3.9.5
socket.io#1.4.5
Here's some relevant server code :
var port = 8502;
var socketio = require('socket.io');
var express = require("express");
var http = require('http');
var app = express();
var server = http.createServer(app);
var io = socketio.listen(server);
server.listen(port);
app.get('/', function(req, res, next) {
//Returning index.html
});
io.on("connection", function(socket) {
//Some events...
});
Here's a bit of the client code :
var client = io.connect();
client.on('connect', function() {
//Some events
})
your binding before the server is listening, try something like this
var app = express();
server = app.listen(PORT, function () {
console.log('Example app listening on port ' + PORT + '!');
});
io.listen(server);
I managed to replace the bouncy module with nginx. See my other question for the solution.
nginx : redirect to port according to domain prefix (dynamically)
Related
I am using Socket.io in my NodeJS backend. However, the sockets do not work. For example, one should receive a link and then send them to all other rooms under the same code, but the code is not executing. In my heroku logs I receive no errors but when I inspect element the page I get
polling-xhr.js:268 GET https://localhost:5000/socket.io/?EIO=3&transport=polling&t=NDADDNH net::ERR_CONNECTION_REFUSED
and
Failed to load resource: net::ERR_CONNECTION_REFUSED
I have looked into similar problems from this forum and made several changes but none of them have solved the issue. Also a bunch of the posts answer with solutions for ws in general which I don't understand at all :/
From what I read the issue might be with my ports? I followed a few of them but the same errors still occured.
Socket.io:
/***BACKEND***/
const express = require('express');
const path = require('path');
const app = express();
let rooms = [];
/***SERVER***/
const port = process.env.PORT || 5000;
server = app.listen(port, function(){
console.log('App is listening on port ' + port)
});
/***SOCKET.IO***/
const socket = require('socket.io');
io = socket(server);
io.on('connection', (socket) => {
//bunch of functionality
}
and then in my client I am using
this.socket = io('localhost:5000');
//one of the functions
this.syncQueue = () => {
this.socket.emit('SYNC_QUEUE', {
activeRoom: this.props.getRoom()
});
}
this.socket.on('RECEIVE_QUEUE', newQueue => {
props.onAddToQueue(newQueue);
});
FYI Everything works on localhost
Localhost will not work on the server and if you are using default namespace you no need to specify the URL. So try this, this.socket = io()
On the client side, you're trying to connect to localhost:5000 instead of the URL Heroku provides. Try this this.socket = io('heroku url goes here').
I'm trying to add instant messaging to an existing app. But I'm not sure how should configure socket.io module.
I've already tried the following:
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const config = require('./config/config.js');
var expressConfig = require('./config/express.js').front,
models = require('./app/models'),
passConfig = require('./config/passport-front.js');
const app = expressConfig();
const passport = passConfig();
app.set('port', config.frontPort);
const http = require('http').Server(app);
const io = require('socket.io')(http);
io.on('connection', function (socket) {
console.log('Connected');
});
models.sequelize.sync().then(function () {
var server = http.listen(app.get('port'), function () {
console.log('Express server listening on port ' + server.address().port);
});
});
module.exports = http;
Since connected is not being logged when I open a page I'm assuming something is missing. Where is my mistake?
You didn't show your client-side code so it's hard to tell you what's wrong. Do you get any error in the browser? What is the network traffic on the browser? Without that it's hard to tell anything specific.
Take a look at this answer:
Getting data from/writing data to localhost with Express and Socket.io
It has a working example of something similar to what you're trying to do.
In general - remember that you need to include the socket.io client-side code in the browser:
<script src="/socket.io/socket.io.js"></script>
and then you need to connect with io() with something like:
var s = io();
s.on('color', function (color) {
document.body.style.backgroundColor = color;
});
The 'color' here is just an example that comes from this project on GitHub:
https://github.com/rsp/node-live-color
It's an example of a website that changes colors selected in messages that come vie socket.io.
I am trying to set up a simple websocket server that communicates between a Flash AS3 client and a Node.js backend. The following code is when both the client and server are hosted locally. The code also functions properly when the swf is hosted locally connected to the server hosted on heroku. The socket only fails when both the swf and the server are hosted online.
Node.js Code (Server)
var WebSocketServer = require("ws").Server
var net = require('net');
var http = require("http")
var express = require("express")
var app = express()
var crossdomain = require('crossdomain')
var port = process.env.PORT || 5000;
app.use(express.static(__dirname + "/"))
var xml = crossdomain({ domain: '*' });
app.all('/crossdomain.xml', function (req, res, next) {
res.writeHead(200, { 'Content-Type': 'application/xml; charset=utf-8' });
res.write(xml);
//res.write(new Buffer([0x00]))
res.end();
});
var server1 = http.createServer(app)
server1.listen(port)
console.log("http server listening on " + port)
var wss = new WebSocketServer({server: server1})
wss.on("connection", function(ws) {
console.log("Connected");
ws.on("close", function() {
console.log("websocket connection close")
})
})
Crossdomain file - example.com/crossdomain.xml
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" secure="false"/>
</cross-domain-policy>
AS3 Code (Client) - I'm Using (https://github.com/theturtle32/AS3WebSocket)
import com.worlize.websocket.*;
Security.loadPolicyFile("http://example.com/crossdomain.xml");
var websocket:WebSocket = new WebSocket("ws://example.com", "*", "echo-protocol");
websocket.addEventListener(WebSocketEvent.OPEN, handleWebSocketOpen);
websocket.connect();
var con = false;
function handleWebSocketOpen(event:WebSocketEvent):void {
trace(event);
}
When the client is accessed from the server a request for the crossdomain.xml does occur and it gets returned successfully to the client, but at that point nothing happens anymore. I've been trying to solve this for ages with no luck. I did find that when you return the crossdomain file you need to end it with a 0x00 for it to be properly read, but I haven't found a way to make to that work. I've tried adding res.write(new Buffer([0x00])) to the response from the crossdomain request as well as several other modifications to no avail. These all seem to stop the xml file from being valid anyway.
I would greatly appreciate if anyone could help in getting this to work, I've been struggling with it for an extremely long time and can't quite seem to get this last step working.
There seems to be some incompatibilities between Socket.IO and Bouncy : in Chrome and Firefox (not in Edge), my browser tabs hang when I open more than 5.
I know it's caused by the NPM module "Bouncy" because if I remove the code that uses it, everything works fine and there's no limit to how many browser tabs I can open. The other culprit is the new version of Socket.IO (>= 1.0, which I just updated to), because when I downgrade back to v0.9.16 the problem goes away as well.
Here's some relevant server code :
var port = 8502;
var bouncy = require('bouncy');
var socketio = require('socket.io');
var express = require("express");
var http = require('http');
var app = express();
var server = http.createServer(app);
var io = socketio.listen(server);
server.listen(port);
var serverBouncer = bouncy(function(req, res, bounce) {
var path = req.url;
var url = req.headers.host;
if (typeof url !== "string") {
res.send(500);
res.end();
return;
}
var urlArray = url.split('.');
var bouncePort = port;
if (!isNaN(urlArray[0]))
bouncePort = parseInt(urlArray[0]);
else if (String(urlArray[0]).toLowerCase() === "www" && !isNaN(urlArray[1]))
bouncePort = parseInt(urlArray[1]);
bounce(bouncePort);
});
serverBouncer.listen(80);
io.on("connection", function(socket) {
//Some events...
});
Here's some relevant client code :
var client = io.connect();
I have been stuck trying to solve this problem for the past 3 days, any help is immensely appreciated.
Update:
Here's what the network tab of chrome dev tools looks like :
Update 2:
I changed the config of socket.io (server side) to force websocket :
io.set('transports', ['websocket', 'polling']);
Same for the client side :
var client = io({transports: ['websocket', 'polling']});
But now the events I emit don't reach the server. Here's what the network tab looks like :
Update 3:
Versions of the main components :
NodeJS v6.2.2
Socket.IO v1.4.8
Bouncy v3.2.2
Cors v2.7.1
Express v4.14.0
Npm v3.10.5
I managed to replace the bouncy module with nginx. See my other question for the solution.
nginx : redirect to port according to domain prefix (dynamically)
I'm actually working on a little project, where i'm supposed to recreate a drawing multiplayer game with node.js, mongoDB, socket.io and canvas.
The drawer is working like a charm, and the server seems to work well too. I got my register/login/sessions and database up and working, the only problem is socket.io. When an user is joining the game room, he can see the drawer and tools, but no connection. Why ? The browser can't find socket.io.js.
What I did :
I verified if it was installed, it is with npm install socket.io.
I checked if the server was starting it when turning the server on : Got "socket.io started" in my console.
I checked my HTML code, here it is :
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
According to the billions of tutorials/dev sites/help subjects, this is supposed to work. But it's not. When opening the console of my browser, I got this :
X GET http://localhost:1337/socket.io/socket.io.js NOT FOUND.
I don't know where is the problem, I can't figure this out and it's giving me a huge headache.. So I'm here.
Thanks in advance for helping ! :)
Given the code in your comment, you're not using the correct variable for initializing socket.io.
Try this:
var express = require('express');
var app = express();
var server = app.listen(1337);
var io = require('socket.io').listen(server);
...
So instead of having socket.io 'listen' on the Express app instance, it should listen to what app.listen(...) returns (which happens to be an http.Server instance).
For anyone landing here because they're going through the v4.x socket.io get started example, all you need to do is add another endpoint to your index.js file
index.js
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
// add this
app.get('/socket.io/socket.io.js', (req, res) => {
res.sendFile(__dirname + '/node_modules/socket.io/client-dist/socket.io.js');
});
///
io.on('connection', (socket) => {
console.log('a user connected');
});
server.listen(3000, () => {
console.log('listening on *:3000');
});