【问题标题】:BlueMix websocket - VCAP_APP_PORT error EADDRINUSEBlueMix websocket - VCAP_APP_PORT 错误 EADDRINUSE
【发布时间】:2015-12-22 02:46:28
【问题描述】:

我已经创建了一个 NodeJS websocket 服务器和客户端

服务器:

//handler server 
app.get('/server', function (req, res) {

  //test websocket
  console.log("server: starting websocket server...");

  var port = (process.env.PORT || 8888); 

  var WebSocketServer = require('ws').Server;

  wss = new WebSocketServer({port: port});
  wss.on('connection', function(ws) {
      ws.on('message', function(message) {
          console.log('server: received: %s', message);
          ws.send('echo: ' + message);
      });
      ws.send('connected');
  });

  console.log("server: listening  websocket on " + appEnv.url + " - port " + port );
  res.send('SERVER - listening websocket on: ' + appEnv.url + " port " + port);

});

客户

//handler client 
app.get('/client', function (req, res) {

    //var url = 'ws://localhost:8888';//local
    var url = 'ws://<appname>.mybluemix.net';//BlueMix

     var WebSocket = require('ws')     
          , ws = new WebSocket(url);

     console.log('client: calling url: %s', url);

     ws.on('open', function() {
         ws.send('hello');
     });
     ws.on('message', function(message) {
         console.log('client: received: %s', message);
     });

    res.send('CLIENT - WebSocket call done - check the log !!!');

});

我的期望是使用 BlueMix 上的 env VCAP_APP_PORT/PORT 提供的端口。但我得到服务器错误:听 EADDRINUSE。这是 NodeJS 运行时服务器使用的端口,这是合理的原因。

本地所有其他端口都可以工作(80/443/8888/5555/XXXX 等),但客户端调用必须在该端口上完成:

本地测试:

  • SERVER localhost:6007 - port 80 > OK -- CLIENT call ws://localhost > OK

  • SERVER localhost:6007 - 端口 433 > OK -- 客户端调用 ws://localhost:443 > OK

  • SERVER localhost:6007 - 端口 8888 > OK -- 客户端调用 ws://localhost:8888 > OK

  • SERVER localhost:6007 - 端口 5555 > OK -- 客户端调用 ws://localhost:5555 > OK

在 BlueMix 上使用 VCAP_APP_PORT 是不可能的,因为该端口是从 NodeJS 服务器使用的(错误 EADDRINUSE)。似乎不允许使用端口 80/443(错误 EACCES 权限被拒绝)。使用所有其他端口在服务器端工作。但是 BlueMix 防火墙在传入呼叫时阻止了除 80/443 之外的所有端口(这就是使用 Websocket 而不是 Socket 的原因)。

在 BLUEMIX 上测试:

  • SERVER VCAP_APP_PORT (62577-62045) > 服务器错误:监听 EADDRINUSE

  • SERVER 端口 80/443 > 服务器错误:监听 EACCES(权限被拒绝)

  • 服务器端口 8888 > OK -- 客户端调用 ws://myapp.mybluemix.net:8888 > 错误:连接 ECONNREFUSED

  • 服务器端口 8888 > 正常 -- 客户端调用 ws://myapp.mybluemix.net > 错误:意外的服务器响应 (500)

  • 服务器端口 5555 > 正常 -- 客户端调用 ws://myapp.mybluemix.net > 错误:意外的服务器响应 (500)

  • SERVER 端口 5555 > OK -- 客户端调用 ws://myapp.mybluemix.net:5555 > 错误:连接 ECONNREFUSED

1.在 BlueMix 上必须使用哪个端口?
2.客户端调用必须在80/443上工作,Websocket是为处理80(http)和443(https)端口上的来电而创建的......?

谢谢

【问题讨论】:

    标签: node.js websocket ibm-cloud


    【解决方案1】:

    使用现有 Express 应用程序启动 WebSocket 服务器需要您共享连接实例,而不是直接打开。

    从他们的documentation,使用 server 参数而不是 port 创建 WebSocketServer 对象。请参阅下面的示例。

    平台路由器接收到的 HTTP 和 WS 流量都将转发到您的应用程序使用 PORT 变量绑定到的内部端口。

    var server = require('http').createServer() , url = 需要('url') , WebSocketServer = require('ws').Server , wss = new WebSocketServer({ server: server }) , 快递 = 要求('快递') , 应用程序 = 快递() , 端口 = 4080; app.use(函数 (req, res) { res.send({ msg: "你好" }); }); wss.on('连接', 函数连接(ws) { var location = url.parse(ws.upgradeReq.url, true); // 你可以使用 location.query.access_token 来验证或共享会话 // 或 ws.upgradeReq.headers.cookie(见 http://stackoverflow.com/a/16395220/151312) ws.on('消息', 函数传入(消息) { console.log('received: %s', message); }); ws.send('某事'); }); server.on('request', app); server.listen(port, function () { console.log('监听' + server.address().port) });

    【讨论】:

      【解决方案2】:

      非常感谢@James Thomas 按照您在 BlueMix 上的建议尝试了 ping pong WS。有效!!

      var server = require('http').createServer()
        , url = require('url')
        , WebSocketServer = require('ws').Server
        , wss = new WebSocketServer({ server: server })
        , express = require('express')
        , app = express()
        , port = (process.env.PORT || 4080);
      
      //---------------------------------------------------------------------------
      
      wss.on('connection', function connection(ws) {
        var location = url.parse(ws.upgradeReq.url, true);
        // you might use location.query.access_token to authenticate or share sessions
        // or ws.upgradeReq.headers.cookie (see http://stackoverflow.com/a/16395220/151312)
      
        ws.on('message', function incoming(message) {
          console.log('server: on message - received: %s', message);
        });
      
        console.log('server: waiting connection');
        ws.send('msg from server');
      });
      
      //---------------------------------------------------------------------------
      
      app.use(function (req, res) {
      
          //var url = 'ws://localhost:4080';
          var url = 'ws://<app>.mybluemix.net';
      
           var WebSocket = require('ws')     
                , ws = new WebSocket(url);
      
           console.log('client: calling url: %s', url);
      
           ws.on('open', function() {
               ws.send('msg from client');
               console.log('client: on open - sent msg from client');
           });
           ws.on('message', function(message) {
               console.log('client: on messagge - received: %s', message);
           });
      
        res.send({ msg: "client call done" });
      });
      
      //---------------------------------------------------------------------------
      
      server.on('request', app);
      server.listen(port, function () { console.log('Listening on ' + server.address().port) })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-28
        • 2017-07-28
        • 1970-01-01
        • 2015-11-23
        • 2016-09-16
        • 2016-05-29
        • 1970-01-01
        • 2014-01-17
        相关资源
        最近更新 更多