thinkphp5 +swoole 一对一聊天实现源码

namespace app\Console;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
class WebSocket extends Command
{
    // Server 实例
    protected $server;
    protected function configure(){
        $this->setName('websocket:start')->setDescription('Start Web Socket Server!');
    }
    protected function execute(Input $input, Output $output){
        // 监听所有地址,监听 10000 端口
        $this->server = new \swoole_websocket_server('0.0.0.0', 9997);
        $this->server->set([
            'max_conn' => 50,
            'max_request' => 50,
            'daemonize' => 1
        ]);
        // 设置 server 运行前各项参数
        // 调试的时候把守护进程关闭,部署到生产环境时再把注释取消
        // $this->server->set([
        //     'daemonize' => true,
        // ]);
        
        // 设置回调函数
        $this->server->on('Open', [$this, 'onOpen']);
        $this->server->on('Message', [$this, 'onMessage']);
        $this->server->on('Close', [$this, 'onClose']); 
        $this->server->start();
        // $output->writeln("WebSocket: Start.\n");
    }
    
    // 建立连接时回调函数
    public function onOpen(\swoole_websocket_server $server, \swoole_http_request $request){
        echo "用户{$request->fd}加入。\n";
    }
    
    // 收到数据时回调函数
    public function onMessage(\swoole_websocket_server $server, \swoole_websocket_frame $frame){   




        //接受的json数据转化成数据
        $data = json_decode($frame->data,true);
       
        //判断是否是首次连接
        //dump($data) . "\n";
        //添加时间戳
        $data['addtime'] = time();
        //判断是有内容发送,如果没有则是第一次连接
        if(isset($data['content'])){


            
            //找到接收消息者的fd
            $receive_id = db('fd')->where('user_id',$data['receive_id'])->find();
            //判断是否存在fd,如果不存在fd则表明已下线
            if($receive_id['fd']){
                //保存发送的数据
                $res = db('chat')->insertGetId($data);
                //发送消息给接收者
                $server->push($receive_id['fd'], $data['content']);
            }else{


                //设置未读消息
                $data['read_is'] = 1;
                //保存发送的数据
                $res = db('chat')->insertGetId($data);
                echo "该用户已下线。 \n";
            }


        }else{


            //重新连接或者首次连接绑定fd
            //获取当前用户
            $user_id = db('fd')->find($data['user_id']);
            //判断是否存在用户
            if($user_id){


                //找到接收消息者的fd
                $receive_id = db('fd')->where('user_id',$data['receive_id'])->find();
                if($receive_id['fd']){
                    //保存发送内容
                    $res = db('chat')->insert($data);
                }else{
                    //设置未读消息
                    $data['read_is'] = 1;
                    //保存发送的数据
                    $res = db('chat')->insert($data);
                }
                
                //更新fd
                db('fd')->where('user_id',$data['user_id'])->update(['fd' => $frame->fd]);
            }else{


                //找到接收消息者的fd
                $receive_id = db('fd')->where('user_id',$data['receive_id'])->find();
                if($receive_id['fd']){
                    //保存发送内容
                    $res = db('chat')->insert($data);
                }else{
                    //设置未读消息
                    $data['read_is'] = 1;
                    //保存发送的数据
                    $res = db('chat')->insert($data);
                }
                //插入新用户数据
                $data_fd = [
                   'user_id' => $data['user_id'] ,
                   'fd'      => $frame->fd
                ];
                db('fd')->insert($data_fd);
            }
        }
        


        echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}" ."test \n";
       
    }
    


    // 连接关闭时回调函数
    public function onClose($server, $fd){
        db('fd')->where('fd',$fd)->update(['fd' => null]);
        echo "client {$fd} closed \n";
    }


}

你可能感兴趣的:(thinkphp5 +swoole 一对一聊天实现源码)