【问题标题】:Using socket.io with nodejs on a server with apache as a reverse proxy在以 apache 作为反向代理的服务器上使用带有 nodejs 的 socket.io
【发布时间】:2012-05-03 23:58:44
【问题描述】:

我正在尝试使用带有 Socket.IO 的 Node.js 来促进浏览器和客户端之间的消息传递,遵循 the guide

但是,我必须在 Apache 后面设置反向代理节点。因此,我使用的是 example.com/nodejs/,而不是 node 的 example.com:8080。

这似乎导致 Socket.IO 失去了自我意识。这是我的节点应用程序

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

// this has to be here, otherwise the client tries to 
// send events to example.com/socket.io instead of example.com/nodejs/socket.io
io.set( 'resource', '/nodejs/socket.io' );

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

  socket.emit('bar', { one: '1'});

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

});

这是我的客户端文件的样子

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Socket.IO test</title>

  <script src="http://example.com/nodejs/socket.io/socket.io.js"></script>

  <script>

  var socket = io.connect('http://example.com/nodejs/');

  console.log( socket );

  socket.on( 'bar', function (data)
  {
    console.log(data);
    socket.emit( 'foo', {bar:'baz'} );
  });

  socket.emit('foo',{bar:'baz'});

  </script>
</head>
<body>
  <p id="hello">Hello World</p>
</body>
</html>

这里的问题是对http://example.com/nodejs/socket.io/socket.io.js 的脚本引用。它没有返回预期的 JavaScript 内容——而是返回“Welcome to socket.io”,就好像我点击了http://example.com/nodejs/

知道我怎样才能完成这项工作吗?

【问题讨论】:

  • 我知道这与手头的问题无关(如果我应该打开一个新的 SO 问题,请给我打电话),但我很好奇你的 Apache httpd.conf 是什么样的。我已经设置了代理以传递给实际的 node.js 服务器,但是,我无法让 websockets 代理工作。您能否举例说明您是如何使用 Apache 进行此操作的?
  • 对不起,我不能。这个项目是在 2 年前的一次黑客马拉松上完成的,为其设置的服务器已不存在。

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


【解决方案1】:

这最终成为一个多管齐下的解决方案。

首先,在服务器端,我必须像这样设置端点

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

var rootSockets = io.of('/nodejs').on('connection', function(socket)
{
  // stuff
});

var otherSockets = io.of('nodejs/other').on('connection', function(socket)
{
  // stuff
});

然后,在客户端,正确连接看起来像这样

var socket = io.connect(
    'http://example.com/nodejs/'
  , {resource: 'nodejs/socket.io'}
);

// The usage of .of() is important
socket.of('/nodejs').on( 'event', function(){} );
socket.of('/nodejs/other').on( 'event', function(){} );

在这之后,一切都奏效了。请记住,在这台服务器上,Apache 在内部将 example.com/nodejs 代理到端口 8080。

【讨论】:

  • 你使用的是哪个版本的socket.io?我尝试了提到的解决方案。但是,如果 Web 套接字请求通过 apache mod_proxy 路由,则所有 http 标头都会被删除。因此,socket.io 将连接关闭为“websocket 连接无效”。
【解决方案2】:

我认为这与您的 apache 代理无关,但与 socket.io 如何处理子目录上的请求有关。在这里查看我的答案。 NGINX configuration to work with Socket.IO

基本上,您需要改用这个连接语句:

var socket = io.connect('http://example.com', {resource:'nodejs/socket.io'});

【讨论】:

  • 从 socket.io 1.0 开始,{resource: ... {path: ... 取代
【解决方案3】:

如果有人感兴趣,只有这对我有用。 将端口 3000 替换为您的 Nodejs 端口

虚拟主机中的 Apache 2.2.14

    <IfModule mod_proxy.c>
      <Proxy *>
        Order allow,deny
        allow from all
      </Proxy>
    </IfModule>

    RewriteEngine on

    RewriteCond %{QUERY_STRING} transport=polling
    RewriteRule /(.*)$ http://localhost:3001/$1 [P]

    ProxyRequests off
    ProxyPass /socket.io/ ws://localhost:3001/socket.io/
    ProxyPassReverse /socket.io/ ws://localhost:3001/socket.io/

客户端连接:

  var myIoSocket = io.connect($location.protocol() + '://' + $location.host(), {path: '/socket.io'});

无需在 Node.js 方面进行任何更改。

【讨论】:

    猜你喜欢
    • 2020-09-07
    • 1970-01-01
    • 2014-12-13
    • 2016-10-20
    • 1970-01-01
    • 2018-05-09
    • 2019-11-12
    • 2017-08-16
    • 2021-04-26
    相关资源
    最近更新 更多