php用redis实现简单的系统消息/订阅消息群发

技术 回首页
1702
头像
众网网络 2018-12-23

本站有一篇文章介绍一对一的审核消息推送https://www.h0376.cn/jie/detail.html?id=66

这一次来说说如系统群发消息或订阅消息推送。

1、相比较一对一的推送,群发消息更加繁杂

一对一的系统消息只需要把信息写入个人账号,而系统群发消息要送达给站点下所有人,不可能一个一个写入到个人账号,不管是存文件还是存数据库。

所以就简单利用redis来实现 。

系统群发消息分两份,一份存数据库,一份存redis,同时记录着结束id,开始时间,结束时间,内容,频道/用户组。。。

$queryinfo=$sql->table('system_gg')->insert(array('title'=>$name,'contents'=>$filename,'starttime'=>$starTime,'endtime'=>$endTime,'mark'=>$markinfo));
//mysql

$msginfo=json_encode(array('cname'=>$markinfo,'starttime'=>$starTime,'endtime'=>$endTime,'contents'=>$value));

$redis->hSetNx('Smsg',$queryinfo,$msginfo);//redis利用希哈表 Smsg为key 插入数据的id的为field域,$msginfo里的值为域的值,注意要这个值不能存 array,要转换一下

完成后可以利用redis检查一下,看有没有问题

2、用户获取消息

系统群发消息生成后,并不是像MQ之类的主动推送到所有用户,需要像之前文章写的,客户端定时访问消息接口,消息接口再根据redis里Smsg有无最新消息来反馈给用户,是否有最新系统消息。

$Snums=$redis->hKeys('Smsg');
	if(!empty($Snums)){//从redis中读取系统消息
		foreach($Snums as $key=>$value){
			$Smsg= $check->object_array(json_decode($redis->hGet('Smsg',$value)));
			if($Smsg['endtime']<=time()){
				$redis->hDel('Smsg',$value);//系统消息过期删除
			}else{
				$Smsginfo[$Snums[$key]]=$Smsg;//系统消息未过期则存入array,方便后续调用
			}
		}

3、用户对系统消息的操作

因为系统群发消息是存在redis中的,过期删除,用户点击阅读后发现不感兴趣,删除了,或是这个消息要展示给特定的用户组看的,等等一系列操作如何实现?

还是利用用户消息目录下的另一个txt文档

$check->touchFile($filepath.'smsg.txt'); //先查看是否存在smsg.txt文档
		$sinfomsg=file_get_contents($filepath.'smsg.txt');先读取文档里有没有旧的消息
		if(!empty($sinfomsg)){
		$sinfomsg1=explode(';',$sinfomsg);//截取消息并转成array
		$smsgsinfo=false;
		$smsgs=null;
		foreach($sinfomsg1 as $k=>$v){//循环读取消息
			$sinfo=explode(',', $v);
			if(!empty($sinfo[3])){
				$sinfomsg2[]=$sinfo[3];将文档内消息id记录下来,到时候redis里的消息作比对
				if($sinfo[2]=='1' && array_key_exists($sinfo[3],$Smsginfo)==false){//1为标记已读消息 array_key_exitst用于比对redis消息,
                                                                                              //看是否还存在该消息,不存在则给个提示
					$smsgsinfo=true;
				}else{//如果消息没过期,就记录下来
					$smsgs .=';'.$v;
				}
			}else{
				$sinfomsg2[]=null;
			}
		}
		if($smsgsinfo==true){//如果消息有过期的,就把没过期的消息重写smsg.txt内
			file_put_contents($filepath.'smsg.txt', $smsgs);
		}
	}else{
			$sinfomsg2=array();
		}

$Snum=array_diff($Snums, $sinfomsg2);//redis内消息和用户smsg.txt内消息比对,如果有新消息就提示用户有新消息要查收 //print_r($sinfomsg2); if(is_array($Snum)){ $count +=count($Snum); }

用户对消息的删除操作:

对于系统群发的消息不能直接删除,只能等消息过期之后,程序来删除,当用户来删除系统消息时,我们需要将用户message里的那条消息记录参数设置成已读即可。

$Snums=$redis->hKeys('Smsg');
	if(!empty($Snums)){ //从redis中读取系统消息
		
		$sinfomsg=file_get_contents($filepath.'smsg.txt');//读取用户smsg.txt
		if(!empty($sinfomsg)){
			$sinfomsgs=null;
			$sinfomsg1=explode(';',$sinfomsg);
			foreach($sinfomsg1 as $k=>$v){分割后循环读取详细消息
				$sinfo=explode(',', $v);
				if(isset($sinfo[2])){
					if($sinfo[2]=='0'){//如果这条消息的标记是未读取(0),则改为已读(1)
						$sinfomsgs .=';'.$sinfo[0].','.$sinfo[1].',1,'.$sinfo[3].','.$sinfo[4];
					}else{//如果消息状态不为0(未读)刚直接记录
						$sinfomsgs .=';'.$v;
					}
				}
			}
			file_put_contents($filepath.'smsg.txt', $sinfomsgs);//完成后重新写入数据smgs.txt
		}
		
	}

以上为php用redis实现简单的系统消息/订阅消息群发,如需要共同探讨请加QQ:756651572