【问题标题】:Connect to Socket.io server from a Rails server从 Rails 服务器连接到 Socket.io 服务器
【发布时间】:2013-01-30 01:08:24
【问题描述】:

[更新 1] 我发现io.connect('http://xxxxx.herokuapp.com') 实际上在 xxxxx.herokuapp.com 端口 3000 上发送了一个请求: 如果请求没有端口号,则连接有效。我没有在 io.connect 中指定端口,我该如何摆脱它?

  Request URL:http://xxxxx.herokuapp.com:3000/socket.io/1/?t=1360853265439
  Request Headersview source
  Cache-Control:max-age=0
  Origin:http://localhost:3000
  Referer:http://localhost:3000/about
  User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like      Gecko) Chrome/24.0.1312.57 Safari/537.17
  Query String Parametersview sourceview URL encoded
  t:1360853265439

[更新 2] 比较这里是当我从本地文件系统运行 java 脚本时成功连接的 HEAD

 Request URL:http://xxxxx.herokuapp.com/socket.io/1/?t=1360854705943
 Request Method:GET
 Status Code:200 OK
 Request Headersview source
 Accept:*/*
 Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
 Accept-Encoding:gzip,deflate,sdch
 Accept-Language:en-US,en;q=0.8
 Cache-Control:max-age=0
 Connection:keep-alive
 Host :xxxxx.herokuapp.com
 Origin:null
 User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like      Gecko) Chrome/24.0.1312.57 Safari/537.17

[更新 3] 将端口设置为 80 似乎可以正常工作

    var socket = io.connect('http://xxxxx.herokuapp.com',{port:80});

[问题] 我打算在一台主机上设置 socket.io 以与另一台主机上的 Rails 应用程序通信。当客户端 Javascript 托管在 localhost:3000 以连接到托管在 localhost:5000 上的 node.js 服务器上的 Socket.io 时,一切正常。当客户端 Javascript 和 Socket.io 都托管在 Heroku 上的同一端口上时,它也能正常工作。

socket_server.js 托管在 XXXX.herokuapp.com 上

               var app = require('http').createServer(handler)
              , io = require('socket.io').listen(app)
              , fs = require('fs')
              , i = 0


            io.configure(function () {
              io.set("origin = *");
              io.set("transports", ["xhr-polling"]);
              io.set("polling duration", 100);
            });

            var port = process.env.PORT || 5000; // Use the port that Heroku provides or default to 5000
            app.listen(port, function() {
              console.log(">>>>>>socket server up and running on port: "+port);
            });


            function handler (req, res) {
              fs.readFile(__dirname + '/socket.html',
              function (err, data) {
                if (err) {
                  res.writeHead(500);
                  return res.end('Error loading socket.html');
                }

                res.writeHead(200);
                res.end(data);
              });
            }

            io.sockets.on('connection', function (socket) {
                console.log(">>>>>>client connected through socket");
              socket.emit('news', '>>>>>>server say hello to client', i);
              console.log('>>>>>>server say hello to client' +'['+i+']')
              socket.on('my other event', function (data) {
                socket.emit('news', i);
                i++;
                console.log(data +'['+i+']');
              });
            });

如果我将客户端 javascript 放在 XXXX.herokuapp.com 上的 socket.html 中,与 socket.io 相同,它的行为与预期相同。

                    <div id='sandbox'>sandbox</div>

        <script src="/socket.io/socket.io.js"></script>

        <script>

          var socket = io.connect('window.location.hostname');
          $('#sandbox').append('<div> lora </div>');
          socket.on('news', function (data, index) {
            $('#sandbox').append('<div>' + data + ' ' + index + '</div>');
            console.log(data);
            socket.emit('my other event', { my: 'data' });
          });
        </script>

但是,如果我将客户端 Javascript 放在 YYYY.herokuapp.com 上的 Rails 服务器上并尝试连接到 xxx.herokuapp.com 上的 Socket.io 服务器,它就不起作用。它设法在服务器上检索 socket.io.js 但 io.connect('http://xxxxx.herokuapp.com') 没有得到服务器的任何响应。

                    <div id='sandbox'>sandbox</div>

        <script src="http://xxxxx.herokuapp.com/socket.io/socket.io.js"></script>

        <script>

          var socket = io.connect('http://xxxxx.herokuapp.com');
          $('#sandbox').append('<div> lora </div>');
          socket.on('news', function (data, index) {
            $('#sandbox').append('<div>' + data + ' ' + index + '</div>');
            console.log(data);
            socket.emit('my other event', { my: 'data' });
          });
        </script>

我阅读了一些帖子点设置 io.set("origins = *") 的解决方案,但这似乎在这种情况下也不起作用。

【问题讨论】:

    标签: ruby-on-rails node.js heroku socket.io


    【解决方案1】:

    在 socket.io 中,Origins 默认设置为*。它会是io.set("origin", "*");,但由于这是默认值,你可以忽略这个函数。

    我确实注意到您的客户端代码中也有 var socket = io.connect('window.location.hostname'),您可能会提到:var socket = io.connect(window.location.hostname) 没有单引号。 heroku 文档确实建议使用 io.set("polling duration", 100); 但您将其设置为 100 而不是建议的 10。否则我认为您的代码没有任何问题,它应该可以正常工作。

    如果这些修复没有帮助,那么我会将其归咎于您的托管。在部署实时应用程序时,Heroku 是一个非常严格的平台。所以可能是他们在这里搞砸了。我建议尝试在其他地方部署,例如在 nodejitsu.com 上,它也支持 WebSockets,并且不会对轮询施加任何限制,以查看它是否适合您。

    【讨论】:

    • 我尝试在 Nodejisui 上托管 socket.io 并将我的 javascript on rails 应用程序指向 xxx.jit.su var socket = io.connect('xxxxx.jit.su');但还是有同样的问题
    • 它似乎与域有关,而不是托管。即 localhost:3000 上的 [工作] 客户端 js localhost:5000 上的 socket.io。 [工作] xxx.herokuapp.com 上的客户端 js xxx.herokuapp.com 上的 socket.io [故障] localhost:4000 上的客户端 js xxx.herokuapp.com 上的 socket.io
    • 这里有人问过类似的问题:stackoverflow.com/questions/12439852/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 2014-09-12
    • 2018-10-06
    • 2023-03-23
    • 2011-06-11
    • 1970-01-01
    相关资源
    最近更新 更多