首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何只在我网站的特定页面上使用socket.io?

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

Stack Overflow用户
提问于 2013-08-01 08:00:46
回答 3查看 10.4K关注 0票数 9

让我们假设我有一个网站,它不需要主页上的web套接字,但在其他相对路径(例如‘/new’)上需要它。

假设我需要“connection”事件来统计登录到“主页”页面和“新”页面的用户。

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

代码语言:javascript
复制
app.get('/new',
         function(req,res) {
              io.sockets.on('connection', function (socket) {
                .....
              }
         });

但是:

  1. 表现不太好。当许多用户连接时,该事件会在不应该发生的情况下引发。
  2. 我在网上没有看到像上面这样的例子。所有socket.io事件都在主文件(app.js)中配置一次。

怎么做呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-03 15:21:47

回答你的问题:

  1. 显然,因为当用户点击/new时,它的处理程序会触发并将连接处理程序添加到io。这是一个巨大的内存泄漏。
  2. 这和上面的那个有关。不希望每次访问/new时都添加一个连接处理程序。

为了解决您的问题,我认为最好的方法是调用(在浏览器端)。

代码语言:javascript
复制
io.connect("http://localhost/new");

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

代码语言:javascript
复制
io.of("/new").on("connection", function (socket) {
    // here are connections from /new
});

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

  1. 连接到io服务器:io.connect("http://localhost);
  2. 发送消息I'm in /new;
  3. 在服务器上获取该消息并将该连接存储在适当的列表中。

当然,您可以在路由处理程序中指定是否希望客户端连接到socket.io服务器(只需传递某种标志)。

票数 19
EN

Stack Overflow用户

发布于 2013-09-03 15:24:47

在处理程序方法中没有像这样初始化Socket.io连接。

它将在页面呈现后初始化,浏览器加载客户端脚本并调用io.connect (在客户端脚本中)。

在服务器端脚本中的任何地方调用io.sockets.on('connection'),只需将另一个侦听器(服务器侦听器)注册到套接字连接事件。

将其放置在请求处理程序中意味着每当您向'/new‘发送GET请求时,就会注册另一个侦听器。(您可以在那里放置一些console.log,点击几次刷新并查看新套接字何时连接)

如果不希望在某个页面上进行socket.io连接,可以这样做

在服务器端脚本上

代码语言:javascript
复制
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/ with子句,用于或不包含带有socket.io逻辑的javascript文件。

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

代码语言:javascript
复制
socket.on('connect', function () {
    socket.emit('from', {page: 'your-page'});
});
票数 1
EN

Stack Overflow用户

发布于 2013-09-03 14:55:14

如果不选择将socket.io客户端选择性地放在每个页面上,则可以使用授权事件并检查它们从哪个页面连接到哪个页面:

代码语言:javascript
复制
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事件永远不会触发,因此您可以使用如下设置:

代码语言:javascript
复制
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
});

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

代码语言:javascript
复制
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]--;
  });
}

如果用户打开多个选项卡,那么您可以存储连接的会话cookie并查找匹配项,也可以使用socket.handshake对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17988300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档