Socket.io Cross-domain connections fail; 'XMLHttpRequest cannot load ...' - node.js

I'm trying to do cross-domain socket.io, but I'm experiencing an issue:
I always get XMLHttpRequest cannot load http://handsonwithnodejs.samarthwiz.c9.io/socket.io/1/?t=1358882710333. Origin https://c9.io is not allowed by Access-Control-Allow-Origin.
Server code:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(process.env.PORT);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.set('origins', '*:*');
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
On line 19 io.set('origins', '*:*');I tried replacing ':' with '*', 'https://c9.io', 'c9.io','https://c9.io/' and '.', some times when I add something like 'c9.io/'
I get warn 'illegal origin ...' but that is just a cloud9 related issue.
Client code:
<html>
<body>
<script src="https://raw.github.com/LearnBoost/socket.io-client/master/dist/socket.io.js"></script>
<script>
var socket = io.connect('http://handsonwithnodejs.samarthwiz.c9.io');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</body>
</html>
I know that using github to get my script isn't the best idea yet, but I wanted to keep my code clean and the error messages readable(everything in 'socket.io.min.js' is on line 2)
P.S. 1. I know that there are other threads like this but they didn't solve my problem.
2. Please don't reply 'Just host the page on the same server as socket.io' I need it to be cross-domain for a reason.

I think you need to set the Access-Control-Allow-Origin header when you host the client code. Look at https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS for more info about the header.
This header must be set by the client for security reasons.

Related

Socket.io fails sending to client on some computers

Using the following simple application of socket.io, I get very strange behaviour, but only on some computers I tested. On most computers, it seems to work fine. This is the setup I used:
server.js:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
i = 0;
setInterval(function() {
socket.emit('news', 'test');
}, 200);
socket.on('my other event', function (data) {
console.log(data);
});
});
index.html:
<html>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
socket.on('news', function (data) {;
console.log("test");
socket.emit('my other event', { my: 'data' });
});
</script>
</html>
<body></body>
If I set the interval on 30 instead of 200 milliseconds, it seems to work well (i.e. the client and server both receive the socket messages on time), but when I set the interval on 100 or more milliseconds, the client does not respond to the first 13 (consequently 13) messages sent by the server and then suddenly receives all 13 messages at once, directly followed by this error:
"WebSocket connection to 'ws://example.com/socket.io/1/websocket/63zOWQ5mEuzV01WuqZ5X' failed: Unrecognized frame opcode: 11".
This behaviour repeats for some time, so sets of 13 messages are suddenly received followed by the error, but sometimes, after a random amount of error sets, it starts behaving normally again. I know this sounds really weird, but I can't find the source of this problem and it greatly affects the user experience. What could trigger this problem?
I am using node.js version 0.8.24, socket.io 0.9.14 and chrome version 31.0.1650.63 m. I am running on CentOS version 6.5. This behaviour also happens on IE 10 with a different error: "SCRIPT12152: WebSocket Error: Network Error 12152"

Node.js Socket.io wrong path

