简体   繁体   中英

Putting socket.io behind a reverse proxy?

I recently decided to learn socket.io, to make something real-time. I wrote something up, following the Get Started page on the site, and tested it locally until I got it working properly.

I uploaded it to my server using the same process as anything else. I ran it on port 8002, and added it to my reverse proxy (using http-proxy-middleware ) under /pong/* . I then proxied /socket.io/* to port 8002 before it worked. However after inspection with Firefox I noticed that socket.io was only using polling as a transport method and not websockets, and after some further thought I decided that sending /socket.io/* to 8002 is not going to be good when using socket.io on other projects in the future.

So I ask, how do I get multiple socket.io programs running behind a reverse proxy, using websockets as a for transport?


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>

What I have currently comes from following the answer to this question: Setting up multiple socket.io/node.js apps on an Apache server?

However in the firefox console I get a warning which reads: Loading failed for the <script> with source “https://curlip.xyz/pong/socket.io.js” , followed by an error io is not defined . In the network tab getting socket.io.js is showing a 404.

So what I believe is happening is that because express is capturing the requests for /, socket.io cannot (for some reason) server socket.io.js. However when I changed / to /index.html and loaded that there was no change.

So I did some more research and came upon a solution. I opened the port 8002 on my EC2 so that I could poke around looking for socket.io.js .

Essentially what I found is socket.io.js was located at /pong/pong/socket.io.js because I set path in pong.js to "pong", which, in hindsight make sense, the proxy adds one "pong", while socket.io itself is capturing "/pong".

Knowing this I removed the path option in pong.js, so that socket.io.js can be found at /pong/socket.io/socket.io.js . I then made the client point to this by changing the script tag and path option in 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/"
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM