Node.js 使用socket.io和空消息队列向特定客户端发送消息

Node.js 使用socket.io和空消息队列向特定客户端发送消息,node.js,express,socket.io,Node.js,Express,Socket.io,我快被socket.io搞疯了! 文档太糟糕了,根本不是真的 我想通过socket.io向特定客户发送反馈 我的服务器端如下所示: app.get('/upload', requiresLogin, function(request, response) { response.render('upload/index.jade'); io.sockets.on('connection', function (socket) { console.log('SOCKE

我快被socket.io搞疯了! 文档太糟糕了,根本不是真的

我想通过socket.io向特定客户发送反馈

我的服务器端如下所示:

app.get('/upload', requiresLogin, function(request, response) {
    response.render('upload/index.jade');
    io.sockets.on('connection', function (socket) {
        console.log('SOCKET ID ' + socket.id);
        io.sockets.socket(socket.id).emit('new', 'hello');
    });
});
$(document).ready(function() {
    var socket = io.connect('http://localhost:80/socket.io/socket.io.js');
    socket.on('new', function (data) { 
        console.log(socket.id);
        console.log(data); 
        //$('#state').html(data.status);
    });
});
var socket = clients[sId];
socket.emit('show', {});
客户端是这样的:

app.get('/upload', requiresLogin, function(request, response) {
    response.render('upload/index.jade');
    io.sockets.on('connection', function (socket) {
        console.log('SOCKET ID ' + socket.id);
        io.sockets.socket(socket.id).emit('new', 'hello');
    });
});
$(document).ready(function() {
    var socket = io.connect('http://localhost:80/socket.io/socket.io.js');
    socket.on('new', function (data) { 
        console.log(socket.id);
        console.log(data); 
        //$('#state').html(data.status);
    });
});
var socket = clients[sId];
socket.emit('show', {});
但客户什么也不做。我几乎什么都试过了。有人能告诉我我做错了什么吗(

2件事

1) 你应该将你的
io.sockets.on(..)
放在你的
app/update
路由之外,以防止为客户端添加多个侦听器


2) io.sockets.socket(id);不应使用,它应该是
socket.emit('new','hello')

将消息发送到特定的客户端,并保存每个连接到对象中服务器的客户端

var socketio = require('socket.io');
var clients = {};
var io = socketio.listen(app);

io.sockets.on('connection', function (socket) {
  clients[socket.id] = socket;
});
然后,您可以稍后执行以下操作:

app.get('/upload', requiresLogin, function(request, response) {
    response.render('upload/index.jade');
    io.sockets.on('connection', function (socket) {
        console.log('SOCKET ID ' + socket.id);
        io.sockets.socket(socket.id).emit('new', 'hello');
    });
});
$(document).ready(function() {
    var socket = io.connect('http://localhost:80/socket.io/socket.io.js');
    socket.on('new', function (data) { 
        console.log(socket.id);
        console.log(data); 
        //$('#state').html(data.status);
    });
});
var socket = clients[sId];
socket.emit('show', {});

首先,您不能在客户端使用
socket.id

然后换行

var socket=io.connect('http://localhost:80/socket.io/socket.io.js');


var socket=io.connect('http://localhost:80/');

通过socket.io向特定客户端发送反馈的两种方法包括:

  • 如pkyeck所述,将所有客户端保存到一个对象,以便稍后在路由处理程序中发送到这些特定客户端,例如:

    var sessionsConnections = {};
    sio.on('connection', function (socket) {
      // do all the session stuff
      sessionsConnections[socket.handshake.sessionID] = socket;
    });
    
    sio.on('connection', function (socket) {
      // do all the session stuff
      socket.join(socket.handshake.sessionID);
      // socket.io will leave the room upon disconnect
    });
    
    app.get('/', function (req, res) {
      sio.sockets.in(req.sessionID).send('Man, good to see you back!');
    });
    
  • 或者,使用socket.io对文件室的内置支持-在连接时为每个客户端订阅一个文件室,并在路由处理程序中通过该文件室发送,例如:

    var sessionsConnections = {};
    sio.on('connection', function (socket) {
      // do all the session stuff
      sessionsConnections[socket.handshake.sessionID] = socket;
    });
    
    sio.on('connection', function (socket) {
      // do all the session stuff
      socket.join(socket.handshake.sessionID);
      // socket.io will leave the room upon disconnect
    });
    
    app.get('/', function (req, res) {
      sio.sockets.in(req.sessionID).send('Man, good to see you back!');
    });
    
确认:

请注意,这两个示例解决方案都假定socket.io和express已配置为使用相同的会话存储,因此引用相同的会话对象。有关实现此目标的更多详细信息,请参见上面和下面的链接:


在socket.io 1.0中,这就是它的工作方式。它可能适用于较低版本,但我不能保证

socket.to(socket_id_here).emit('new', 'hello');
这是因为socket.io会在连接时自动向具有套接字id的房间添加套接字


此外,如果您计划升级到1.0版,api会有很多更改,因此有时您必须更改一些代码才能使其在1.0版中工作。

我相信io.sockets.socket已被删除,并且在socket.io()中出现了问题

您可以使用io.sockets.connected[socket.id]并存储socket.id以通过用户名与用户进行引用:

var usernames = {};
usernames[username] = socket.id;
// Sending the message
io.sockets.connected[usernames[username]].emit(...);
我在文档中的任何地方都看不到,所以我可以看出这是如何没有得到回答的。此外,如果您没有通过用户名进行任何引用,您可以尝试:

users[socket.id] = socket.id;
复制密钥和值以便于访问

还有一种可能的方法是使用io.clients,如下所述,但我没有使用这种方法


其他解决方案:

在Socket.io 1.0+中执行此操作的正确方法是:

io.to(users_socket_id).emit('new', 'hello');
您还可以将文件室名称替换为“users\u socket\u id”以发送到特定的socket.io文件室。

您尝试过使用吗

var socket = io.connect('http://localhost:80/');
我对node和socket.io的最新版本感到厌倦 下面我将发布完整的代码


好的,很好,这也是一个问题io.connect(');但是当我想在上传过程中发送消息时怎么办?然后我需要存储客户端ID并使用io.sockets.socket(socket.ID).emit('new','hello');还是没有?据我所知,通过表单上传文件时套接字连接没有断开。好的,很好,最后一个问题。是否可以清空消息队列?当我重新进入视图时,我会收到所有旧消息…@vboy您在谈论哪个消息队列?socket.io在内部维护的消息队列,用于客户端未接收到的不起作用的消息。我做了一个简单的测试:var-soc;on('connection',function(socket){soc=socket;});从每一次溃败中走出。在我的上传功能中,我使用了soc.emit('news','bla'),没有任何事情发生……正如我前面所说的:上传文件时不能发送事件。但是这种方法是有效的,当您有相应的id时,您可以向特定的客户端发送消息。:-/对不起,我误解了您的意思。因此,没有办法从路由函数触发消息到特定客户机?是的,有。您必须将连接到服务器的所有客户端保存在clients对象中(参见示例),当您拥有套接字id时,您可以通过该对象直接访问套接字。但你不能在上传时这样做…你到底想做什么?是否删除旧连接?只需执行一个
删除客户端[socketId]
当客户端断开连接时,它将从
客户端
散列中删除。我想说的是,将会话id用作会议室是一个很好的建议。帮助我解决了一个问题,所以谢谢:)看起来socket.io 1.0内置了对room-per-socket方法的支持:room应该负责集群。与其他答案一样,在本地内存中保存套接字可能会导致内存泄漏,并且无法扩展。