【问题标题】:Nodejs - how to get url parameters using socket.io?Nodejs - 如何使用 socket.io 获取 url 参数?
【发布时间】:2017-05-25 14:56:58
【问题描述】:

我一直在研究 Nodejs 和 Socket.io,问题是我正在努力解决如何获取 url 参数 (www.example.com/sample/:sampleid) 并将其用于我的套接字连接。

这是一个例子:

var roomname;
var username;
app.get('/room/:roomname/user/:username', function(req, res){
    var room = {
        username: req.params.username,
        roomname: req.params.roomname
    };
    roomname = room.roomname;
    username = room.username;
    res.render('room', room);
});

var users  = {};

io.sockets.on('connection', function (socket) {
    socket.username = username;
    socket.room = roomname;
    users[username] = username;
    console.log("joining room: " + roomname)
    socket.join(roomname);
    console.log("emiting to room: " + roomname)
    socket.broadcast.to(roomname).emit('newUser', username);

});

我只是将名称存储在 roomname 中并在 io.sockets.on 中使用它,但我认为这是一种 hack,应该是实现此目的的更好方法...

有什么好办法解决这种情况?

【问题讨论】:

    标签: ios node.js sockets


    【解决方案1】:

    由于您正在使用 res.render 并且您已经将 room 作为数据参数传递,我认为最好利用它并执行类似的操作(我在示例中使用 EJS,因为我习惯了):

    客户:

    <script>socket.emit('join', {room: '<%- room.roomname %>' });</script>
    

    服务器:

    io.on('connection', (socket) => {
        socket.room = '';
    
        socket.on('join', (msg) => {
            socket.room = msg.room;
        });
    });
    

    否则,发出document.location.pathname 可能是个好主意,但是您必须自己解析路径才能从中获取房间名。

    编辑:
    由于以下情况,您目前正在做的事情实际上非常危险: 用户 1 打开页面,“全局”变量 usernameroom 已设置(我们现在将它们都设置为 foo),但用户 1 的互联网速度很慢,因此加载和套接字需要一些时间。 io 连接。

    现在用户 2 打开页面,在用户 1 打开 socket.io 连接之前,“全局”变量 usernameroom 已更改为新值(让我们使用 bar)。

    现在用户 1 和用户 2 使用 socket.io 连接,但由于用户 2 的互联网速度比用户 1 快,所以 var usernamevar roomname 现在都设置为值 bar,即使用户 1 有 usernameroomnamefoo

    请注意。

    【讨论】:

      【解决方案2】:

      socket 可以发出任何事件,因为 socket 对象是EventEmitter,因此它可以随时触发(发出)事件,并且另一端的服务器可以通过 .on 函数监听此事件

      example 
      socket.emit('join',{name:"ahmed"})
      
      server
      io.sockets.on('join',function(data){
          console.log(data.name)
      })
      

      【讨论】:

        【解决方案3】:

        我有同样的问题,但我得到了一个不同的解决方案,我在连接时传递参数。

        //it's my connection in client side
        let socket = socketio(`http://localhost:4444?user=${uuid}&room=${room}`); 
        // where UUID is my user ID and room id
        

        所以在服务器端我们可以得到如下参数

        let userUUID = socket.handshake.query.user;
        let roomId = socket.handshake.query.room;
        

        好消息是当连接丢失时,您不必依赖客户端会再次调用您的自定义连接事件这一事实,您可以将您的逻辑放入默认的io.on('connection',);

        更多信息在这里https://socket.io/docs/server-api/#socket-handshake

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-20
          • 1970-01-01
          • 1970-01-01
          • 2018-09-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-03
          相关资源
          最近更新 更多