我在 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' } } }
任何帮助,将不胜感激 !