swoole通用类库,不管你用的什么框架,一个类库全部搞定!!!

       研究swoole一段时间了,但是swoole对于新手来说还是有一定的难度的,所以今天研究了下,写了一个通用的类库,这样可以直接在框架中引入调用就可以了,不多说,看代码吧.

 先看一个代码的结构图:

                                      

也许熟悉TP5.1的小伙伴们看出来了,没错,这里面演示的就是在Tp5.0中的调用

先是关键核心的Http.php文件:

<?php
namespace sockets\socket6;
use sockets\socket6\Predis;
require_once 'Predis.php';
/**
 *    socket面向对象的编译
 */
class Http
{
    CONST HOST = '0.0.0.0';
    CONST PORT = '12316';
    public $ws = null;
    public $client = null;
    private $key = 'paiv3@$))(';
    private $prefix = 'paiv3_';
    public $pwd = "/www/wwwroot/wanguopai/swoole/";

    public function __construct()
    {
        // $this->ws=new \swoole_websocket_server(self::HOST,self::PORT,SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
        $this->ws = new \swoole_websocket_server(self::HOST, self::PORT);
        $this->ws->set([
            //心跳检测
            'heartbeat_check_interval' => 60,
            'heartbeat_idle_time' => 600,
            //设置证书,实现wss连接
            // 'ssl_cert_file' => $this->pwd.'pai.wanguo.net.crt',
            // 'ssl_key_file' => $this->pwd.'pai.wanguo.net.key',
        ]);
        //监听新端口
        $this->client = $this->ws->listen("127.0.0.1", 12317, SWOOLE_SOCK_TCP);
        //关闭websocket模式
        $this->client->set([
            'open_websocket_protocol' => false,
        ]);
        $this->ws->on("start", [$this, 'onStart']);
        $this->client->on("receive", [$this, 'onReceive']);
        $this->ws->on('message', [$this, 'onmessage']);
        $this->ws->on('close', [$this, 'onclose']);
        $this->client->on('close', [$this, 'oncloses']);
        $this->ws->start();
    }

    //监听数据接收事件
    public function onReceive($serv, $fd, $from_id, $data)
    {
        $data = json_decode($data, true);
        //成交
        if ($data['type'] == 'done') {
            self::push_room($data['room_id'],$data);
            $data['tips']=$room_id."已成交,最终成交价格:¥".$price."元";
            //推送全部
            self::push_all($data);
        }elseif ($data['type'] == 'msg') {
            //个人
            if ($data['totype']=='single') {
                unset($data['totype']);
                $id=$data["toid"];
                unset($data['toid']);
                self::push_single($id,$data);
            //房间
            }elseif ($data['totype']=='room') {
                unset($data['totype']);
                $id=$data["toid"];
                unset($data['toid']);
                self::push_room($id,$data);
            //全部
            }elseif ($data['totype']=='all'){
                unset($data['totype']);
                unset($data['toid']);
                self::push_all($data);
            }
        }else{
            //出价 开始 结束
            self::push_room($data['room_id'],$data);
            //结束的时候清除对应redis
            if ($data['type'] == 'end') {
                $push_arr=Predis::getInstance()->smembers('room_id'.$data['room_id']);
                //获取该房间下用户的fd
                $fds=[];
                foreach ($push_arr as $v) {
                    $fds=Predis::getInstance()->smembers(substr($v,6));     //smembers自动写入,所以要截取掉
                    foreach ($fds as $vv) {
                        Predis::getInstance()->del(substr($vv,6));                       //删除在线的fd字符
                    }
                    Predis::getInstance()->del(substr($v,6));                       //删除在线的用户
                }
                Predis::getInstance()->del('room_id'.$data['room_id']);              //对应的价格
                Predis::getInstance()->hdel('new_price',$data['room_id']);              //对应的价格
            }
        }
    }
    /**
     *   推送房间所有人
     *   $room_id    当前房间id
     *   $arr    组装数据
     */
    public function push_room($room_id, $arr)
    {
        //获取该房间下的用户
        $push_arr = Predis::getInstance()->smembers('room_id' . $room_id);
        //获取该房间下用户的fd
        $fds = [];
        foreach ($push_arr as $k => $v) {
            $fds = Predis::getInstance()->smembers(substr($v, 6));     //smembers自动写入,所以要截取掉
            foreach ($fds as $vv) {
                //推送
                $this->ws->push(substr($vv, 8), json_encode($arr));
            }
        }
    }
    /**
    *   推送消息给所有人
    *   $arr 通知的消息
    */
    public function push_all($arr)
    {
        //获取所有人的fd
        $fd=Predis::getInstance()->keys("fd*");
        foreach ($fd as $k => $v) {
            $v=str_replace("paiv3_fd","",$v);
            $this->ws->push($v, json_encode($arr));
        }
    }
    /**
    *   推送给个人
    *   $arr 通知的消息   
    *
    */
    public function push_single($id,$arr)
    {
        $fds=Predis::getInstance()->keys("fd*");
        foreach ($fds as $k => $v) {
            //解析fd下的uid信息
            $user=json_decode(Predis::getInstance()->gets($v), true);
            //判断所有uid的fd连接
            if ($user['uid'] == $id) {
                $fd[]=str_replace("paiv3_fd","",$v);
            }
        }
        foreach ($fd as $v) {
            $this->ws->push($v, json_encode($arr));
        }
    }

