如同web端的QQ和微信一样,这是一个web端的聊天程序.
Redis 实现每个连接websocket的服务都唯一绑定一个用户.通过 用户账号 = websocket fd 存到redis中.
Mysql 实现离线消息池.如果一个用户不在线,则其他用户发送给他的消息暂时存储在mysql.待该用户上线时,再从离线消息池取出发送.
还是感谢大神.
具体参考代码和相应注释:
服务端代码:
php $server = new swoole_websocket_server("0.0.0.0", 9052); $redis = new Redis(); $redis->connect('12⑦0.0.1', 6379); $db = new mysqli('12⑦0.0.1', 'test', 'test', 'thinkphp5'); $server->on('open', function (swoole_websocket_server $server, $request) { echo "server: handshake success with fd{$request->fd}\n";//$request->fd 是客户端id }); $server->on('message', function (swoole_websocket_server $server, $frame) { $data = json_decode($frame->data,true); if($data['flag'] == 'init'){ //用户刚连接的时候初始化,每个用户登录时记录该用户对应的fd $GLOBALS['redis']->set($data['from'], $frame->fd); //处理发给该用户的离线消息 $sql = "SELECT ◆from◆,content FROM thinkphp⑤app_offline WHERE ◆to◆='{$data['from']}' AND ◆from◆='{$data['to']}' AND ◆status◆='0' ORDER BY addtime ASC;"; if ($result = $GLOBALS['db']->query($sql)) { $re = array(); while ($row = $result->fetch_assoc()) { array_push($re, $row); } $result->free(); foreach($re as $content){ $content = json_encode($content); $server->push($frame->fd , $content); } //设置消息池中的消息为已发送 $sql = "UPDATE thinkphp⑤app_offline SET ◆status◆=1 WHERE ◆to◆='{$data['from']}' AND ◆from◆='{$data['to']}';"; $GLOBALS['db']->query($sql); } }else if($data['flag'] == 'msg'){ //非初始化的信息发送,一对一聊天,根据每个用户对应的fd发给特定用户 $tofd = $GLOBALS['redis']->get($data['to']); //消息要发给谁 $fds = []; //所有在线的用户(打开聊天窗口的用户) foreach($server->connections as $fd){ array_push($fds, $fd); } if(in_array($tofd,$fds)){ $tmp['from'] = $data['from']; //消息来自于谁 $tmp['content'] = $data['content']; //消息内容 $re = json_encode($tmp); $server->push($tofd , $re); }else{ //该粉丝不在线(不在聊天室内),将信息发送到离线消息池 $time = time(); $sql = "INSERT INTO thinkphp⑤app_offline (◆to◆,◆from◆,◆content◆,◆status◆,◆addtime◆) VALUES ('{$data['to']}','{$data['from']}','{$data['content']}','0','{$time}');"; $GLOBALS['db']->query($sql); } }else if($data['flag'] == 'group'){ //todo 群聊 }else if($data['flag'] == 'all'){ //全站广播 foreach($server->connections as $fd){ $server->push($fd , $data); } } }); $server->on('close', function ($ser, $fd) { echo "client {$fd} closed\n"; }); $server->start();
数据库DB:
CREATE TABLE ◆app_offline◆ ( ◆id◆ int(11) NOT NULL AUTO_INCREMENT, ◆from◆ varchar(50) DEFAULT NULL COMMENT '离线发送方', ◆to◆ varchar(50) DEFAULT NULL COMMENT '离线接收方', ◆content◆ varchar(1000) DEFAULT NULL COMMENT '发送的离线内容', ◆status◆ tinyint(4) DEFAULT '0' COMMENT '发送状态:0-未发送,1-已发送', ◆addtime◆ int(11) DEFAULT NULL COMMENT '发送方发送时间', PRIMARY KEY (◆id◆) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
以上就是土嘎嘎小编为大家整理的swoole◆websocket◆redis实现一对一聊天相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!