前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TP5.1.18+swoole实现聊天室

TP5.1.18+swoole实现聊天室

作者头像
李昊天
发布2019-05-26 10:50:19
1.3K0
发布2019-05-26 10:50:19
举报
5b3a9b6705f24.gif
5b3a9b6705f24.gif

TP是最新版本的; 大概实现的有,用户注册,注册完毕之后跳转到登录页面; 登录之后生成身份令牌(token)存到Redis; 在聊天界面没有任何ajax请求,只要在握手的时候有一个http请求,实在是搞不懂一些人,在聊天界面发布消息用ajax去发布,

做了一些处理,一个浏览器里面只能用一个账号,所以测试的时候必须用两个浏览器

之后跳转到聊天界面,然后建立WebSocket握手,在握手的同时携带toekn,以及对方的ID(朋友的ID) ;

后台服务器在OnOpen的时候做一系列的操作,例如(检测token,检测朋友的ID,将自己的ID和fd更新到数据表,fd绑定uid等..); 这些检测都通过之后获取聊天记录,为了效率是拉取和朋友的15条聊天记录;

在OnMessage中获取了发送的数据! 在发送之后检测对方是否在线,如果不在线就不用发送给对方,如果对方在线就将信息push给他!

心跳检测: 每5秒检测一次,如果在100秒没有任何操作将断开连接,断开连接的同时将数据库中的fd清空!

代码很简单,,,但是有个别的问题没有解决,比如在线统计(connections)

下面贴上Socket_Server.php的代码 其他的都是没有什么逻辑的代码!

完整的等之后写完了再发出来吧,大家共同进步!

<?php
/**
 * User: 李昊天
 * Date: 18/7/03
 * Time: 上午4:19
 * Email: haotian0607@gmail.com
 */

namespace app\index\controller;

use app\index\model\Message;
use app\index\model\User as UserModel;
use app\tool\Tool;
use think\facade\Cache;
use swoole_websocket_server;

class Swoole extends \think\swoole\Server
{
    protected static $token;
    protected $host = '127.0.0.1';
    protected $port = 9508;
    protected $serverType = 'socket';
    protected static $uid = '';
    protected $option = [
        'worker_num' => 4, // 设置启动的Worker进程数 
        'daemonize' => false, //守护进程化。
        'backlog' => 128, //Listen队列长度,
        'dispatch_mode' => 2,
        'heartbeat_check_interval' => 5,
        'heartbeat_idle_time' => 100,
    ];


    public function onOpen(swoole_websocket_server $server, \swoole_http_request $req)
    {
        $fd = $req->fd;
        $token = $req->get['token'] ?? '';    //拿到客户端用户ID
        if (!$token) {
            $server->push($fd, Tool::showAjax(['status' => 3, 'message' => '请先登录!']));
            $server->close($fd);
            return;
        }

        $userData = Cache::get($token);
        if (!$userData) {
            $server->push($fd, Tool::showAjax(['status' => 2, 'message' => '用户身份无效,请重新登录!']));
            $server->close($fd);
            return;
        }

        self::$uid = $req->get['friendId'];
        if (self::$uid == $userData['uid']) {
            $server->push($fd, Tool::showAjax(['status' => 2, 'message' => '非法操作!']));
            $server->close($fd);
        }
        $server->bind($fd, $userData['uid']);
        $messages = Message::getMessage($userData['uid']);

        (new UserModel())->where('id', $userData['uid'])->update(['fd' => $req->fd]);
        $arr = $messages->toArray();
        sort($arr);

        $server->push($fd, Tool::showAjax(['status' => 1, 'message' => 'success', 'data' => $arr]));
    }

    public function onMessage(swoole_websocket_server $server, \swoole_websocket_frame $frame)
    {

        $message = $frame->data;
        if (empty($message)) return;
        $data = [
            'uid1' => $server->getClientInfo($frame->fd)['uid'],
            'uid2' => self::$uid,
            'message' => htmlspecialchars($message),
            'send_uid' => $server->getClientInfo($frame->fd)['uid']
        ];
        try {
            (new Message())->save($data);
        } catch (\Exception $e) {
            $server->push($frame->fd, Tool::showAjax(['status' => '2', 'message' => '发送数据失败!']));
        }

        $messages = Message::getMessage($server->getClientInfo($frame->fd)['uid']);
        $friendData = UserModel::geUserDataFd(self::$uid);
        $arr = $messages->toArray();
        sort($arr);


        if ($friendData) {
            $server->push($friendData, Tool::showAjax(['status' => 1, 'message' => 'success', 'data' => $arr]));
        }
        $server->push($frame->fd, Tool::showAjax(['status' => 1, 'message' => 'success', 'data' => $arr]));
    }

    function onClose(\swoole_server $server, int $fd, int $reactorId)
    {
        (new UserModel())->where('fd', $fd)->update(['fd' => '']);
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档