php redis 处理websocket聊天记录
<?php
ini_set('display_errors', 'on'); class chatClass {
private $redis; //这个变量模拟用户当前状态,是否登录,是否可查看
public $checkUserReadable = false; //构造函数链接redis数据库
public function __construct() {
$this -> redis = new Redis();
$this -> redis -> connect('127.0.0.1', '6379');
$this -> redis -> auth('***cnblogs.com/handle');
} /*
发送消息时保存聊天记录
* 这里用的redis存储是list数据类型
* 两个人的聊天用一个list保存
*
* @from 消息发送者id
* @to 消息接受者id
* @meassage 消息内容
*
* 返回值,当前聊天的总聊天记录数
*/
public function setChatRecord($from, $to, $message) {
$data = array('from' => $from, 'to' => $to, 'message' => $message, 'sent' => time()/*, 'recd' => 0*/);
$value = json_encode($data);
//生成json字符串
$keyName = 'rec:' . $this -> getRecKeyName($from, $to);
//echo $keyName;
$res = $this -> redis -> lPush($keyName, $value);
if (!$this -> checkUserReadable) {//消息接受者无法立刻查看时,将消息设置为未读
$this -> cacheUnreadMsg($from, $to);
}
return $res;
} /*
* 获取聊天记录
* @from 消息发送者id
* @to 消息接受者id
* @num 获取的数量
*
* 返回值,指定长度的包含聊天记录的数组
*/
public function getChatRecord($from, $to, $num) {
$keyName = 'rec:' . $this -> getRecKeyName($from, $to);
//echo $keyName;
$recList = $this -> redis -> lRange($keyName, 0, (int)($num));
return $recList;
} /*
* 当用户上线时,或点开聊天框时,获取未读消息的数目
* @user 用户id
*
* 返回值,一个所有当前用户未读的消息的发送者和数组
* 数组格式为‘消息发送者id’=>‘未读消息数目’
*
*/
public function getUnreadMsgCount($user) {
return $this -> redis -> hGetAll('unread_' . $user);
} /*
* 获取未读消息的内容
* 通过未读消息数目,在列表中取得最新的相应消息即为未读
* @from 消息发送者id
* @to 消息接受者id
*
* 返回值,包括所有未读消息内容的数组
*
*
*/
public function getUnreadMsg($from, $to) {
$countArr = $this -> getUnreadMsgCount($to);
$count = $countArr[$from];
$keyName = 'rec:' . $this -> getRecKeyName($from, $to);
return $this -> redis -> lRange($keyName, 0, (int)($count));
} /*
* 将消息设为已读
* 当一个用户打开另一个用户的聊天框时,将所有未读消息设为已读
* 清楚未读消息中的缓存
* @from 消息发送者id
* @to 消息接受者id
*
* 返回值,成功将未读消息设为已读则返回true,没有未读消息则返回false
*/ public function setUnreadToRead($from, $to) {
$res = $this -> redis -> hDel('unread_' . $to, $from);
return (bool)$res;
} /*
* 当用户不在线时,或者当前没有立刻接收消息时,缓存未读消息,将未读消息的数目和发送者信息存到一个与接受者关联的hash数据中
*
* @from 发送消息的用户id
* @to 接收消息的用户id
*
* 返回值,当前两个用户聊天中的未读消息
*
*/
private function cacheUnreadMsg($from, $to) {
return $this -> redis -> hIncrBy('unread_' . $to, $from, 1);
} /*生成聊天记录的键名,即按大小规则将两个数字排序
* @from 消息发送者id
* @to 消息接受者id
*
*
*/
private function getRecKeyName($from, $to) {
return ($from > $to) ? $to . '_' . $from : $from . '_' . $to;
} } /*
* 下面为测试用的代码 ,伪造数据模拟场景
* 假定有两个用户id为2和3 ,2 向 3 发送消息
* $chat = new chatClass(); $chat -> checkUserReadable = true;
for ($i = 0; $i < 20; $i++) {
$chat -> setChatRecord('2', '3', 'message_' . $i);
} echo 'get 20 chat records</br>';
$arr = $chat -> getChatRecord('2', '3', 20);
for ($j = 0; $j < count($arr); $j++) {
echo $arr[$j] . '</br>';
} $chat -> checkUserReadable = false; for ($m = 0; $m < 5; $m++) {
$chat -> setChatRecord('2', '3', 'message_' . $m);
} echo "</br>";
$umsg_1 = $chat -> getUnreadMsgCount(3);
echo "Unread message counts ";
echo "</br>";
print_r($umsg_1);
echo "Unread message content </br> ";
$umsgContent = $chat -> getUnreadMsg(2, 3);
for ($n = 0; $n < count($umsgContent); $n++) {
echo $arr[$n] . '</br>';
}
echo "</br>";
$chat -> setUnreadToRead(2, 3);
$umsg_2 = $chat -> getUnreadMsgCount(3);
echo "</br>";
echo "Unread message counts ";
echo "</br>";
print_r($umsg_2);
*
*/
?>
php redis 处理websocket聊天记录的更多相关文章
- Canvas + WebSocket + Redis 实现一个视频弹幕
原文出自:https://www.pandashen.com 页面布局 首先,我们需要实现页面布局,在根目录创建 index.html 布局中我们需要有一个 video 多媒体标签引入我们的本地视频, ...
- Swoole Redis 连接池的实现
概述 这是关于 Swoole 入门学习的第九篇文章:Swoole Redis 连接池的实现. 第八篇:Swoole MySQL 连接池的实现 第七篇:Swoole RPC 的实现 第六篇:Swoole ...
- Spring Boot 2.x 系列教程:WebFlux 系列教程大纲(一)
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! WebFlux 系列教程大纲 一.背景 大家都知道,Sprin ...
- laravel 事件广播
Laravel 5.1 之中新加入了事件广播的功能,作用是把服务器中触发的事件通过websocket服务通知客户端,也就是浏览器,客户端js根据接受到的事件,做出相应动作.本文会用简单的代码展示一个事 ...
- Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)
1 开发需要环境 工欲善其事,必先利其器.在正式开发之前我们检查好需要安装的拓展,不要开发中发现这些问题,打断思路影响我们的开发效率. 安装 swoole 拓展包 安装 redis 拓展包 安装 la ...
- Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息)
推荐阅读:Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信) 需求分析 我们假设有一个需求,我在后端点击按钮 1,首页弹出 “后端触发了按钮 1”.后端点了 ...
- SpringBoot 和Vue前后端分离入门教程(附源码)
作者:梁小生0101 juejin.im/post/5c622fb5e51d457f9f2c2381 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计 ...
- Spring Boot WebFlux-导读
背景 大家都知道,Spring Framework 是 Java/Spring 应用程序跨平台开发框架,也是 Java EE(Java Enterprise Edition) 轻量级框架,其 Spri ...
- 脚踏实地的Netty源码研究笔记——开篇
1. 脚踏实地的Netty源码研究笔记--开篇 1.1. Netty介绍 Netty是一个老牌的高性能网络框架.在众多开源框架中都有它的身影,比如:grpc.dubbo.seata等. 里面有着非常多 ...
随机推荐
- python检测字符串乱码
import chardet f=open('test.txt','rb') f_read=f.read() f_charInfo=chardet.detect(f_read) print(f_cha ...
- erlang 删除老版本 安装新版本
[root@izbp1buyhgwtrvlxv3u2gqz ~]# yum remove erlang-erts-R16B-03.18.el7.x86_64Loaded plugins: fastes ...
- Packets larger than max_allowed_packet are not allowed(mysql数据查询提示:不允许超过允许的最大数据包)解决方案
问题背景: 首先我的项目运用的时Mysql,在做一个数据更新操作的时候,提示异常:System.Exception:“ExecuteNonQuery:Packets larger than max_a ...
- ping命令的七种用法,看完瞬间成大神
一.ping基本使用详解 在网络中ping是一个十分强大的TCP/IP工具.它的作用主要为: 1.用来检测网络的连通情况和分析网络速度 2.根据域名得到服务器IP 3.根据ping返回的TTL值来判断 ...
- 吴恩达机器学习笔记61-应用实例:图片文字识别(Application Example: Photo OCR)【完结】
最后一章内容,主要是OCR的实例,很多都是和经验或者实际应用有关:看完了,总之,善始善终,继续加油!! 一.图像识别(店名识别)的步骤: 图像文字识别应用所作的事是,从一张给定的图片中识别文字.这比从 ...
- 生产环境中学习Redis
摘要 看到这篇文章,很有借鉴意义,因此写个读书笔记,不算是翻译.想要深入了解,请看原文http://tech.trivago.com/2017/01/25/learn-redis-the-hard-w ...
- springboot打包不同环境配置与shell脚本部署
本篇和大家分享的是springboot打包并结合shell脚本命令部署,重点在分享一个shell程序启动工具,希望能便利工作: profiles指定不同环境的配置 maven-assembly-plu ...
- [开发技巧]·Numpy广播机制的深入理解与应用
[开发技巧]·Numpy广播机制的深入理解与应用 1.问题描述 我们在使用Numpy进行数据的处理时,经常会用到广播机制来简化操作,例如在所有元素都加上一个数,或者在某些纬度上作相同的操作.广播机制很 ...
- [翻译] Linux 内核中的位数组和位操作
目录 Linux 内核里的数据结构 原文链接与说明 Linux 内核中的位数组和位操作 位数组声明 体系结构特定的位操作 通用位操作 链接 Linux 内核里的数据结构 原文链接与说明 https:/ ...
- 自定义Visual Studio.net Extensions 开发符合ABP vnext框架代码生成插件[附源码]
介绍 我很早之前一直在做mvc5 scaffolder的开发功能做的已经非常完善,使用代码对mvc5的项目开发效率确实能成倍的提高,就算是刚进团队的新成员也能很快上手,如果你感兴趣 可以参考 http ...