将socket.io放在反向代理后面?

时间:2018-10-03 01:58:53

标签: node.js socket.io reverse-proxy

我最近决定学习socket.io,使之实时。我在网站上的“入门”页面之后写了一些东西,并在本地对其进行了测试,直到它可以正常工作为止。

我使用与其他任何方法相同的过程将其上传到服务器。我在端口8002上运行它,并将其添加到/pong/*下的我的反向代理中(使用http-proxy-middleware)。然后,我将/socket.io/*代理到端口8002,然后它才起作用。但是,在使用Firefox检查之后,我注意到socket.io仅使用轮询作为传输方法,而不使用websockets,经过进一步思考,我决定将/socket.io/*发送到8002并不适合使用socket.io在将来的其他项目中。

所以我问,如何使用websockets作为传输工具,在反向代理后面运行多个socket.io程序?


proxy.js

const express = require("express")
const fs = require('fs');
const http = require('http');
const https = require('https');
const proxy = require('http-proxy-middleware');

const privateKey  = fs.readFileSync('/etc/[path-to- letsencrypt]/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/[path-to-letsencrypt]/cert.pem', 'utf8');
const ca = fs.readFileSync('/[path-to-letsencrypt]/chain.pem', 'utf8');

var credentials = {key: privateKey, cert: certificate, ca: ca};
var app = express();

app.use(function (req, res, next) {
        console.log(req.url)
        next()
})

app.use("/pong/*", proxy({ target: "http://localhost:8002", pathRewrite: {"^/pong": ""},  ws:true, changeOrigin: true }))
app.use("/pnw/war/*", proxy({ target: "http://localhost:8000" }))
app.use("/pnw/nation/*", proxy({ target: "http://localhost:8001" }))
app.use(express.static("./static"))

https.createServer(credentials, app).listen(443);

// Redirect all HTTP traffic to HTTPS
http.createServer(function (req, res) {
    res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
    res.end();
}).listen(80);

pong.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http, {
    path: "/pong/"
});

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

http.listen(8002, function(){
  console.log('listening on *:8002');
});

index.html

<script src="/pong/socket.io.js"></script>
<script>
    var socket = io({
        // transports: ['websocket'], upgrade: false, (using for testing)
        path:"/pong"
    }) 

    // ...
</script>

我目前所获得的来自以下问题的答案: Setting up multiple socket.io/node.js apps on an Apache server?

但是在firefox控制台中,我收到一条警告,内容为: Loading failed for the <script> with source “https://curlip.xyz/pong/socket.io.js”,后接错误io is not defined。在网络标签中,获取socket.io.js会显示404。

所以我相信正在发生的事情是,因为express正在捕获对/的请求,所以socket.io无法(由于某种原因)无法服务器socket.io.js。但是,当我将/更改为/index.html并加载时,没有任何变化。

1 个答案:

答案 0 :(得分:1)

因此,我进行了更多研究,并找到了解决方案。我在EC2上打开了端口8002,以便可以四处寻找socket.io.js

基本上我发现的是socket.io.js位于/pong/pong/socket.io.js,因为我将pong.js中的路径设置为“ pong”,事后看来,代理添加了一个“ pong”,而socket.io本身正在捕获“ / pong”。

知道这一点后,我删除了pong.js中的path选项,以便可以在/pong/socket.io/socket.io.js上找到socket.io.js。然后,通过更改index.html中的脚本标记和路径选项,使客户端指向此位置。


pong.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

http.listen(8002, function(){
  console.log('listening on *:8002');
});

index.html

<script src="/pong/socket.io/socket.io.js"></script>

var socket = io({
    path:"/pong/socket.io/"
})