node.js - 发送到单个客户端套接字 io 1.3.2

标签 node.js sockets socket.io

我在这里查看了几个答案,但我认为他们指的是旧版本的 socket.io,因为他们的解决方案对我不起作用。我使用

将数据返回到浏览器中
io.emit('update', data)

但它会发送给所有客户端,因此当我访问相同的 URL 时,相同的数据会显示在多个窗口中。我是否必须在连接时将客户端 ID 存储在某处,或者我可以在发出之前将其取回吗?请具体说明。我尝试了一些其他的解决方案,但我得到了很多 ReferenceError 'id' is not Defined 或套接字而不是套接字。

服务器设置和连接:

var app = express();
var server = require('http').createServer(app)
var io = require('socket.io')(server)

app.get('/aPath', function (req, res, next) {
        res.writeHead(200)

    var data = {
        "val1":  req.query.val1,
        "val2":  req.query.val2,
        "val3":  req.query.val3,
        "val4":  req.query.val4,
        "val5":  req.query.val5,
        "val6":  req.query.val6,
    }

    /*console.log(io.sockets.id)*/

    //io.to(io.sockets.id).emit('update', data)
    //io.sockets.socket(id).emit('update', data)
    io.emit('update', data)
    res.end("OK")
})

io.on('connection', function (socket) {
    console.log('websocket user connected')
});

最佳答案

由于第三方客户端通过 Restful 接口(interface)发送信息,因此您需要在该请求中以 header 或查询字符串的形式包含客户端的引用数据。

我建议使用 Redis 来存储事件套接字用户以供快速引用。这将允许您部署多个应用程序,使用单个 redis 实例来保持数据同步。您也可以在应用程序内存中执行相同的操作,但这只是不能很好地扩展。

首先,您需要使用中间件来验证用户身份并缓存socket.id

var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var redis = require('redis');

io.use(function(socket, next){
  // validate user
  // cache user with socket.id
  var userId = validatedUser;
  socket.handshake.userId = userId;
  redis.set(userId, socket.id, function (err, res) {
       next()
  });
});

下一步处理所有套接字通信

io.on('connection', function (socket) {
    console.log('websocket user connected');

    //next handle all socket communication
    socket.on('endpoint', function (payload) {
        //do stuff
        socket.emit('endpoint.response', {/*data*/});
    });

    //Then remove socket.id from cache
    socket.on('disconnect', function (payload) {
        //remove user.id from cache
        redis.del(socket.handshake.userId, function (err, res) {
             console.log('user with %s disconnected', socket.id);
        });
    });
});

处理第三方事件。

app.get('/aPath', function (req, res, next) {
    // get user from third party
    var userId = req.query.userId

    var data = {
        "val1":  req.query.val1,
        "val2":  req.query.val2,
        "val3":  req.query.val3,
        "val4":  req.query.val4,
        "val5":  req.query.val5,
        "val6":  req.query.val6,
    };

    // get cached socketId from userId
    redis.get(userId, function (err, socketId) {
        // return ok to third party;
        res.status(200).send("OK");
        only emit if socketid still exists
        if (err || !socketId) return;
        // now emit to user
        io.to(socketId).emit('update', data):
    });
});

关于node.js - 发送到单个客户端套接字 io 1.3.2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28403336/

相关文章:

javascript - 如何通过 socket.io 将图像发送到服务器?

javascript - 我如何在socket.io 1.0中断开服务器端和客户端的套接字

node.js - 获取oauth信息后如何将数据发送回客户端

javascript - 如何使用多个 npm 身份验证 token

c# - 将 Python SocketServer 与 C# 客户端连接

linux - 如何通过 sll_ifindex 判断一个接口(interface)是否为环回设备?

php - Node.js + Socket IO + Apache + PHP 从 url 中删除端口?

node.js - 将异步代码视为 Node.js 中的线程?

javascript/node JSON 解析问题

java - 我的服务器和客户端套接字程序只是挂起而不打印任何内容