<?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聊天记录的更多相关文章

  1. Canvas + WebSocket + Redis 实现一个视频弹幕

    原文出自:https://www.pandashen.com 页面布局 首先,我们需要实现页面布局,在根目录创建 index.html 布局中我们需要有一个 video 多媒体标签引入我们的本地视频, ...

  2. Swoole Redis 连接池的实现

    概述 这是关于 Swoole 入门学习的第九篇文章:Swoole Redis 连接池的实现. 第八篇:Swoole MySQL 连接池的实现 第七篇:Swoole RPC 的实现 第六篇:Swoole ...

  3. Spring Boot 2.x 系列教程:WebFlux 系列教程大纲(一)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! WebFlux 系列教程大纲 一.背景 大家都知道,Sprin ...

  4. laravel 事件广播

    Laravel 5.1 之中新加入了事件广播的功能,作用是把服务器中触发的事件通过websocket服务通知客户端,也就是浏览器,客户端js根据接受到的事件,做出相应动作.本文会用简单的代码展示一个事 ...

  5. Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)

    1 开发需要环境 工欲善其事,必先利其器.在正式开发之前我们检查好需要安装的拓展,不要开发中发现这些问题,打断思路影响我们的开发效率. 安装 swoole 拓展包 安装 redis 拓展包 安装 la ...

  6. Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息)

    推荐阅读:Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)​ 需求分析 我们假设有一个需求,我在后端点击按钮 1,首页弹出 “后端触发了按钮 1”.后端点了 ...

  7. SpringBoot 和Vue前后端分离入门教程(附源码)

    作者:梁小生0101 juejin.im/post/5c622fb5e51d457f9f2c2381 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计 ...

  8. Spring Boot WebFlux-导读

    背景 大家都知道,Spring Framework 是 Java/Spring 应用程序跨平台开发框架,也是 Java EE(Java Enterprise Edition) 轻量级框架,其 Spri ...

  9. 脚踏实地的Netty源码研究笔记——开篇

    1. 脚踏实地的Netty源码研究笔记--开篇 1.1. Netty介绍 Netty是一个老牌的高性能网络框架.在众多开源框架中都有它的身影,比如:grpc.dubbo.seata等. 里面有着非常多 ...

随机推荐

  1. Storm入门(七)可靠性机制代码示例

    一.关联代码 使用maven,代码如下. pom.xml  参考 http://www.cnblogs.com/hd3013779515/p/6970551.html MessageTopology. ...

  2. 【Android Studio安装部署系列】九、Android Studio常用配置以及快捷键

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 整理Android Studio的常用配置和快捷键. 常用配置 显示行号 临时显示 永久显示 File——Settings——Edi ...

  3. 谓词筛选表达式的扩展库PredicateLib

    PredicateLib PredicateLib是谓词筛选表达式Expression<Func<T, bool>>的一个扩展库,它可以帮你创建一个复杂且灵活的Expressi ...

  4. Python实战171202元组访问

    学生信息系统中数据为固定格式: (名字,年龄,性别,邮箱地址,......) 学生数量很大为了减小存储开销,对每个学生信息用元组表示: ('jim',18,'male','jim8765@gmail. ...

  5. SmartSql Config配置

    Demo <?xml version="1.0" encoding="utf-8" ?> <SmartSqlMapConfig xmlns=& ...

  6. RDIFramework.NET V3.3 Web版新增系统公告、系统新闻模块方便需要的客户

    1.系统新闻功能描述 在RDIFramework.NET V3.3版本中新增了系统新闻模块,用户可以根据实际情况做相应应用,如用在内部业务系统的展示中或网站上新闻的展示.新闻可以分类进行管理,非常的实 ...

  7. js事件循环机制辨析

     对于新接触js语言的人来说,最令人困惑的大概就是事件循环机制了.最开始这也困惑了我好久,花了我几个月时间通过书本,打代码,查阅资料不停地渐进地理解他.接下来我想要和大家分享一下,虽然可能有些许错误的 ...

  8. 【设计模式+原型理解】第一章:使用Javascript来巧妙实现经典的设计模式

    刚开始学习设计模式之前,我是没想说要学习设计模式的,我只是因为想学习JS中的原型prototype知识,一开始我想JS中为什么要存在原型这个东西?于是慢慢通过原型而接触到设计模式,后来发现我这个过程是 ...

  9. 【转载】Sqlserver数据库中无自增Id的情况下使用ROW_NUMBER()函数进行数据分页

    在Sqlserver数据库中,如果查询表中含有自增长Id列,一般会采用select Top的方式来数据的分页操作.而实际上很多数据表设计的时候,不一定含有自增长Id列,那么数据库没有Id自增列的时候要 ...

  10. 史上最全office2016 激活码

    现在office版本已经更新到2016了,现在给大家分享Office 2016 各个版本的激活码,记得断网激活哈.(本人使用的是家庭版) Office 2016 Pro Retail 版激活密钥: [ ...