PHP REDIS NODE.JS多个发布者/订阅者
我想创建一个私人聊天。
说明:
想象一下,你是User_1,你打开一个用户列表[User_2,User_3 ...等],点击一个特定按钮后,每个元素都有一个按钮,我想与特定用户一起开始聊天窗口。 (服务器端Laravel项目端口:8000)有效地使用Websockets我也在运行node.js服务器(端口3000)。要将数据从php传输到node.js我正在使用redis Pub / Sub,ChatController.php:
class ChatController extends Controller
{
public function toChat($ForeignUserId)
{
$fid = (int) $ForeignUserId;
$uid = (int) Sentinel::getUser()->id;
$CollectionName1 = $fid . "collection" . $uid;
$CollectionName2 = $uid . "collection" . $fid;
$roomName = $uid . "room" . $fid;
$res = DB::table('chats')
->where('collection_name', '=', $CollectionName1)
->orWhere('collection_name', '=', $CollectionName2)
->take(1)
->get();
if(count($res) == 1)
{
$redis = Redis::connection();
//$redis->publish('chat-channel', json_encode([['idone' => $uid], ['idtwo' => $fid]]));
$redis->publish('chat-channel', json_encode(['idone' => $uid, 'idtwo' => $fid, 'IOroom' => $res[0]->room_name, 'collection' => $res[0]->collection_name]));
}
else
{
$date = date('Y-m-d H:m:s');
DB::table('chats')->insert(['collection_name' => $CollectionName2, 'room_name' => $roomName, 'sender' => $uid, 'receiver' => $fid, 'created_at' => $date]);
//$client = new MongoDB\Client;
$client = new Mongo;
$companydb = $client->chat;
$result1 = $companydb->createCollection($CollectionName2);
$redis = Redis::connection();
//$redis->publish('chat-channel', json_encode([['idone' => $uid], ['idtwo' => $fid]]));
$redis->publish('chat-channel', json_encode(['idone' => $uid, 'idtwo' => $fid, 'IOroom' => $roomName, 'collection' => $CollectionName2]));
}
//return view('chat');
$url = "http://localhost:3000";
return Redirect::to($url);
}
}
接收数据的Node.js文件(server.js端口:3000):
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var mongoClientInstance = require('mongodb').MongoClient;
var redis = require('redis');
var php_listener = redis.createClient();
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
php_listener.subscribe('chat-channel');
php_listener.on('message', function(channel, message){
var purchase_data = JSON.parse(message);
let colName = purchase_data.collection;
let roomName = purchase_data.IOroom;
let data = [];
data.push(purchase_data.idone);
data.push(purchase_data.idtwo);
data.push(purchase_data.collection);
data.push(purchase_data.IOroom);
http.listen(process.env.PORT || 3000);
console.log('Server running...');
io.on('connection', function(socket){
socket.join(roomName);
io.sockets.in(roomName).emit('roomChat', data);
});
});
我的问题是:我是User_1点击button2(所以打开与User_2聊天,获取所有信息:websocket_room(我称之为IOroom),mongodb_collection等...)
现在让我假装我是User_3(使用其他浏览器)并点击按钮4(与user_4聊天)我正在加入websocket_room并仍然从User_1获取所有信息(他点击了哪个按钮)(websocket_room,mongodbcollection等。 ..)Console.log结果为User_3:
(4) [2, 1, "2collection1", "2room1"]
(4) [4, 3, "4collection3", "4room3"]
我错过了什么?我忘记了什么?
回答如下:您的Node.js应用程序有一个奇怪的代码。我认为您不了解代码的每一行。例如:
//this code will add express routeing rule on every message in Redis
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
在您实施聊天之前,您应该做出以下决定:
- 前端如何发送新消息?通过带有Laravel的REST API或带有Node.js的WebSocket?
- 在升级连接到WS期间,前端如何进行身份验证? Node.js会向Laravel或Node发出请求.js会向数据库发出请求吗?
- 您应该将聊天对话存储到任何存储文件系统或数据库吗?
- 你可以使用Nginx或任何类似Nginx的东西来路由你的Node.js和Laravel应用程序吗?