0

我在 OpenShift Cloud 上部署了一个 node.js 服务器,我正在使用 socket.io 来实现一个实时聊天应用程序。在我的开发机器上它工作正常,但是当我将它部署到 OpenShift 时,它向 Socket.io Java 客户端返回 400 响应代码。

请看它是服务器代码

  const
  http = require('http'), fs = require('fs'), path = require('path'),
    contentTypes = require('./utils/content-types'),
    sysInfo = require('./utils/sys-info'), env = process.env,
    credential = require('./credentials.js'),
    ChatEvent = require('./chat.js');

// Import all dependencies
var express = require('express');
var app = express();
var server = require('http').Server(app);
var socketio = require('socket.io');
var io = socketio(server);

app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept");
  next();
});


var connectedClients = {};

io.set("transports", ['xhr-polling', 'polling', 'websocket']);

io.sockets.on('connection', function(client) {
var address = client.request.connection.remoteAddress;
console.log('Client connected from: [%s] ', address);
console.log(client);
var clientId = null;

client.on('message', function(data) {
    console.log("Message received: %s", data);
    client.write("From Server: " + data);
});

client.on('error', function(err) {
    console.log(err);
 });


client.on('echo', function(data) {
    client.write(data);
});

client.on('disconnect', function() {
    if (clientId)
        delete connectedClients[clientId];
    console.log('Client Disconnected: [%s]', address);
});

});

app.all('*', function(req, res, next) {
var url = req.url;
if (url == '/') {
    url += 'index.html';
}

if (url == '/health') {
    res.writeHead(HttpStatus.OK);
    res.end();
} else if (url.indexOf('/info/') == 0) {
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Cache-Control', 'no-cache, no-store');
    res.end(JSON.stringify(sysInfo[url.slice(6)]()));
} else {
    fs.readFile('./static' + url, function(err, data) {
        if (err) {
            res.writeHead(HttpStatus.NOT_FOUND);
            res.end();
        } else {
            var ext = path.extname(url).slice(1);
            // res.setHeader('Content-Type', contentTypes[ext]);
            if (ext === 'html') {
                res.setHeader('Cache-Control', 'no-cache, no-store');
            }
            res.end(data);
        }
    });
   }
});

// --------------------- Start Server------------------------ //

server.listen(env.NODE_PORT || 3000, env.NODE_IP || 'localhost', function()           {
var host = server.address().address
var port = server.address().port
console.log("Chat App listening at http://%s:%s", host, port)
});

这是我使用https://github.com/socketio/socket.io-client-java的客户端代码

public class SMRChatClient {

public static void main(String[] args)
        throws UnknownHostException, IOException, ClassNotFoundException, URISyntaxException {

    final Socket socket = IO.socket("http://myapp-url.rhcloud.com:8000");
    socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {

        @Override
        public void call(Object... args) {
            JSONObject object = new JSONObject();
            try {
                object.put("sessionToken", "1d0bbced4d560af3ae22bc4513bfa400");
                socket.emit("echo", object.toString());

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

    }).on(Socket.EVENT_MESSAGE, new Emitter.Listener() {

        @Override
        public void call(Object... args) {
            System.out.println("Message Received: ");
            for (int i = 0; i < args.length; i++) {
                System.out.println(args[i]);
            }
        }

    }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {

        @Override
        public void call(Object... args) {
            System.out.println("Client disconnected");
        }

    }).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {

        @Override
        public void call(Object... args) {
            Exception e = (Exception) args[0];
            e.printStackTrace();
        }

    }).on(Socket.EVENT_ERROR, new Emitter.Listener() {

        @Override
        public void call(Object... args) {
            Exception e = (Exception) args[0];
            e.printStackTrace();
        }

    }).on(Socket.EVENT_RECONNECT, new Emitter.Listener() {

        @Override
        public void call(Object... args) {
            System.out.println("Reconnecting: ");
            for (int i = 0; i < args.length; i++) {
                System.out.println(args[i]);
            }
        }

    });
    socket.connect();
}

}

响应是 EVENT_ERROR,e.printStackTrace() 之后的控制台是:

io.socket.engineio.client.EngineIOException: xhr poll error
at io.socket.engineio.client.Transport.onError(Transport.java:64)
at io.socket.engineio.client.transports.PollingXHR.access$100(PollingXHR.java:18)
at io.socket.engineio.client.transports.PollingXHR$6$1.run(PollingXHR.java:126)
at io.socket.thread.EventThread$2.run(EventThread.java:75)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: 400
at io.socket.engineio.client.transports.PollingXHR$Request$1.run(PollingXHR.java:218)
... 1 more

