Impossible de créer de la croix-domaine de connexion websocket pour Node.js socket.io server

Selon mes recherches, cela ne devrait pas être si difficile que ça, et j'ai essayé beaucoup de choses avec pas de chance jusqu'à présent. J'ai un Node.js serveur en cours d'exécution sur Heroku qui crée une socket.io serveur (j'ai aussi essayé d'hébergement sur Nodejitsu, ce qui n'aide pas). Le socket.io socket de connexion fonctionne sans problèmes si je me servir de la page de l'Node.js le serveur que je veux créer une connexion websocket, mais je ne peux pas le faire tout de mon cross-domain tentatives de connexion de socket travail.

J'ai essayé de faire un cross-domain se connecter à cette prise.io serveur de plusieurs façons:

(1) Un simple fichier HTML local avec un script qui récupère côté client socket.io bibliothèque avec succès à partir du nœud de serveur (à l'aide de $.getScript), puis tente de créer une connexion de socket (var socket = io.connect('nodejs_server_hostname:port_num');), qui échoue.

(2) rails de roulement application serveur en local (mode de développement) qui sert de réponse aux clients contenant du javascript qui essaie de former une connexion websocket de la même manière que la méthode (1), et ne parvient pas

(3) l'Hébergement d'application rails en Heroku, et de faire la même chose que la méthode (2). Cela échoue. J'ai fait en sorte d'activer les websockets, comme spécifié dans le Heroku documentation (https://devcenter.heroku.com/articles/heroku-labs-websockets). Encore une fois, tout fonctionne si la demande est servi de l'Node.js serveur que le client tente de former un support.io connexion avec.

La prise.socket.("erreur"), l'événement est déclenché dans tous les trois tentatives.

J'ai essayé de modifier les en-têtes de réponse http dans l'application rails en utilisant le code suivant:

response.headers['Access-Control-Allow-Origin'] = '*'

Ce définit les en-têtes correctement (j'ai vérifié après la demande de page à partir du serveur rails), mais il ne résout pas la connexion de socket problème.

J'ai créé un socket-io autorisation de rappel sur la Node.js serveur qui effectue la journalisation, et il semble que ce rappel n'est jamais de la même frapper à la croix-domaine de tentatives de connexion de socket. Donc il semble que la Node.js le serveur n'a même jamais voit le websocket tentative de connexion, ce qui est assez confus pour moi.

Ci-dessous je vais coller tous les fichiers de code.

Node.js serveur de fichiers:

var http = require('http'),
express = require('express'),
whiskers = require('whiskers'),
redis = require('redis'),
port = process.env.PORT || 5000,
app = express(),
server = http.createServer(app).listen(port),
io = require('socket.io').listen(server);
console.log('---- ' + port);
console.log(port);
console.log('---- ' + port);
io.configure(function () {    
io.set('authorization', function (handshakeData, callback) {
console.log("-- inside io.set('authorization, cb)")
console.log('-- handshakeData:');
console.log(handshakeData);
console.log('-- end of handshakeData logging --');
callback(null, true); //error first callback style 
});
});
app.configure(function() {
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view options', { layout: false });
app.engine('.html', whiskers.__express);
});
app.get('/', function(req, res) {
res.render('index.html');
});
io.sockets.on('connection', function(socket) {
console.log('---- new client connected ----');
console.log(socket);
console.log('---- end of socket details logging for new client connection ----');
socket.emit('news', { hello: 'world' });
socket.on('my other event', function(data) {
console.log("-- server -- inside socket.on 'my other event' callback");
console.log(data);
});
socket.on('button clicked', function(data) {
console.log("-- server -- inside socket.on 'button clicked' callback");
console.log(data);
io.sockets.emit('news', { info: 'the button was clicked' });
});
});

Ici, c'est le javascript côté client fichier à partir de l'application Rails:

$(document).ready(function() {
console.log('-- inside chat.js -- document is ready');
$('#join-chat-container').hide();
$('#new-message-container').hide();
//$.getScript('http://node-server-for-rails-chat.herokuapp.com/socket.io/socket.io.js')
$.getScript('http://node-server-for-rails-chat.jit.su/socket.io/socket.io.js')
.done(function( script, textStatus ) {
console.log("-- socket.io.js loaded and executed -- textStatus: " + textStatus);
setup_socket();
})
.fail(function( jqxhr, settings, exception ) {
console.log("-- socket.io.js load error -- exception:");
console.log(exception);
console.log("-- jqxhr: " + jqxhr);
});
});
function setup_socket() {
//var socket = io.connect('node-server-for-rails-chat.herokuapp.com', { port: 19364 });
//var socket = io.connect('node-server-for-rails-chat.jit.su', { port: 5000 });
var socket = io.connect('node-server-for-rails-chat.herokuapp.com:27305');
socket.socket.on('error', function (reason) {
console.log('--- cant connect');
console.log(reason);
console.error('Unable to connect Socket.IO', reason);
});
socket.on('connect_failed', function() {
console.log('connect failed');
});
socket.on('connect', function() {
console.log('successfully connected!');
});
socket.on('message', function (message_html) {
console.log("-- client -- inside socket.on('message', cb) callback");
console.log("-- client -- message_html: " + message_html);
add_message(message_html);
});
if (!socket.socket.connected) {
console.log(socket);
console.log("-- Error connecting with socket");
}
socket_loaded(socket);
};
function socket_loaded(socket) {
//this part contains irrelevant (not socket related) code
}
//more irrelevant code excluded for brevity (add_message function, plus other stuff)

C'est le stand-alone fichier HTML, j'ai ouvert en local dans le navigateur:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-git.js"></script>
<script>
$(document).ready(function() {
if (typeof jQuery !==  'undefined') {
console.log('-- client -- jQuery library loaded successfully');
$('#myButton').on('click', function() {
console.log("-- client -- inside jquery '#myButton' click callback");
socket.emit('button clicked', { button: '#myButton' });
});
}
$.getScript('http://node-server-for-rails-chat.herokuapp.com/socket.io/socket.io.js')
.done(function( script, textStatus ) {
console.log("-- socket.io.js loaded and executed -- textStatus: " + textStatus);
socket_is_loaded();
})
.fail(function( jqxhr, settings, exception ) {
console.log("-- socket.io.js load error -- exception:");
console.log(exception);
console.log("-- jqxhr: " + jqxhr);
});
});
function socket_is_loaded() {
//var socket = io.connect('node-server-for-rails-chat.jit.su:5000');
var socket = io.connect('node-server-for-rails-chat.herokuapp.com:27305');
socket.socket.on('error', function (reason) {
console.log('--- cant connect');
console.log(reason);
console.error('Unable to connect Socket.IO', reason);
});
socket.on('connect_failed', function() {
console.log('connect failed');
});
socket.on('connect', function() {
console.log('successfully connected!');
});
socket.on('news', function(data) {
console.log("-- client -- inside socket.on 'news' callback");
console.log(data);
//socket.emit('my other event', { my: 'data' });
});
}
</script>
</head>
<body>
<h1>Socket.io How-to-use Example Script</h1>
<input type='button' id='myButton' value='click me!'/>
</body>
</html>

Quelqu'un a des idées sur comment je peux résoudre ce problème? Merci un tas.

OriginalL'auteur Daniel Waltrip | 2013-11-20