2013-02-25 10 views
6

Tôi đã viết http proxy trong node.js đang chạy trên cổng 80. Tất cả những gì tôi cần là chuyển hướng lưu lượng socket.io đến cổng 9090 và lưu lượng truy cập http tiêu chuẩn đến Apache trên 8080. Đây là mã proxy của tôi:node.js: proxy websockets đến cổng khác

httpProxy = require('http-proxy'); 

httpProxy.createServer(function (req, res, proxy) { 
    if (req.url.match(/socket.io/)) { 
     proxy.proxyRequest(req, res, { 
      host: 'localhost', 
      port: 9090 
     }); 
    } else { 
     proxy.proxyRequest(req, res, { 
      host: 'localhost', 
      port: 8080 
     }); 
    } 
}).listen(80); 

Mọi thứ đều hoạt động, nhưng io.socket rơi trở lại xhr-polling.

http://localhost/client.htm - falls back to xhr-polling 

file:///C:/.../client9090.htm - still uses websocket 

ứng dụng socket.io đang chạy trên cổng 9090, client.htm kết nối vào 80 và client9090.htm kết nối trực tiếp đến 9090.

Nó trông giống như một nút-http-proxy làm cho ứng dụng socket.io để làm việc trong chế độ xhr-polling. Khách hàng là Chrome v.25

mã ứng dụng socket.io

var io = require('socket.io').listen(9090); 

io.on('connection', function (socket) { 

     socket.on('hi!', function (data) { 
      console.log(data); 
      socket.emit('news'); 
     }); 

     socket.on('ahoj', function (data) { 
      console.log(data); 
     }); 
    }); 

đang client.htm

<script src="http://localhost/socket.io/socket.io.js"></script> 
<script> 
    var chat = io.connect('http://localhost') 

    chat.on('connect', function() { 
     chat.emit('hi!'); 
    }); 

    chat.on('news', function() { 
     chat.emit('ahoj',{a:1,b:2}); 
    }); 
</script> 

client9090.htm là như nhau nhưng localhost được thay thế bằng localhost: 9090

Như tôi đã nói, mọi thứ đều hoạt động tốt, chỉ có vấn đề là, nút-http-proxy đó làm giảm trở lại từ các websockets đến xhr-polling. Có ai giúp được không?

Trả lời

2

Theo https://npmjs.org/package/http-proxy, khi thêm một callback để httpProxy.createServer(), bạn phải tự proxy 'nâng cấp' sự kiện, vì vậy một cái gì đó như thế này:

httpProxy = require('http-proxy'); 

// added `var server =` here 
var server = httpProxy.createServer(function (req, res, proxy) { 
    if (req.url.match(/socket.io/)) { 
     proxy.proxyRequest(req, res, { 
      host: 'localhost', 
      port: 9090 
     }); 
    } else { 
     proxy.proxyRequest(req, res, { 
      host: 'localhost', 
      port: 8080 
     }); 
    } 
}).listen(80); 

// added upgrade listener section here: 
server.on('upgrade', function (req, socket, head) { 
    server.proxy.proxyWebSocketRequest(req, socket, head); 
}); 

Tuy nhiên, đối với việc sử dụng bạn mô tả ở trên , bạn thậm chí không cần chức năng gọi lại - bạn có thể dễ dàng thực hiện một việc như sau:

httpProxy = require('http-proxy'); 

var options = { 
    pathnameOnly: true, 
    router: { 
    '/wiki': '127.0.0.1:8001', 
    '/blog': '127.0.0.1:8002', 
    '/api': '127.0.0.1:8003' 
    } 
} 

var proxyServer = httpProxy.createServer(options); 
proxyServer.listen(80);