最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • php 使用workerman/gateway制作聊天

    正文概述 转载于:掘金(大鸟成鹏)   2021-01-21   588

    这次使用的是laravel框架:

    1、安装workerman/gateway-worker

    终端项目目录下输入:

    composer require workerman/gateway-worker

    2、创建workerman启动文件

    php artisan make:command Workerman

    <?php
    
    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use GatewayWorker\BusinessWorker;
    use GatewayWorker\Gateway;
    use GatewayWorker\Register;
    use Workerman\Worker;
    
    
    class Workerman extends Command
    {
        /**
         * The name and signature of the console command.
         *
         * @var string
         */
        protected $signature = 'workerman {action} {--d}';
    
        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = 'Start a Workerman server.';
    
        /**
         * Create a new command instance.
         *
         * @return void
         */
        public function __construct()
        {
            parent::__construct();
        }
    
        /**
         * Execute the console command.
         *
         * @return mixed
         */
        public function handle()
        {
            //
            global $argv;
            $action = $this->argument('action');
     
            $argv[0] = 'artisan workerman';
            $argv[1] = $action;
            $argv[2] = $this->option('d') ? '-d' : '';   //必须是一个-,上面定义命令两个--,后台启动用两个--
     
            $this->start();
        }
    
        private function start()
        {
            $this->startGateWay();
            $this->startBusinessWorker();
            $this->startRegister();
            Worker::runAll();
        }
     
        private function startBusinessWorker()
        {
            $worker                  = new BusinessWorker();
            $worker->name            = 'BusinessWorker';
            $worker->count           = 1;
            $worker->registerAddress = '127.0.0.1:1236';
            $worker->eventHandler    = \App\GatewayWorker\Events::class;
        }
     
        private function startGateWay()
        {
            $gateway = new Gateway("websocket://0.0.0.0:2346");
            $gateway->name                 = 'Gateway';
            $gateway->count                = 1;
            $gateway->lanIp                = '127.0.0.1';
            $gateway->startPort            = 2300;
            $gateway->pingInterval         = 30;
            $gateway->pingNotResponseLimit = 0;
            $gateway->pingData             = '{"type":"ping"}';
            $gateway->registerAddress      = '127.0.0.1:1236';
        }
     
        private function startRegister()
        {
            new Register('text://0.0.0.0:1236');
        }
    
    }
    

    3、创建事件监听文件

    创建一个 app/GatewayWorker/Events.php 文件来监听处理 workman 的各种事件

    <?php
    namespace App\GatewayWorker;
    
    use GatewayWorker\Lib\Gateway;
    use Illuminate\Support\Facades\Log;
    
    
    class Events
    {
     
        public static function onWorkerStart($businessWorker)
        {
            echo "onWorkerStart\r\n";
        }
     
        public static function onConnect($client_id)
        {
            Gateway::sendToClient($client_id, json_encode(['type' => 'onConnect', 'client_id' => $client_id]));
            // echo $client_id;
            echo $client_id."登陆成功\r\n";
        }
     
        public static function onWebSocketConnect($client_id, $data)
        {
            echo "onWebSocketConnect\r\n";
        }
     
        public static function onMessage($client_id, $message)
        {
             Gateway::sendToClient($client_id,$message);
             echo $message;
            // Gateway::sendToClient($client_id, json_encode(['type' => 'onMessage', 'client_id' => $client_id, 'name' => json_decode($message)->name]));
     
            // echo "onMessage\r\n";
        }
     
        public static function onClose($client_id)
        {
            Log::info('Workerman close connection' . $client_id);
            echo "onClose\r\n";
        }
     
    }
    

    4、测试。启动workerman服务端

    php artisan workerman start --d
    

     在浏览器 F12 打开调试模式,在 Console 里输入

    ws = new WebSocket("ws://ipaddress:2346");
        ws.onopen = function() {
            ws . send('{"name":"one","user_id":"111"}');
            ws . send('{"name":"two","user_id":"222"}');
        };
        ws.onmessage = function(e) {
            console.log("收到服务端的消息:" + e.data);
        };
        ws.onclose = function(e) {
            console.log("服务已断开" );
        }
    

    console收到服务器端的消息.....

    如在控制器里使用,需要

    public function __construct()
    {
            // 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值(ip不能是0.0.0.0)
        Gateway::$registerAddress = '127.0.0.1:1236';
     
    }
    

    doc2.workerman.net/

    5、长链接使用代码

    后端:

    <?php
    
    namespace App\Http\Controllers\chat;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Redis;
    use App\GatewayWorker\Events;
    use GatewayWorker\Lib\Gateway;
    
    class Chat
    {
        public function __construct()
        {
            // 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值(ip不能是0.0.0.0)
            Gateway::$registerAddress = '127.0.0.1:1236';
     
        }
    
        public function talks()
        {
            return view('chat.talks');
        }
    
        public function talk(Request $request)
        {
            return view('chat.talk');
        }
    
        public function loginConfirm(Request $request)
        {
            $name = $request->post('name');
            if ($name) {
                $user = Redis::sAdd('name',$name);
                // if ($user) {
                    return response()->json(['code'=>200]);
                // }
            }
        }
    
        public function getList(Request $request)
        {
            $to = $request->get('name');
            $list = Redis::sMembers('name');
            foreach ($list as $k=>$v)
            {
                $unread = Redis::hGet('unread_'.$to, $v);
                $list[$k] = array('name'=>$v, 'unread'=>$unread);
            }
            if ($list) {
                return response()->json(['code'=>200, 'list'=>$list]);
            }
        }
    
        public function content(Request $request)
        {
    
            $client_id = $request->post('client_id');
            $content = $request->post('content');
            $from = $request->post('from');
            $to = $request->post('to');
            $plus = strcmp(md5($from), md5($to));
            if ($plus == 0) {
                $res = $from.$to;
            } else if ($plus < 0) {
                $res = $from.$to;
            } else if ($plus >0) {
                $res = $to.$from;
            }
            $data = json_encode(array('from'=>$from, 'to'=>$to, 'message'=>$content, 'time'=>time()),JSON_UNESCAPED_UNICODE,true);
            $keyName = 'mes:'.$res;
            $insert = Redis::rPush($keyName, $data);
            $unread = Redis::hIncrBy('unread_'.$to,$from,1);
            if ($insert&&$unread) {
                Gateway::sendToGroup($res,$data);
                return response()->json(['code'=>200]);
            }
    
        }
    
        public function mesList(Request $request)
        {
            $from = $request->get('from');
            $to = $request->get('to');
    
            $plus = strcmp(md5($from), md5($to));
            if ($plus == 0) {
                $res = $from.$to;
            } else if ($plus < 0) {
                $res = $from.$to;
            } else if ($plus >0) {
                $res = $to.$from;
            }
            
            $list = Redis::lrange('mes:'.$res,-10,-1);
            foreach( $list as $k=>$v) {
                $list[$k] = json_decode($v);
            }
            Redis::hSet('unread_'.$from, $to, 0);
            $client_id = $request->get('client_id');
            Gateway::joinGroup($client_id, $res);
            return response()->json(['code'=>200, 'list'=>$list]);
        }
    
        public function mesRead(Request $request)
        {
            $from = $request->input('from');
            $to = $request->input('to');
            Redis::hSet('unread_'.$from, $to, 0);
        }
    }
    

    前端:

    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title></title>
        <link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/open/libs/weui/2.4.1/weui.min.css">
    </head>
    <body style="background-color: #ececec">
    <div class="page">
        <div style="width: 100%;background-color: #00AAAA" @click="back">《后退</div>
        <div v-for="list in lists">
            <div v-if="list.from==master" style="text-align: right">
                <span style="background-color: yellowgreen;">@{{ list.message }}</span>
                <span style="">@{{list.from}}</span>
            </div>
            <div v-else style="text-align: left">
                <span style="">@{{list.from}}</span>
                <span style="background-color: white;">@{{ list.message }}</span>
            </div>
        </div>
        <div style="position: fixed;bottom: 0;">
            <input type="text" v-model="content" style="height: 2rem" placeholder="填写聊天内容"/>
            <a href="javascript:" class="weui-btn weui-btn_mini weui-btn_primary" style="line-height: initial;overflow: initial" @click="send">发送</a>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <script src="https://unpkg.com/axios@0.21.1/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
    <script type="text/javascript">
    
        var Ca = new Vue({
            el:".page",
            data(){
                return{
                    content: '',
                    lists: [],
                    master: '',
                    client_id: ''
                }
            },
            created: function(){
                this.master = Cookies.get('name');
                ws = new WebSocket("ws://www.dzzzh.com:2346");
                    ws.onmessage = function(e) {
                        console.log(e)
                        let eJson = JSON.parse(e.data)
                        if (eJson.type == "onConnect") {
                            // Cookies.set('client_id', eJson.client_id)
                            Ca.client_id = eJson.client_id
                            Ca.mesList()
                        }
                        if (eJson.message){
                            Ca.lists.push(eJson)
                            Ca.read()
                        }
                        console.log("收到服务端的消息:" + e.data);
                    };
            },
            methods:{
                back(){
                    window.location.href="{{url('/talks')}}"
                },
                send(){
                    axios.post("{{url('/api/content')}}",{
                        from: "{{$_GET['name']}}",
                        to: "{{$_GET['to']}}",
                        content: this.content,
                        client_id: this.client_id
                    }).then(function(res){
                        if (res.data.code === 200) {
                            Ca.content = '';
                        }
                    }).catch(function(err){
                        console.error(err)
                    })
    
                },
                mesList(){
                    axios.get("{{url('/api/mesList')}}",{params:{
                        from:"{{$_GET['name']}}",
                        to:"{{$_GET['to']}}",
                        client_id: Ca.client_id
                    }}).then(function(res){
                        if (res.data.code === 200) {
                            Ca.lists = res.data.list
                        }
                    }).catch(function(err){
                        console.error(err)
                    })
                },
                read(){
                    axios.put("{{url('/api/mesRead')}}",{params:{
                        from: "{{$_GET['name']}}",
                        to: "{{$_GET['to']}}",
                    }}).then(function(res){
                        console.log(res)
                    }).catch(function(err){
                        console.log(err)
                    })
                }
            }
        })
    </script>
    </body>
    </html>
    

    起源地下载网 » php 使用workerman/gateway制作聊天

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元