目标:将帖子添加到特定频道时,向该频道的所有已连接订阅用户发送通知。
视图上的关系数据库表:Post,Channels,Users,Channels_Users
目标:创建帖子后,向特定用户组发送通知。
我已经尝试了几种方式,它正如预期的那样工作。但我正在寻找正确的方法。
服务器端:socket.js
Naming conventions: Channel name: channel-1, channel-2, channel-3, .... Namespace name('namespace-'+[channelName]) : namespace-channel-1, namespace-channel-2, ...
var app = require('express')();
var request = require('request');
var http = require('http').Server(app);
var io = require('socket.io').listen(http);
var Redis = require('ioredis');
var redis = new Redis(####, 'localhost');
// Get all channels from Database and loop through it
// subscribe to redis channel
// initialize namespace inorder to send message to it
for(var i=1; i=<50; i++) {
redis.subscribe('channel-'+i);
io.of('/namespace-channel-'+i).on('connection', function(socket){
console.log('user connected');
});
}
// We have been subscribed to redis channel so
// this block will hear if there is any new message from redis server
redis.on('message', function(channel, message) {
message = JSON.parse(message);
// send message to specific namespace, with event = newPost
io.of('/namespace-'+channel).emit('newPost', message.data);
});
//Listen
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
客户端:Angularjs Socket工厂代码:(提及主套接字代码)
// userChannels: user subscribed channels array
// Loop through all channel and hear for new Post and
// display notification if there is newPost event
userChannels.forEach(function (c) {
let socket = {};
console.info('Attempting to connect to namespace'+c);
socket = io.connect(SOCKET_URL + ':3000/namespace-'+c, {query: "Authorization=token"});
socket.on('connect',function(){
if(socket.connected){
console.info("namespace-" + c + " Connected!");
// On New post event for this name space
socket.on('newPost', function(data) {
/* DISPLAY DESKTOP NOTIFICATION */
});
}
});
});
在创建新帖子时将数据发布到Redis服务器
$data = [
'event' => 'newPost',
'data' => [
'title' => $postTitle,
'content' => $postContent
]
];
$redisChannel = "channel-" . $channelId; // As per our naming conventions
Redis::publish($redisChannel, json_encode($data));
用户正在为他们订阅的频道正确收到通知。
问题1:我不确定这是实现此通知事项的最佳解决方案。
问题2:当用户在多个浏览器选项卡中打开相同的应用程序时,它会收到所有这些选项卡的通知。它应该只发送一个通知。这与redis端服务器端的用户管理有关。我也不确定这一部分。
我非常感谢您对此的建议/帮助。先感谢您。