【问题标题】:SocketIO over Nginx with SSL带有 SSL 的 Nginx 上的 SocketIO
【发布时间】:2017-09-04 19:59:52
【问题描述】:

我正在尝试通过 nginx 使用 ssl 设置 socketio。问题是我可以让客户端连接,但是我没有看到我希望通过套接字来的其他事件。 (注意:这在本地工作,只是不在我的生产服务器上)

客户端代码在这里:

import openSocket from "socket.io-client";
const socket = openSocket(`${SOCKET}`);

function subscribeToTimer(callBack) {
  socket.on("timer", timestamp => callBack(null, timestamp));
  socket.emit("subscribeToTimer", 1000);
}

export class App extends Component {
  constructor(props) {
    super(props);
    this.store = this.configureStore();
    subscribeToTimer((err, action) => this.store.dispatch(action));
  }

和服务器:

const port = 8000
const io = require('socket.io')()

io.on("connection", (client) => {
  console.log("a user connected")
  client.on("subscribeToTimer", (interval) => {
    console.log("a user is subscribing to timer with interval: ", interval)
    setInterval(() => {
      timestamp = new Date()
      client.emit('timer', { type: 'SET_TIME', payload: timestamp });
    }, interval);
  });
})

io.listen(port)
console.log('listening on port ', port)

由 nginx 管理 /etc/nginx/sites-enabled/default:

server {
  <snip>
  location /socket.io {
    proxy_pass http://localhost:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}

当我启动服务器时,我得到:

listening on port 8000
a user connected

所以,客户端正在连接到服务器,但我没有看到 subscribeToTImer 事件。

这里有什么见解吗?

【问题讨论】:

  • 开发者控制台中的任何内容?
  • @TarunLalwani 客户端控制台中没有任何内容。我实际上想通了,所以我会更新答案:)

标签: ssl nginx socket.io


【解决方案1】:

这个问题可能有两个原因。一种是使用 Host 标头,一种是使用 localhost 而不是127.0.0.1

server {
  <snip>
  location /socket.io {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_cache_bypass $http_upgrade;
  }
}

我不是 100% 确定根本原因,但我已经看到删除 Host 并使用 127.0.0.1 而不是 localhost 在过去解决了 socket.io 的其他问题

【讨论】:

    【解决方案2】:

    问题出在配置的proxy_pass 行。您需要使用一组命名的服务器创建一个 upstream 部分,然后在 proxy_pass 中引用它(而不是像我那样使用 http://localhost...)。

    工作配置/etc/nginx/sites-enabled/default:

    upstream socket_nodes {
      ip_hash;
      server 127.0.0.1:8000;
    }
    
    server {
    
      <-- snip -->
    
      location /socket.io {
        proxy_pass http://socket_nodes;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
      }
    }
    

    【讨论】:

    • 不确定这是否对单个上游服务器有影响。你可以试试`proxy_pass 127.0.0.1:8000;`代替吗?直接在location /socket.io
    • @TarunLalwani nginx 对待 127.0.0.1localhost 有什么不同吗?它几乎与 localhost 一起工作,所以......无论如何,我今晚应该能够测试。
    • @TarunLalwani 你是对的。 127.0.0.1:8000 确实有效。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-07-27
    • 2013-11-24
    • 2021-01-29
    • 2015-09-25
    • 2020-08-13
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多