Cloudfoundry上的非http TCP连接

时间:2013-04-21 20:10:54

标签: node.js tcp cloud cloudfoundry

我是一个不起眼的移动开发者,试图利用cloudfoundry的服务运行我的服务器来处理一些聊天和角色动作。 我正在使用Noobhub实现此目的(使用Node.js和Corona SDK的TCP连接API在服务器和客户端之间建立TCP连接)

所以基本上我正在尝试Cloudfoundry(Node.js)和我的机器(lua)之间的非http TCP连接。

Link to Noobhub(There is a github repo with server AND client side implementation.

我在做

客户端

...
socket.connect("myappname.cloudfoundry.com", 45234)
...

(45234来自服务器的process.env.VCAP_APP_PORT值,我从运行应用程序后通过“vmc logs myappname”获得的控制台输出中检索到。)

服务器

...
server.listen(process.env.VCAP_APP_PORT)

当我尝试连接时,它只是超时。

在我的本地机器上,做 客户端

...
socket.connect("localhost",8989)

服务器

...
server.listen(8989)

按预期工作。它只是在云计算上它不起作用。

我尝试了其他一些方法,例如将客户端的端口连接设置为80以及其他一些端口连接。我看到了一些资源,但没有人解决它。 我经常吹嘘提问,所以如果你需要更多信息,请问我!

P.S。

在你带着愤怒的脸D向我扔这个链接之前:< ,这是一个问题,显示了另一个人发布的类似问题。

cannot connect to TCP server on CloudFoundry (localhost node.js works fine)

从这里,我可以看到这家伙正在尝试做我正在做的类似事情。 所选答案是否意味着我必须使用主机头(即使用http协议)来连接?这是否也意味着cloudfoundry不会像heroku或app fog一样支持“TRUE”TCP套接字?

2 个答案:

答案 0 :(得分:4)

实际上,process.env.VCAP_APP_PORT环境变量为您提供了端口,Cloud Foundry L7路由器(nginx)根据您的应用程序路由将您的HTTP流量重定向到该端口(例如,nodejsapp.vcap.me:80被重定向到到虚拟机上的process.env.VCAP_APP_PORT端口,所以你绝对不应该将它用于TCP连接。此端口应用于侦听HTTP流量。这就是为什么您的示例在本地工作而不在Cloud Foundry上工作的原因。

对我有用的方法是使用HTTP服务器监听CF提供的端口,然后将Websocket服务器(下面的示例中的websocket.io)附加到它。我创建了样本回显服务器,它既可以在本地也可以在CF中使用。名为example.js的Node.js文件的内容为

var host = process.env.VCAP_APP_HOST || "localhost";
var port = process.env.VCAP_APP_PORT || 1245;

var webServerApp = require("http").createServer(webServerHandler);  
var websocket = require("websocket.io");
var http = webServerApp.listen(port, host);
var webSocketServer = websocket.attach(http);

function webServerHandler (req, res) {
    res.writeHead(200);
    res.end("Node.js websockets.");
}
console.log("Web server running at " + host + ":" + port);

//Web Socket part
webSocketServer.on("connection", function (socket) {
    console.log("Connection established."); 

    socket.send("Hi from webSocketServer on connect");

    socket.on("message", function (message) { 
        console.log("Message to echo: " + message);
        //Echo back
        socket.send(message);
    });

    socket.on("error", function(error){
        console.log("Error: " + error);
    });

    socket.on("close", function () { console.log("Connection closed."); });
});

依赖库lib websocket.io可以在同一目录中运行npm install websocket.io命令。还有一个manifest.yml文件描述了CF部署参数:

---
applications:
- name: websocket
  command: node example.js
  memory: 128M
  instances: 1
  host: websocket
  domain: vcap.me
  path: .

因此,从此目录运行cf push将app部署到我的本地CFv2实例(在cf_nise_installer的帮助下设置) 为了测试这个echo websocket服务器,我使用了简单的index.html文件,它连接到服务器并发送消息(所有内容都记录在控制台中):

<!DOCTYPE html>
    <head>
        <script>        
        var socket = null;
        var pingData = 1;
        var prefix = "ws://";

        function connect(){
            socket = new WebSocket(prefix + document.getElementById("websocket_url").value);
            socket.onopen = function() { 
                console.log("Connection established"); 
            };
            socket.onclose = function(event) { 
                if (event.wasClean) {
                    console.log("Connection closed clean");
                } else {
                    console.log("Connection aborted (e.g. server process killed)");
                }
                    console.log("Code: " + event.code + " reason: " + event.reason);
                };             
            socket.onmessage = function(event) { 
                console.log("Data received:  " + event.data);
            };
            socket.onerror = function(error) { 
                console.log("Error: " + error.message);               
            };
        }        
        function ping(){
            if( !socket || (socket.readyState != WebSocket.OPEN)){
                console.log("Websocket connection not establihed");
                return;
            }            
            socket.send(pingData++);
        }        
        </script>
    </head>
    <body>
        ws://<input id="websocket_url">
        <button onclick="connect()">connect</button>
        <button onclick="ping()">ping</button>
    </body>
</html>

唯一要做的就是在Index页面的文本框中输入服务器地址(在我的情况下为websocket.vcap.me),按“连接”按钮,我们通过TCP进行Websocket连接,可以进行测试通过发送Ping和接收回声。这在Chrome中运行良好,但IE 10和Firefox存在一些问题。

“TRUE”TCP套接字怎么样,没有确切的信息:根据最后一段here,您不能使用除80和443(HTTP和HTTPS)之外的任何端口与云外部的应用程序进行通信Foundry,这让我觉得TCP套接字无法实现。但是,根据this回答,您实际上可以使用任何其他端口......似乎需要对此​​问题进行一些深入调查......

答案 1 :(得分:-2)

“Cloud Foundry在客户端和应用程序之间使用L7路由器(ngnix)。路由器需要解析HTTP才能将请求路由到应用程序。这种方法不适用于非HTTP协议,如WebSockets。运行node.js的人员将会遇到这个问题,但目前的Cloud Foundry架构中没有简单的解决方案。“   - http://www.subbu.org/blog/2012/03/my-gripes-with-cloud-foundry

我决定使用pubnub来满足我所有的消息需求。