栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > PHP

PHP用swoole+websocket和redis实现web一对一聊天

PHP 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

PHP用swoole+websocket和redis实现web一对一聊天

Redis 实现每个连接websocket的服务都唯一绑定一个用户。通过 用户账号 = websocket fd 存到redis中。

Mysql 实现离线消息池。如果一个用户不在线,则其他用户发送给他的消息暂时存储在mysql。待该用户上线时,再从离线消息池取出发送。

具体参考代码和相应注释:

connect('127.0.0.1', 6379);
$db = new mysqli('127.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 thinkphp5.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 thinkphp5.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 thinkphp5.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} closedn";
});

$server->start();

客户端代码:




 XST-app
 
 
 
 
 
 
 
 
 
  
 body{background:url(/static/images/yuyin_bg.jpg);background-size:100%;}
 @media all and (min-width: 640px) {
  body,html,.wenwen-footer,.speak_window{width:640px!important;margin:0 auto}
  .speak_window,.wenwen-footer{left:50%!important;margin-left:-320px}
 }
 input,button{outline:none;}
 .wenwen-footer{width:100%;position:fixed;bottom:-5px;left:0;background:#fff;padding:3%;border-top:solid 1px #ddd;box-sizing:border-box;}
 .wenwen_btn,.wenwen_help{width:15%;text-align:center;}
 .wenwen_btn img,.wenwen_help img{height:40px;}
 .wenwen_text{height:40px;border-radius:5px;border:solid 1px #636162;box-sizing:border-box;width:66%;text-align:center;overflow:hidden;margin-left:2%;}
 .circle-button{padding:0 5px;}
 .wenwen_text .circle-button{font-size:14px;color:#666;line-height:38px;}
 .write_box{background:#fff;width:100%;height:40px;line-height:40px;}
 .write_box input{height:40px;padding:0 5px;line-height:40px;width:100%;box-sizing:border-box;border:0;}
 .wenwen_help button{width:95%;background:#42929d;color:#fff;border-radius:5px;border:0;height:40px;}
 #wenwen{height:100%;}
 .speak_window{overflow-y:scroll;height:100%;width:100%;position:fixed;top:50px;left:0;}
 .speak_box{margin-bottom:70px;padding:10px;}
 .question,.answer{margin-bottom:1rem;}
 .question{text-align:right;}
 .question>div{display:inline-block;}
 .left{float:left;}
 .right{float:right;}
 .clear{clear:both;}
 .heard_img{height:60px;width:60px;border-radius:5px;overflow:hidden;background:#ddd;}
 .heard_img img{width:100%;height:100%}
 .question_text,.answer_text{box-sizing:border-box;position:relative;display:table-cell;min-height:60px;}
 .question_text{padding-right:20px;}
 .answer_text{padding-left:20px;}
 .question_text p,.answer_text p{border-radius:10px;padding:.5rem;margin:0;font-size:14px;line-height:28px;box-sizing:border-box;vertical-align:middle;display:table-cell;height:30px;word-wrap:break-word;}
 .answer_text p{background:#fff;}
 .question_text p{background:#42929d;color:#fff;text-align:left;}
 .question_text i,.answer_text i{width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;position:absolute;top:25px;}
 .answer_text i{border-right:10px solid #fff;left:10px;}
 .question_text i{border-left:10px solid #42929d;right:10px;}
 .answer_text p a{color:#42929d;display:inline-block;}
 .write_list{position:absolute;left:0;width:100%;background:#fff;border-top:solid 1px #ddd;padding:5px;line-height:30px;}
  




  
    
    
      

与 {$tonickname} 的聊天

数据表结构:

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

具体效果:


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/38634.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号