I'm experimenting this issue at game.html
GET http://localhost/socket.io/socket.io.js 404 (Not Found) game.html:1
Uncaught ReferenceError: io is not defined game.html:3
My game.html file
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost/game.html');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
And my server.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(5667);
function handler (req, res) {
fs.readFile(__dirname + '/game.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
});
It was working fine when I was using index.html instead of game.html
It looks like you're not retrieving game.html from the Node app, because the socket.io.js file seems to be retrieved from an HTTP port running on port 80 whereas your Node app is running on port 5667.
Also, your client-side connection string is incorrect:
var socket = io.connect('http://localhost/game.html');
That also tries to contact a server on port 80 (and I don't know what game.html is doing there).
So try this:
change the client-side connection string to var socket = io.connect();
start your Node app
open http://localhost:5667/ in your browser
And see if that works better.

Node.js and socket.io don't work on Cloud9 IDE

Does anyone has experience to have Node.js and socket.io working on Cloud9 IDE?
The "Example (NodeJS with Socket.io)" (at https://c9.io/site/blog/2013/05/native-websockets-support/) doesn't work.
First, the server (https://c9.io/etlolap/webapp, /test.js) throws an error unless I fix as follow. I clicked Run button while test.js is on active tab.
var
socketIo = require('socket.io'),
io = socketIo.listen(Number(process.env.PORT));
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Then, my client (https://c9.io/etlolap/webapp, /test.html) still cannot connect. I clicked Preview button while test.html is on active tab.
<!doctype html>
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('https://webapp-c9-etlolap.c9.io');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</head>
<body>
Loading...
</body>
</html>
and got error message below.
Failed to load resource: the server responded with a status of 404 --- (Not Found) https://c9.io/socket.io/socket.io.js
Uncaught ReferenceError: io is not defined --- test.html:6
1. Steps
1.1) Run server.js
The cloud 9 console shows up:
1.2) Hit Preview on index.html
1.3) Then a window is opening on the right side of your IDE. You can either hit the button in the middle of the navigation bar or copy and paste the url into a new browser window.
1.4) Socket communication is working!
2. Prerequisite
2.1) node module socket.io
Hit F6 or View -> Console and install socket.io.
2.2) the client side JavaScript from socket.io
Since I didn't find an official link to download it, I created a GitHubGist.
socket.io.js
3. Code
server.js
// module dependencies
var http = require("http"),
sio = require("socket.io");
// create http server
var server = http.createServer().listen(process.env.PORT, process.env.IP),
// create socket server
io = sio.listen(server);
// set socket.io debugging
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
socket.emit('news', { message: 'Hello world!' });
socket.on('my other event', function (data) {
console.log(data.message);
});
});
index.html
<!DOCTYPE html>
<html>
<script src="js/socket.io.js"></script>
<script>
var socket = io.connect("https://demo-project-c9-matthiasholdorf.c9.io");
socket.on("news", function(data) {
console.log(data.message);
});
socket.emit("my other event", { message : "client emit" } );
</script>
</html>
Thanks for feedback from damphat and Matthias. After many failed attempts, finally I figured out the solution myself.
On Cloud9 IDE, the typical line in client (test.html here) has to be changed from,
<script src="/socket.io/socket.io.js"></script>
to
<script src="https://webapp-c9-etlolap.c9.io/socket.io/socket.io.js"></script>
The prefix is the URL of your Cloud9 project URL. By changing this line, my example worked.
you must flowing these step:
open the terminal on https://c9.io/etlolap/webapp, type:
npm install socket.io
node test
then open a new tab of browser with url
https://webapp-c9-etlolap.c9.io/socket.io/socket.io.js
You will see socket.io.js source code
I did not how you open test.html in c9.io without http server, did you just press preview?
Edit:
To return html files, you should merge http server and socket.io server like this:
// file: test.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen( Number( process.env.PORT ) );
function handler (req, res) {
fs.readFile(__dirname + '/test.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
To fetch any html file requested, using html files located in the file folder, you can use express:
var fs = require('fs');
var express = require('express');
var app = express();
// This fetches html files from the client folder (if they exist), and returns a "Page could not be found" error otherwise (this can be customized to some other 404 error page as desired)
app.get('*', function (req, res) {
var urlReading = req.url;
if (urlReading == "/")
{
urlReading = "/index.html";
}
urlReading = __dirname + "/client" + urlReading;
console.log("Loading: " + urlReading);
fs.readFile(urlReading, function (err, html) {
if (err) {
console.log("Could not find " + urlReading)
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end("<html><head><title>Page could not be found</title></head><body><h1>Page could not be found</h1></body></html>");
}
else
{
console.log("Found " + urlReading)
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(html);
}
});
});
app.listen(process.env.PORT, process.env.IP);

Socket IO not working on other machine

I have simple socket io code
-- Server
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8080);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
-- Client
<script src="http://192.168.1.100:8080/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://192.168.1.100:8080');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
there is no problem if the client script run on the server machine , but in other machine rather than server there is no problem in getting socket io javascript file , the client send request to server and I can see that the request received by server , but the client do not receive anything and it try to switch transport after 20 sec , none of them work. But as soon as I close server , the client receive the message that sent from server before ...
I use ubunto 12.04 LTS and Google chrome 28 , please help me through this problem

socket.io example: not working

I am completely new to the socket.io and trying to get my feet wet by starting with examples on their home page. But all that i get in console after execution is this
debug - served static content /socket.io.js
My Server side code is this:
var app=require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(80);
function handler (req, res)
{
fs.readFile(__dirname + '/index.html', function (err, data)
{
if (err)
{
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
console.log("connected");
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
})
And my index.html goes like this:
var socket = io.connect('document.location.href');
socket.on('error',function(reason){
// console.error("Error");
});
socket.on('connect', function () {
console.log('connected');
socket.send('hi');
socket.on('message', function (msg) {
// my msg
});
});
</script>
I googled about it and couldn't resolve the issue. I am on ubuntu with firefox.
If i'm not mistaken your error is here:
'document.location.href'
which shall be
document.location.href
I've just complete a simple example app for which I'll be soon writing a tutorial:
https://github.com/dotcloud/socket.io-on-dotcloud
You can grab it (just clone it) and fool around with it to easy how to get started with socket.io with express 3. It is even ready to be push on dotCloud if you whish to share your app.

Resources