如何在我的网站的特定页面上使用socket.io?

时间:2013-08-01 08:00:46

标签: node.js socket.io

假设我有一个网站,主页上不需要网络套接字,但是在某些其他相对路径上需要它(例如'/ new')。

假设我需要'连接'事件,以便计算登录“主页”页面和“新”页面的用户。

我试图在相对路径中配置socket.io'connection'事件,如:

app.get('/new',
         function(req,res) {
              io.sockets.on('connection', function (socket) {
                .....
              }
         });

BUT:

  1. 表现不佳。当许多用户连接时,该事件会在不应该被提升时被提升。
  2. 我没有在网上看到像上面那样的任何例子。所有socket.io事件都在主文件(app.js)中配置一次。
  3. 怎么做?

3 个答案:

答案 0 :(得分:15)

回答你的问题:

  1. 显然,因为当用户点击/new时,其处理程序将触发并将连接处理程序添加到io。这是巨大的内存泄漏。

  2. 这与上面的内容有关。每次用户点击/new时,不希望添加连接处理程序。

  3. 现在要解决您的问题,我认为最好的想法是(在浏览器端)调用

    io.connect("http://localhost/new");
    

    然后在你的Node.js应用程序中:

    io.of("/new").on("connection", function (socket) {
        // here are connections from /new
    });
    

    代码应放在顶层,而不是放在路由处理程序中。如果您希望它更具动态性,那么您可以创建自己的子协议:

    1. 连接到io服务器:io.connect("http://localhost);
    2. 发送消息I'm in /new;
    3. 在服务器上获取该消息并将该连接存储在适当的列表中。
    4. 当然,您可以在路由处理程序中指定是否希望客户端连接到socket.io服务器(只需传递某种标志)。

答案 1 :(得分:1)

Socket.io连接未在您的处理程序方法中初始化。
它将在呈现页面后初始化,浏览器加载客户端脚本并调用io.connect(在客户端脚本中)。

在服务器端脚本中的任何位置调用io.sockets.on('connection')只需将另一个侦听器(服务器侦听器)注册到套接字连接事件。
将它放在请求处理程序中意味着只要您向'/ new'发送GET请求,就会注册另一个侦听器。 (您可以在其中放置一些console.log,点击刷新一次,看看新套接字何时连接)

如果你不想在某些页面上使用socket.io连接,你可以这样做

在服务器端脚本

app.all("*", function(req, res, next) {
    res.locals({
        needSocketIo: true
    });
}

app.get('/some-page-you-do-not-want-socket-io', function(req, res) {
    res.render('some-view', {needSocketIo: false});
})

在你的视图/布局上,它只是一个if / else子句,或者不包含带有socket.io逻辑的javascript文件。

如果您希望服务器知道套接字连接的位置,您可以从客户端发出一些消息

socket.on('connect', function () {
    socket.emit('from', {page: 'your-page'});
});

答案 2 :(得分:0)

如果您不选择每页选择性地放置socket.io客户端,那么您可以使用授权事件并检查他们连接的页面:

io.configure(function () {
  io.set('authorization', function (handshakeData, callback) {
    if (handshakeData.url == '/new') {
      //allow the socket to connect
      callback(null, true);
    } else {
      //prevent the socket handshake with an error
      callback('socket.io is not accepting connections from this page', false);
    }
  });
});

您不应多次使用io.sockets.on对象,因为在您的代码中,每次有人加载该页面时,您都会向connection事件添加侦听器。此外,当拒绝握手时,connection事件永远不会被触发,因此您可以使用如下设置:

io.sockets.on('connection', function(socket) {
  //this shouldn't ever happen, it's the same object that was checked before
  if (socket.handshake.url != '/new') {
    socket.disconnect();
    return;
  }

  //do something on page '/new'
}

app.get('/new', function(req, res) {
  //sockets can successfully connect with this page
});

app.get('/foo', function(req, res) {
  //sockets from this page will fail handshakes and be disconnected
});

如果需要计算页面上的用户数量,则可以同时监听套接字的连接和断开连接事件。这是可以做到的一种方式:

var pages = [];
io.sockets.on('connection', function(socket) {
  if (pages[socket.handshake.url] == null) {
    pages[socket.handshake.url] = 0;
  }
  pages[socket.handshake.url]++;

  socket.on('disconnect', function() {
    pages[socket.handshake.url]--;
  });
}

如果人们打开了多个标签页,那么您可以使用socket.handshake对象存储已连接的会话Cookie并查找匹配项。