图

1、WebSoketServer是在swoole_http_server基础上增加了协议解析

2、完整的webSoket协议请求会被解析并封装在frame对象内

3、新增push方法用于发送websoket数据

回调函数

onHandShake

onOpen

当打开连接时候触发,在触发open事件的时候。可以通过连接的URL来判定用户。防止多联。

前端js代码

        // ws = new WebSocket("wss://wss.wkcto.com/websocket");
        ws = new WebSocket("ws://web.socket.com/websocket/1");
        ws.onopen = function () {
            //发送登录信息
            var data = '{"type":"login","name":"' + "asd" + '"}';
            ws.send(data);
        };
        ws.onmessage = onmessage;

php代码

    public function onOpen($server, $request)
    {
        var_dump($request);
    }

图
图

或者cookie来识别用户谁是谁?在onMessage之前进行判定

onMessage

注意:因为websocketServer是继承httpServer而来的所以也可以用onRequest回调的、那么如何判断连接是否为WebSocket客户端?

通过使用$server->connection_info($fd)获取连接信息,返回的数组中有一项为 websocket_status,根据此状态可以判断是否为WebSocket客户端

图

打印

图

完整的后端的代码

<?php
define('DS',DIRECTORY_SEPARATOR);



class webSocket{
    private $serv;
    private $reids;



    public function __construct($ip="0.0.0.0",$port=1990)
    {
        $this->serv= new swoole_websocket_server($ip, $port);
        $this->serv->set(array(
            'worker_num' =>2,
//            'task_worker_num'=>2,
            'daemonize' => false,
            'max_request' => 10000,
            'dispatch_mode' => 2,
        ));
        $this->redis=new redis();
        $this->redis->connect("127.0.0.1",6378);
        $this->serv->on('workerStart',[$this,'onWorkerStart']);
        $this->serv->on('open',[$this,'onOpen']);
        $this->serv->on('message',[$this,'onMessage']);
        $this->serv->on("close",[$this,"onClose"]);
        $this->serv->start();
    }

    public function getFileData()
    {
        $day=date('d');
        $fileName="online_".$day.".txt";
        $file=__DIR__.DS.$fileName;
        if(!is_file($file)){
            file_put_contents($file,0);
            return 0;
        }else{
            return file_get_contents($file);
        }
    }

    public function setFileData(int $num)
    {
        $day=date('d');
        $fileName="online_".$day.".txt";
        $file=__DIR__.DS.$fileName;
        file_put_contents($file,$num);
    }


    public function onWorkerStart($server, $workerId)
    {

        if($workerId==0){
            //redis订阅连接了websocket可以利用前端发送广播
            $client = new swoole_redis;
            $client->on('message', function (swoole_redis $client, $result) use ($server) {
                if ($result[0] == 'message') {
                    foreach($server->connections as $fd) {
                        $msg=['type'=>"push",'msg'=>$result[2],'fromUser'=>"系统",'toUser'=>0];
                        $server->push($fd, json_encode($msg));
                    }
                }
            });
            $client->connect('127.0.0.1', 6379, function (swoole_redis $redis_client, $result) {
                $redis_client->subscribe('test');
            });

            swoole_timer_tick(1000,function ($timer_id)use($server){
                $onlineNum=$this->getFileData();
                $connectionsNum=count($server->connections);
                if($connectionsNum>$onlineNum){
                    $this->setFileData($connectionsNum);
                }
            });

        }
    }

    public function onOpen($server, $request)
    {
        var_dump($request);
    }

    public function onMessage(swoole_websocket_server $server, $frame)
    {
        $requestMsg=json_decode($frame->data,true);
        if(!is_array($requestMsg)){
            $server->disconnect($frame->fd);
        }
        if($requestMsg['type']=="admin"){
            $this->sendOnlineNum($server,$frame->fd);

        }
        if($requestMsg['type']=="login"){
            $this->sendOnline($server,$frame->fd);
        }
        $msg=['type'=>"online",'msg'=>['bestOnline'=>0,'online'=>0,'date'=>date('Y-m-d H:i:s')],'msgType'=>1];
        $msg=json_encode($msg);

        $server->push($frame->fd, json_encode([]));
    }

    public function sendOnlineNum($server,$fd)
    {
        swoole_timer_tick(1000,function ($timer_id)use($server,$fd){
            $best=$this->getFileData();
            $msg=['type'=>"online",'msg'=>['bestOnline'=>$best,'online'=>count($server->connections),"date"=>date('Y-m-d H:i:s')],'msgType'=>1];
            $msg=json_encode($msg);
            try{
                $bool=@$server->push($fd, $msg);
                if($bool==false){
                    swoole_timer_clear($timer_id);
                }
            }catch (Exception $e){

            }

        });

    }

    public function onClose($server, $fd)
    {

    }

    public function sendOnline($server, $fd)
    {
        var_dump($fd);
        $this->redis->hSet("online",$fd,'1');
        $msg=['type'=>"online",'msg'=>['bestOnline'=>10,'online'=>count($server->connections),"date"=>date('Y-m-d H:i:s')],'msgType'=>1];
        $msg=json_encode($msg);

        $bool=@$server->push($fd, $msg);
    }

}

new webSocket();
Last modification:January 26, 2020
如果觉得我的文章对你有用,请随意赞赏