连接建立但中断,虽然我将客户端套接字登录到控制台,这里是服务器的输出

Socket {
nsp:
 Namespace {
   name: '/',
   server:
    Server {
      nsps: [Object],
    _path: '/socket.io',
    _serveClient: true,
    _adapter: [Function: Adapter],
    _origins: '*:*',
    sockets: [Circular],
    eio: [Object],
    httpServer: [Object],
    engine: [Object] },
 sockets: { '/#TiwzTKVNEVtlBVdkAAAC': [Circular] },
 connected: { '/#TiwzTKVNEVtlBVdkAAAC': [Circular] },
 fns: [],
 ids: 0,
 adapter:
  Adapter {
    nsp: [Circular],
    rooms: [Object],
    sids: [Object],
    encoder: Encoder {} },
 _events: { connection: [Function] },
 _eventsCount: 1 },
  server:
   Server {
 nsps: { '/': [Object] },
 _path: '/socket.io',
 _serveClient: true,
 _adapter: [Function: Adapter],
 _origins: '*:*',
 sockets:
  Namespace {
    name: '/',
    server: [Circular],
    sockets: [Object],
    connected: [Object],
    fns: [],
    ids: 0,
    adapter: [Object],
    _events: [Object],
    _eventsCount: 1 },
 eio:
  Server {
    clients: [Object],
    clientsCount: 1,
    pingTimeout: 60000,
    pingInterval: 25000,
    upgradeTimeout: 10000,
    maxHttpBufferSize: 100000000,
    transports: [Object],
    allowUpgrades: true,
    allowRequest: [Function: bound ],
    cookie: 'io',
    cookiePath: false,
    perMessageDeflate: [Object],
    httpCompression: [Object],
    ws: [Object],
    _events: [Object],
    _eventsCount: 1 },
 httpServer:
  Server {
    domain: null,
    _events: [Object],
    _eventsCount: 5,
    _maxListeners: undefined,
    _connections: 0,
    _handle: [Object],
    _usingSlaves: false,
    _slaves: [],
    _unref: false,
    allowHalfOpen: true,
    pauseOnConnect: false,
    httpAllowHalfOpen: false,
    timeout: 120000,
    _pendingResponseData: 0,
    _connectionKey: '4:127.3.143.1:8080' },
 engine:
  Server {
    clients: [Object],
    clientsCount: 1,
    pingTimeout: 60000,
    pingInterval: 25000,
    upgradeTimeout: 10000,
    maxHttpBufferSize: 100000000,
    transports: [Object],
    allowUpgrades: true,
    allowRequest: [Function: bound ],
    cookie: 'io',
    cookiePath: false,
    perMessageDeflate: [Object],
    httpCompression: [Object],
    ws: [Object],
    _events: [Object],
    _eventsCount: 1 } },
 adapter:
   Adapter {
     nsp:
      Namespace {
       name: '/',
    server: [Object],
    sockets: [Object],
    connected: [Object],
    fns: [],
    ids: 0,
    adapter: [Circular],
    _events: [Object],
    _eventsCount: 1 },
 rooms: { '/#TiwzTKVNEVtlBVdkAAAC': [Object] },
 sids: { '/#TiwzTKVNEVtlBVdkAAAC': [Object] },
 encoder: Encoder {} },
  id: '/#TiwzTKVNEVtlBVdkAAAC',
  client:
   Client {
     server:
  Server {
    nsps: [Object],
    _path: '/socket.io',
    _serveClient: true,
    _adapter: [Function: Adapter],
    _origins: '*:*',
    sockets: [Object],
    eio: [Object],
    httpServer: [Object],
    engine: [Object] },
 conn:
  Socket {
    id: 'TiwzTKVNEVtlBVdkAAAC',
    server: [Object],
    upgrading: false,
    upgraded: false,
    readyState: 'open',
    writeBuffer: [Object],
    packetsFn: [Object],
    sentCallbackFn: [],
    cleanupFn: [Object],
    request: [Object],
    remoteAddress: '127.3.143.1',
    checkIntervalTimer: null,
    upgradeTimeoutTimer: null,
    pingTimeoutTimer: [Object],
    transport: [Object],
    _events: [Object],
    _eventsCount: 3 },
 encoder: Encoder {},
 decoder: Decoder { reconstructor: null, _callbacks: [Object] },
 id: 'TiwzTKVNEVtlBVdkAAAC',
 request:
  IncomingMessage {
    _readableState: [Object],
    readable: true,
    domain: null,
    _events: {},
    _eventsCount: 0,
    _maxListeners: undefined,
    socket: [Object],
    connection: [Object],
    httpVersionMajor: 1,
    httpVersionMinor: 1,
    httpVersion: '1.1',
    complete: true,
    headers: [Object],
    rawHeaders: [Object],
    trailers: {},
    rawTrailers: [],
    upgrade: false,
    url: '/socket.io/?EIO=3&transport=polling',
    method: 'GET',
    statusCode: null,
    statusMessage: null,
    client: [Object],
    _consuming: false,
    _dumped: true,
    _query: [Object],
    res: [Object],
    cleanup: [Function: cleanup] },
 onclose: [Function: bound ],
 ondata: [Function: bound ],
 onerror: [Function: bound ],
 ondecoded: [Function: bound ],
 sockets: { '/#TiwzTKVNEVtlBVdkAAAC': [Circular] },
 nsps: { '/': [Circular] },
 connectBuffer: [] },
  conn:
  Socket {
 id: 'TiwzTKVNEVtlBVdkAAAC',
 server:
  Server {
    clients: [Object],
    clientsCount: 1,
    pingTimeout: 60000,
    pingInterval: 25000,
    upgradeTimeout: 10000,
    maxHttpBufferSize: 100000000,
    transports: [Object],
    allowUpgrades: true,
    allowRequest: [Function: bound ],
    cookie: 'io',
    cookiePath: false,
    perMessageDeflate: [Object],
    httpCompression: [Object],
    ws: [Object],
    _events: [Object],
    _eventsCount: 1 },
 upgrading: false,
 upgraded: false,
 readyState: 'open',
 writeBuffer: [ [Object] ],
 packetsFn: [ undefined ],
 sentCallbackFn: [],
 cleanupFn: [ [Function], [Function] ],
 request:
  IncomingMessage {
    _readableState: [Object],
    readable: true,
    domain: null,
    _events: {},
    _eventsCount: 0,
    _maxListeners: undefined,
    socket: [Object],
    connection: [Object],
    httpVersionMajor: 1,
    httpVersionMinor: 1,
    httpVersion: '1.1',
    complete: true,
    headers: [Object],
    rawHeaders: [Object],
    trailers: {},
    rawTrailers: [],
    upgrade: false,
    url: '/socket.io/?EIO=3&transport=polling',
    method: 'GET',
    statusCode: null,
    statusMessage: null,
    client: [Object],
    _consuming: false,
    _dumped: true,
    _query: [Object],
    res: [Object],
    cleanup: [Function: cleanup] },
 remoteAddress: '127.3.143.1',
 checkIntervalTimer: null,
 upgradeTimeoutTimer: null,
 pingTimeoutTimer:
  Timeout {
    _called: false,
    _idleTimeout: 85000,
    _idlePrev: [Object],
    _idleNext: [Object],
    _idleStart: 1634714,
    _onTimeout: [Function],
    _repeat: null },
 transport:
  XHR {
    readyState: 'open',
    discarded: false,
    closeTimeout: 30000,
    maxHttpBufferSize: 100000000,
    httpCompression: [Object],
    supportsBinary: true,
    _events: [Object],
    _eventsCount: 5,
    sid: 'TiwzTKVNEVtlBVdkAAAC',
    req: null,
    res: null,
    writable: false },
 _events:
  { close: [Object],
    data: [Function: bound ],
    error: [Function: bound ] },
 _eventsCount: 3 },
  rooms: {},
  acks: {},
  connected: true,
 disconnected: false,
 handshake:
   { headers:
  { 'user-agent': 'Java/1.8.0_51',
    host: 'myapp-url.rhcloud.com:8000',
    accept: 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2',
    'x-forwarded-for': '117.203.6.68',
    'x-client-ip': '117.203.6.68',
    'x-forwarded-proto': 'http',
    'x-forwarded-host': 'myapp-url.rhcloud.com',
    'x-forwarded-port': '8000',
    connection: 'close' },
 time: 'Sun May 29 2016 10:01:22 GMT-0400 (EDT)',
 address: '127.3.143.1',
 xdomain: false,
 secure: false,
 issued: 1464530482029,
 url: '/socket.io/?EIO=3&transport=polling',
 query: { EIO: '3', transport: 'polling' } } }

任何帮助,将不胜感激 !

4

1 回答 1

2

这里的问题是 OpenShift 的启动脚本正在为我的应用程序启动 4 个工作线程,这导致了无效的会话 ID 问题,这似乎是 node.js 中集群的问题

于 2016-05-29T16:43:51.577 回答