【问题标题】:Socket io Nodejs- manage when a user open multiple tabsSocket io Nodejs-在用户打开多个选项卡时进行管理
【发布时间】:2017-04-24 17:37:13
【问题描述】:

我正在尝试在我的应用程序中编写聊天,但我遇到了一个不知道如何管理它的问题! 这是情景: 我们有很多经过身份验证的用户,所以他们都有一个唯一的 ID,我想实现像 Facebook 这样的聊天,这样每两个用户都可以互相聊天。 为此,我有一个包含内容的 server.js 文件:

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
var users = [];
server.listen(8890);
io.on('connection', function (socket) {

    console.log("client connected");
    var redisClient = redis.
    redisClient.subscribe('message');

    redisClient.on("message", function(channel, data) {
        var data = JSON.parse(data);
        socket.to('user_'+data.user).emit(channel, data);
    });

    // join a room    
    socket.on('newUser',function (user, type){
        socket.type = type;
        socket.join('user_'+user); 

    }); 
});

还有一个 client.js:

var socket = io.connect( 'http://127.0.0.1:8890' );
if (auth) {
    socket.on('connect', function(){
        socket.emit('newUser', userId, userType);
    });
}

socket.on( 'message', function( data ) {

    console.log(data);
    // var data = JSON.parse(data);
    var content = $( "#messages" ).html();
    var newMsgContent = '<li>' + data.message + '</li>';
    var newContent = newMsgContent + content;

    $( "#messages" ).html( newContent );
});

用于发送消息的表单:

<form action="{{ route('message.send') }}" method="POST" class="ajax-form">
    <input name="_method" value="put" type="hidden"/>
    <input name="user" value="{{ $user }}" type="hidden"/>
    <input name="item" value="{{ $item }}" type="hidden"/>
    <input name="type" value="{{ $type }}" type="hidden"/>
    <input name="socketId" value="" type="hidden"/>
    <input name="message" value="message to {{ $user }} from {{ @$requirements->user->id }}" type="text" class="input-xxlarge" placeHolder="Message" />
    <br>
    <input type="submit" value="Send" />
</form>

最后,我将使用 Redis 发送消息:

$redis = \LRedis::connection();
$data = ['user' => $request->user, 'message' => $request->message];
if($redis->publish('message', json_encode($data)))
   return true;

在上面的代码中,当用户打开我的应用程序时,将使用一个连接并且 newUser 将启动,因此我使用他的 ID 为这个用户创建一个房间并将他加入这个房间 (socket.join('user_'+user ))。 然后,当用户想向该用户发送消息时,我只需发送接收者用户的 ID(我们之前为他创建了一个房间)并将消息发送到该 ID 所在的房间(socket.to('user_' +data.user).emit(频道,数据);)。 问题是,当用户打开多个选项卡时,每个选项卡都被识别为用户,并将使用另一个 socket.id 加入同一个房间,但两者都是具有一个唯一 ID 的用户! 然后,当我向打开两个选项卡的用户发送消息时,他将从一个请求中收到 2 条消息!喜欢: 你好 id 5 你好 id 5

那么现在我应该怎么做才能将每​​个标签的消息发送到用户打开的所有标签! 提前致谢。

【问题讨论】:

  • 真的,我什至不知道这意味着我是 node.js 和 socket.io 的新手。 @MarcosCasagrande
  • 是的,我猜...@MarcosCasagrande
  • 在你的`redisClient.on("message", function(channel, data) {`中输入一个控制台日志,看看它是否被触发了两次,因为我在没有redis的情况下测试了你的代码并且可以工作。
  • 是的,没有 redis 也能正常工作!但为什么!!这是redis的问题吗? @MarcosCasagrande
  • 我确信它不会触发两次!实际上,如果我在 chrome 中打开 4 个选项卡并在 Firefox 中打开一个选项卡并从 firefox fo chrome 发送一条消息,有时它是一个基本的选项卡编号,chrome 将在一个请求中收到 4 条消息!

标签: javascript node.js laravel-5 redis socket.io


【解决方案1】:

将您的redisCLient.subscribe 移到连接侦听器之外。每次建立连接时,您都会再次附加该事件,这就是您获得重复项的原因。

var redisClient = redis.createClient();
redisClient.subscribe('message');

redisClient.on("message", function(channel, data) {
  var data = JSON.parse(data);
  //Changed socket.to with io.to
  io.to('user_'+ data.user).emit(channel, data);
});

io.on('connection', function (socket) {

    console.log("client connected");

    // join a room    
    socket.on('newUser',function (user, type){
        socket.type = type;
        socket.join('user_'+user); 

    }); 
});

附带说明一下,可以使用append 改进您的客户端代码

socket.on( 'message', function( data ) {
    console.log(data);
    // var data = JSON.parse(data);
    $( "#messages" ).append('<li>' + data.message + '</li>');    
});

【讨论】:

  • 它不起作用,我在消息redis客户端上放了一个console.log,但没有发生任何日志!
  • 是的,我打错了,该服务器甚至没有启动...但在 io.on('connection'...!
  • 我猜前两行应该是这样的: var redisClient = redis.createClient(); redisClient.subscribe('message');
  • 不可能redis监听器没有被触发,我需要检查完整的代码。
猜你喜欢
  • 2012-05-01
  • 1970-01-01
  • 2012-08-23
  • 2014-01-17
  • 2019-11-22
  • 2013-01-19
  • 1970-01-01
  • 2018-06-27
  • 2015-03-10
相关资源
最近更新 更多