Login
网站首页 > 文章中心 > 其它

swoole◆websocket◆redis实现一对一聊天

作者:小编 更新时间:2023-09-26 18:43:44 浏览量:110人看过

如同web端的QQ和微信一样,这是一个web端的聊天程序.

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

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

swoole◆websocket◆redis实现一对一聊天

还是感谢大神.

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

服务端代码:


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实现一对一聊天相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!

版权声明:倡导尊重与保护知识产权。未经许可,任何人不得复制、转载、或以其他方式使用本站《原创》内容,违者将追究其法律责任。本站文章内容,部分图片来源于网络,如有侵权,请联系我们修改或者删除处理。

编辑推荐

热门文章