【发布时间】: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