2014-02-07 77 views
10

我有一個應用程序通過socket.io使用websockets。對於我的應用程序,我想使用單獨的HTTP服務器爲我的應用程序提供靜態內容和JavaScript。因此,我需要設置一個代理。我正在使用node-http-proxy。作爲一個起點,我有我的WebSockets應用在端口8081上運行,我用下面的代碼重新定向socket.io通信這個獨立的服務器,而使用快遞服務的靜態內容:使用節點http代理代理websocket連接

var http = require('http'), 
    httpProxy = require('http-proxy'), 
    express = require('express'); 

// create a server 
var app = express(); 
var proxy = httpProxy.createProxyServer({ ws: true }); 

// proxy HTTP GET/POST 
app.get('/socket.io/*', function(req, res) { 
    console.log("proxying GET request", req.url); 
    proxy.web(req, res, { target: 'http://localhost:8081'}); 
}); 
app.post('/socket.io/*', function(req, res) { 
    console.log("proxying POST request", req.url); 
    proxy.web(req, res, { target: 'http://localhost:8081'}); 
}); 

// Proxy websockets 
app.on('upgrade', function (req, socket, head) { 
    console.log("proxying upgrade request", req.url); 
    proxy.ws(req, socket, head); 
}); 

// serve static content 
app.use('/', express.static(__dirname + "/public")); 

app.listen(8080); 

的上面的應用程序工作得很好,但是,我可以看到,socket.io不再使用websockets,而是回退到XHR輪詢。

我可以確認,通過觀察從代理代碼日誌:

proxying GET request /socket.io/1/?t=1391781619101 
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294 
proxying POST request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=1391781629 
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294 
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294 

有誰知道如何代理網絡套接字通信?來自node-http-proxy的所有示例都假定您要代理所有流量,而不是代理某些流量併爲其他人提供服務。

+1

我個人使用nginx作爲http服務器和代理服務器。它適用於websocket代理(這是我從apache切換的原因)。 –

+1

@dystroy謝謝你的提示 - 儘管我希望有一個基於節點的解決方案。這樣開發人員就可以擁有反映實時部署的本地設置。 – ColinE

回答

15

在你的問題就迷迷糊糊的,我看到它仍然沒有回答。好吧,如果你還在尋找解決方案... 在你的代碼的問題是,app.listen(8080)

require('http').createServer(app).listen(8080) 

只是語法糖,而app本身只是一個處理函數,不是的HttpServer的一個實例(我個人認爲應該從Express中刪除這個功能以避免混淆)。 因此,您的app.on('upgrade')實際上從未使用過。你應該改寫

var server = require('http').createServer(app); 
server.on('upgrade', function (req, socket, head) { 
    proxy.ws(req, socket, head); 
}); 
server.listen(8080); 

希望,這有幫助。

+1

這完美的作品!我已經創建了一個瀏覽器同步設置的主要內容,並表示:https://gist.github.com/timaschew/00ba49d3a39bc3dfbe8f – timaschew

1

你需要兩臺服務器嗎?如果沒有,你可以使用同一個服務器靜態文件和監聽套接字連接:

// make the http server 
var express = require('express'), 
    app = express(), server = require('http').createServer(app), 
    io; 

// serve static content 
server.use('/', express.static(__dirname + '/public')); 

server.listen(8080); 

// listen for socket connections 
io = require('socket.io').listen(server); 

// socket stuff here 
+1

是的,我知道我可以使用一臺服務器 - 但重要的是,在生產中,流連接將來自不同的服務器!感謝您的輸入:-) – ColinE