    /**
     * 设置进程名,为后续平滑重启进程
     * @param $server
     */
    public function onStart($server)
    {
        swoole_set_process_name("live_master");
    }

    /**
     * 监听接收事件的回调
     */
    public function onmessage($server, $frame)
    {
        //在接收数据的时候进行推送
        $data = json_decode($frame->data, true);
        if (empty($data["room_id"]) || empty($data["uid"])) {
            return flase;
        }
        //加入组集合(集合)
        Predis::getInstance()->sadd('group', $data['room_id']);
        //加入分组(集合)
        Predis::getInstance()->sadd('room_id' . $data['room_id'], 'room_id' . $data['room_id'] . '_' . $data['uid']);
        //加入会员fd的集合(集合)
        Predis::getInstance()->sadd('room_id' . $data['room_id'] . '_' . $data['uid'], 'fd' . $frame->fd);
        //创建fd的json数据(字符)
        $json['room_id'] = $data['room_id'];
        $json['uid'] = $data['uid'];
        Predis::getInstance()->set('fd' . $frame->fd, json_encode($json));
        //组装发送的数据
        $arr['name'] = $data['name'];
        $arr['uid'] = $data['uid'];
        $arr['type'] = "join";
        $arr['num'] = Predis::getInstance()->scard('room_id' . $data['room_id']);
        //推送
        self::push_room($data['room_id'], $arr);
    }

    /**
     * 监听关闭事件的回调
     */
    public function onclose($ser, $fd)
    {
        //先获取字符fd,并得到room_id和uid
        $data = json_decode(Predis::getInstance()->get('fd' . $fd), true);
        //删除用户该次的fd
        Predis::getInstance()->srem('room_id' . $data['room_id'] . '_' . $data['uid'], 'fd' . $fd);
        //删除字段
        Predis::getInstance()->del('fd' . $fd);
        //判断是否为空
        if (empty(Predis::getInstance()->smembers('room_id' . $data['room_id'] . '_' . $data['uid']))) {
            //删除该用户的uid
            Predis::getInstance()->del('room_id' . $data['room_id'] . '_' . $data['uid']);
            //删除分组里面该用户信息
            Predis::getInstance()->srem('room_id' . $data['room_id'], 'room_id' . $data['room_id'] . '_' . $data['uid']);
            //本地房间推送
            $arr['type']='offline';
            $arr['num']=Predis::getInstance()->scard('room_id' . $data['room_id']);
            self::push_room($data['room_id'],$arr);
        }
    }


    public function oncloses($ser, $fd)
    {

    }
}

new Http();


然后是Predis.php

<?php
namespace sockets\socket6;
/**
 * Created by PhpStorm.
 * User: baidu
 * Date: 18/3/26
 * Time: 上午3:52
 */
class Predis {

    //redis的前缀
    private $redis_fix='paiv3_';

    public $redis = "";
    /**
     * 定义单例模式的变量
     * @var null
     */
    private static $_instance = null;

