Swoole实现Websocket推送

Swoole实现Websocket推送

因为网上没有很具体的相关文档,只能摸着石头过河,现功能已经大致实现在这里插入图片描述

<?php
$config = require('/config/swoole.php');
class Websocket {
    public $server;
    private $config;
    public function __construct($config) {
        $this->config = $config;
        $server = new Swoole\WebSocket\Server($this->config['web_host'],$this->config['web_port']);
        $this->server = $server; 
        $this->server->set([
            'worker_num'               => 8,
            'daemonize'                => 1,
            'backlog'                  => 128,
            'max_request'              => 10000,
            'heartbeat_check_interval' => 60,
            'task_worker_num'          => 24,
        ]);
        $process = new Swoole\Process(function($process) use ($server) {
            while (true) {
                $show_market_list = $this->getRealMarket();
                if ($show_market_list) {
                    foreach ($this->server->connections as $conn) {
                        $this->server->push($conn,json_encode(['type' => 'market','date' => $show_market_list]));
                    }
                }
                sleep(1);
            }
        });
        $newprocess = new Swoole\Process(function($process) use ($server){
            while (true) {
                $redis = $this->newRedis();
                $new_list = $redis->hGetALL('swoole_new_push');
                if ($new_list) {
                    //把消息推给所有用户
                    foreach ($new_list as $k => $v) {
                        //查找用户的fd   检查用户是否在线
                        $user_fd = $redis -> hGet('swoole_uid_fd',$k);
                        if ($user_fd) {
                            $this->server->push($user_fd,json_encode(['type' => 'new','date' => $v]));
                        }
                    }
                }
                sleep(1);
            }
        });
        $this->server->addProcess($newprocess);
        $this->server->addProcess($process);
        $this->server->on('handshake',function($request,$response){
            $getAllMarket = $this->getAllMarket();
            $this->server -> push($request->fd,json_encode($getAllMarket));
        });
        $this->server->on('open', function (swoole_websocket_server $server, $request) {

        });
        $this->server->on('task',function(swoole_server $server, $task_id, $from_id, $data){
            $task = json_decode($data['type'],1);
            switch ($task['type']) {
                //K线
                case 'kline':
                    $result['type']            = $task['type'];
                    $result['kline_time_type'] = $task['kline_time_type'];
                    $result['market']          = $task['market'];
                    $result['data']            = $this->getKlineDate($task['kline_time_type'],$task['market']);
                    $result['history']         = $this->getMarketRecord($task['market']);
                    $server -> push($data['fd'],json_encode($result));
                break;
                //用户注册
                case 'login':
                    $token = $task['token'];
                    $redis = $this->newRedis();
                    $uid   = $redis->hGet('user_token',$token);
                    if ($uid) {
                        //找到了 用户的uid
                        $redis -> hSet('swoole_uid_fd',$uid,$data['fd']);
                        $redis -> hSet('swoole_fd_uid',$data['fd'],$uid);
                        $result['type'] = 'login';
                        $result['code'] = 200;
                    }else{
                        $result['type'] = 'login';
                        $result['code'] = 400;
                    }
                    $server -> push($data['fd'],json_encode($result));
                break;
                //响应消息
                case 'respond':
                    $token = $task['token'];
                    $redis = $this->newRedis();
                    $uid   = $redis->hGet('user_token',$token);
                    if ($uid) {
                        $redis->hDel('swoole_new_push',$uid);
                        $result['type'] = 'respond';
                        $result['code'] = 200;
                    }else{
                        $result['type'] = 'respond';
                        $result['code'] = 400;
                    }
                    $server -> push($data['fd'],json_encode($result));
                break;
                default:
                    break;
            }
        });
        $this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
            $task['type'] = $frame->data;
            $task['fd']   = $frame->fd;
            $server -> task($task);
        });
        $this->server->on('close', function ($server, $fd) {
           //删除用户在线
           $redis = $this->newRedis();
           $uid   = $redis -> hGet('swoole_fd_uid',$fd);
           if ($uid) {
               $redis -> hDel('swoole_uid_fd',$uid);
               $redis -> hDel('swoole_fd_uid',$fd);
           }
        });
        $this->server->on('request', function ($request, $response) {

        });
        $this->server->start();
    }
    //K线数据
    public function getKlineDate($type,$market){
        $redis = $this->newRedis();
        $date  = $redis->hGet($type,$market);
        return $date;
    }
    public function getMarketRecord($market){
        $redis                      = $this->newRedis();
        $result['yest_close_price'] = $redis->hget('yest_close_price',$market);
        $result['today_open_price'] = $redis->hget('today_open_price',$market);
        $result['today_low_price']  = $redis->hget('today_low_price',$market);
        $result['today_high_price'] = $redis->hget('today_high_price',$market);
        return $result;
    }
    //获取全部行情
    public function getAllMarket(){
            $redis            = $this->newRedis();
            $market_buy_list  = $redis -> HgetAll('real_market_buy');
            $market_sell_list = $redis -> HgetAll('real_market_sell');
            $market_real_list = $redis->HgetAll('real_market');
            foreach ($market_real_list as $k => $v) {
                $show_market_list[$k]['real'] = $v;
                $show_market_list[$k]['sell'] = $market_sell_list[$k];
                $show_market_list[$k]['buy']  = $market_buy_list[$k];
            }
            return $show_market_list;
    }

    //获取变动的行情 进行广播
    public function getRealMarket(){
            $redis            = $this->newRedis();
            $market_buy_list  = $redis -> HgetAll('real_market_buy');
            $market_sell_list = $redis -> HgetAll('real_market_sell');
            $market_real_list = $redis -> HgetAll('real_market');
            foreach ($market_real_list as $k => $v) {
                $result['real'] = $v;
                $result['sell'] = $market_sell_list[$k];
                $result['buy']  = $market_buy_list[$k];
                $history_market = $redis -> hGet('history_market',$k);
                if ($history_market == json_encode($result)) {
                    //这一次读取的数据 和历史数据是一样的
                    continue;
                }else{
                    $show_market_list[$k] = $result;
                }
            }
            return $show_market_list;
    }
    public function newRedis(){
        $redis = new redis();
        $redis -> connect($this->config['read_redis_host'],$this->config['read_redis_prot']);
        $redis -> auth($this->config['read_redis_auth']);
        return $redis;
    }
}
new Websocket($config);
?>

友情链接:软件,APP、微信小程序开发

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值