【问题标题】:Non-http TCP connection on CloudfoundryCloudfoundry 上的非 http TCP 连接
【发布时间】:2013-04-14 16:20:32
【问题描述】:

我是一个 nooby 移动开发人员,试图利用 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)

按预期工作。它只是在cloudfoundry上不起作用。

我尝试了很多其他方法,例如将客户端的端口连接设置为 80 和其他一些方法。我看到了一些资源,但没有一个能解决它。 我通常会问问题,所以如果您需要更多信息,请问我!

附言

在你带着愤怒的脸 D:

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

从这里,我可以看到这个人正在尝试做我正在做的类似事情。 选择的答案是否意味着我必须使用主机标头(即使用 http 协议)进行连接?这是否也意味着 cloudfoundry 不会像 heroku 或应用程序雾那样支持“真正的”TCP 套接字?

【问题讨论】:

    标签: node.js tcp cloud cloud-foundry


    【解决方案1】:

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

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

    【讨论】:

    • 此信息现已过时。 Cloud Foundry v2 使用在 Go 中实现的新路由器,它同时支持 HTTP 和 WebSockets - 但是,它需要配置为支持 WebSockets,因此如果您依赖 Cloud Foundry 的托管版本,则需要确保主持人已启用此选项。
    【解决方案2】:

    实际上,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 中运行的示例回显服务器。我的 Node.js 文件名为 example.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."); });
    });
    

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

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

    所以,从这个目录运行 cf push 部署应用程序到我的本地 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)之外的任何端口从 Cloud Foundry 外部与您的应用程序通信,这让我觉得 TCP 套接字无法实现。但是,根据this的回答,你实际上可以使用任何其他端口...看来需要对这个问题进行一些深入的调查...

    【讨论】:

    • 您可以使用 HTTP(或可能的 WebSockets)通过侦听 POST / VCAP_APP_PORT 环境变量中反映的端口上的套接字与 Cloud Foundry 应用程序“对话”。您不能使用“任何”基于 TCP 的协议。
    • 您可以使用“任何”基于 TCP 的协议从托管在 Cloud Foundry 上的应用程序“输出”到任何其他平台。
    • 太棒了。但是 VCAP_APP_PORT 已被弃用;现在变量的名称是PORT。请参阅docs.run.pivotal.io/devguide/deploy-apps/… 处的通知
    猜你喜欢
    • 1970-01-01
    • 2015-07-26
    • 2013-03-04
    • 2019-08-06
    • 1970-01-01
    • 2021-02-18
    • 2013-02-18
    • 2021-05-26
    • 2010-12-01
    相关资源
    最近更新 更多