    public static function getInstance() {
        if(empty(self::$_instance)) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    private function __construct() {
        $this->redis = new \Redis();
        $result = $this->redis->connect('127.0.0.1',6379);
        if($result === false) {
            throw new \Exception('redis connect error');
        }
    }

    /**
     * set
     * @param $key
     * @param $value
     * @param int $time
     * @return bool|string
     */
    public function set($key, $value, $time = 0 ) {
        if(!$key) {
            return '';
        }
        if(is_array($value)) {
            $value = json_encode($value);
        }
        if(!$time) {
            return $this->redis->set($this->redis_fix.$key, $value);
        }
        return $this->redis->setex($this->redis_fix.$key, $time, $value);
    }

    /**
     * get
     * @param $key
     * @return bool|string
     */
    public function get($key) {
        if(!$key) {
            return '';
        }

        return $this->redis->get($this->redis_fix.$key);
    }

    public function gets($key)
    {
        return $this->redis->get($key);
    }

    /**
     * @param $key
     * @return array
     */
    public function smembers($key) {
        return $this->redis->sMembers($this->redis_fix.$key);
    }
    public function srem($key,$valus) {
        return $this->redis->sRem($this->redis_fix.$key,$this->redis_fix.$valus);
    }
    public function scard($key) {
        return $this->redis->sCard($this->redis_fix.$key);
    }

    public function lpush($key,$date)
    {
        return $this->redis->lpush($this->redis_fix.$key,$date);
    }

    public function lrange($key,$start,$end)
    {
        return $this->redis->lrange($this->redis_fix.$key,$start,$end);
    }
    public function del($key)
    {
        return $this->redis->del($this->redis_fix.$key);
    }

    public function incr($key)
    {
        return $this->redis->incr($this->redis_fix.$key);
    }
    public function llen($key)
    {
        return $this->redis->llen($this->redis_fix.$key);
    }
    public function lpop($key)
    {
        return $this->redis->lpop($this->redis_fix.$key);
    }
    public function sadd($key,$val)
    {
        return $this->redis->sadd($this->redis_fix.$key,$this->redis_fix.$val);
    }
    //hash
    public function hset($key,$name,$val)
    {
        return $this->redis->hset($this->redis_fix.$key,$this->redis_fix.$name,$val);
    }

    public function hexists($key,$name)
    {
        return $this->redis->hexists($this->redis_fix.$key,$this->redis_fix.$name);
    }

    public function hgetall($key)
    {
        return $this->redis->hgetall($this->redis_fix.$key);
    }
    public function hget($key,$filed)
    {
        return $this->redis->hget($this->redis_fix.$key,$this->redis_fix.$filed);
    }
    public function hvals($key)
    {
        return $this->redis->hvals($this->redis_fix.$key);
    }
    public function hdel($key,$name)
    {
        return $this->redis->hdel($this->redis_fix.$key,$this->redis_fix.$name);
    }
    public function keys($key)
    {
        return $this->redis->keys($this->redis_fix.$key);
    }


    /**
     * @param $name
     * @param $arguments
     * @return array
     */
    public function __call($name, $arguments) {
        //echo $name.PHP_EOL;
        //print_r($arguments);
        if(count($arguments) != 2) {
            return '';
        }
        $this->redis->$name($arguments[0], $arguments[1]);
    }
}

最后也就是引入的类库Socket6.php

<?php
namespace sockets\socket6;
class Socket6
{
    //出价
    public static function bidding($room_id,$name,$price,$price_list){
        $data['type']='bidding';
        $data['room_id']=$room_id;
        $data['name']=$name;
        $data['price']=$price;
        $data['price_list']=$price_list;
        self::push(json_encode($data));
    }

    //开始
    public static function start($room_id){
        $data['type']="start";
        $data['room_id']=$room_id;
        $data['start_time']=date('Y-m-d H:i:s');
        self::push(json_encode($data));
    }

    //成交
    public static function done($room_id,$name,$price){
        $data['type']="done";
        $data['room_id']=$room_id;
        $data['name']=$name;
        $data['price']=$price;
        self::push(json_encode($data));
    }

    //结束
    public static function end($room_id){
        $data['type']="end";
        $data['room_id']=$room_id;
        $data['end_time']=date('Y-m-d H:i:s');
        self::push(json_encode($data));
    }

    //消息通知
    public static function msg($type,$toid,$msg){
        $data['type']="msg"; 
        $data['msg']=$msg;
        $data['toid']=$toid;
        switch ($type) {
            //推给单个用户
            case 'single':
                $data['totype']='single';
                break;
            //推给房间用户
            case 'room':
                $data['totype']='room';
                break;
            //推给全部用户
            case 'all':
                $data['totype']='all';
                break;   
            default:
            break;
        }
        print_r($data);
        self::push(json_encode($data));
    }

    //推送
    public static function push($data){
        $cli = new \swoole_client(SWOOLE_SOCK_TCP);
        //判断连接状态(同步连接模式)
        $res=$cli->connect('127.0.0.1', 12317);
        if (empty($res)) {
            return "连接失败";
        }else{
            $cli->send($data);
        }
    }
}

写到了这里,当点swoole的都知道了,只要在cli中执行php Http.php & 命令就可以了,

完后在TP的常规文件中,执行我们Socket6类中的命令就可以了;

比如说:

<?php
namespace app\index\controller;

use app\common\Client;
use app\common\Predis;
use app\index\model\User;
use sockets\socket6\Predis as redis;
use sockets\socket6\Socket6 as send;

class Index
{
    public function ccc()
    {
        send::bidding(2,"121212121221村田",100,"1,2,3,4");
        send::start(2);
        send::done('2',"刘磊22222222","15000");
        send::end('2');     
        send::msg('single',1,"用户1独立消息!!!");
        echo 13245679;exit();
    }
}

大家可以简单看一下,不过话说我要是写golang也这么的写,会被打死的``````

猜你喜欢

转载自blog.csdn.net/feiwutudou/article/details/81099554