当前位置:首页 > PHP教程 > php高级应用 > 列表

基于swoole实现多人聊天室

发布:smiling 来源: PHP粉丝网  添加日期:2021-10-01 16:33:22 浏览: 评论:0 

本文实例为大家分享了swoole创建多人多房间聊天室的具体代码,供大家参考,具体内容如下。

核心的swoole代码

基本的cs(client-sercer)结构不变,这里利用的是redis的哈希和set来储存和分组;从而达到了分组,统计,定时推送等功能;最后利用onclose事件来剔除断开的连接,全部代码如下:(没做前端,就不展示了)

核心的swoole ws.php

  1. <?php  
  2.    
  3. namespace app\common;  
  4. require_once 'Predis.php';  
  5. require_once 'Task.php';  
  6. /**  
  7. *  socket面向对象的编译  
  8. */ 
  9. class Ws  
  10. {  
  11.   CONST HOST='0.0.0.0';  
  12.   CONST PORT='9501';  
  13.   public $ws=null;  
  14.   public $getmsg=null;  
  15.   public $server=null;  
  16.    
  17.   public function __construct()  
  18.   {    
  19.     $this->ws=new \swoole_websocket_server(self::HOST,self::PORT);  
  20.     $this->ws->set([  
  21.       //启动task必须要设置其数量  
  22.       'worker_num' => 4,  
  23.       'task_worker_num' => 2,  
  24.       // 'heartbeat_check_interval' => 5,  
  25.       // 'heartbeat_idle_time' => 10,  
  26.     ]);  
  27.     //监听新端口  
  28.     $this->server=$this->ws->listen("127.0.0.1", 9502, SWOOLE_SOCK_TCP);  
  29.     //关闭websocket模式  
  30.     $this->server->set([  
  31.       'open_websocket_protocol' => false,  
  32.     ]);  
  33.    
  34.     $this->ws->on("start", [$this'onStart']);  
  35.     $this->ws->on('open',[$this,'onopen']);  
  36.     $this->server->on("receive", [$this'onReceive']);  
  37.     $this->ws->on('task',[$this,'onTask']);  
  38.     $this->ws->on('finish',[$this,'onFinish']);  
  39.     $this->ws->on('message',[$this,'onmessage']);  
  40.     $this->ws->on('close',[$this,'onclose']);  
  41.     $this->server->on("close", [$this'oncloses']);  
  42.     $this->ws->start();  
  43.   }  
  44.   //监听数据接收事件  
  45.   public function onReceive($serv$fd$from_id$data)  
  46.   {  
  47.     $shuju=json_decode($data,ture);  
  48.     // print_r($shuju).PHP_EOL;  
  49.     if (emptyempty($shuju['data'])) {  
  50.       $this->ws->push(Predis::getInstance()->get('fd'), $data);  
  51.     }else{  
  52.       if (emptyempty($shuju['msg'])) {  
  53.         //执行异步任务  
  54.         $this->ws->task($shuju);  
  55.       }else{  
  56.         $push_arr=Predis::getInstance()->hvals($shuju['data']);  
  57.         // echo "集群是:".print_r($push_arr);  
  58.         foreach ($push_arr as $v) {  
  59.           $this->ws->push($v$shuju['msg']);  
  60.         }  
  61.       }  
  62.     }  
  63.   }  
  64.   /**  
  65.    * 设置进程名,为后续平滑重启进程  
  66.    * @param $server  
  67.    */ 
  68.   public function onStart($server) {  
  69.     swoole_set_process_name("live_master");  
  70.   }     
  71.   /**  
  72.     监听开启事件的回调  
  73.   */ 
  74.   public function onopen($server$request)  
  75.   {  
  76.     print_r("这时的fd是:",$request->fd);  
  77.     Predis::getInstance()->set('fd',$request->fd);  
  78.   }  
  79.      
  80.   /**  
  81.     监听接收事件的回调  
  82.   */ 
  83.   public function onmessage($server$frame)  
  84.   {  
  85.     $server->push($frame->fd, "{$frame->data}");  
  86.   }  
  87.   /**  
  88.     监听关闭事件的回调  
  89.   */ 
  90.   public function onclose($ser$fd)  
  91.   {  
  92.     print_r("你好,我的{$fd}\n");  
  93.     //退出并删除多余的分组fd  
  94.     $group=Predis::getInstance()->sMembers('group');  
  95.     foreach ($group as $v) {  
  96.       $fangjian=Predis::getInstance()->hgetall($v);  
  97.       foreach ($fangjian as $k => $vv) {  
  98.         if ($fd == $vv) {  
  99.           Predis::getInstance()->hdel($v,$k);  
  100.         }  
  101.       }  
  102.     }  
  103.   }  
  104.   public function oncloses($ser$fd)  
  105.   {  
  106.     print_r("这个是client{$fd}\n");  
  107.   }  
  108.    
  109.   /**  
  110.   *  $serv      服务  
  111.   *  $task_id    任务ID,由swoole扩展内自动生成,用于区分不同的任务  
  112.   *  $src_worker_id $task_id和$src_worker_id组合起来才是全局唯一的,不同的worker进程投递的任务ID可能会有相同  
  113.   *  $data      是任务的内容  
  114.   */ 
  115.    public function onTask($serv,$task_id,$src_worker_id,$data)  
  116.   {  
  117.     //引入任务  
  118.     $obj = new Task;  
  119.     $method = $data['data'];  
  120.     $arr = $data['arr'];  
  121.     //发布具体的任务  
  122.     $flag = $obj->$method($arr$serv);  
  123.     return $flag// 告诉worker  
  124.   }  
  125.   /**  
  126.   *  $task_id    是任务的ID  
  127.   *  $data      是任务处理的结果内容  
  128.   */ 
  129.    public function onFinish($serv,$task_id,$data)  
  130.   {  
  131.     print_r($data).'/n';  
  132.   }  
  133.    
  134. }  
  135.    
  136. new Ws();  

分发任务task.php

  1. <?php  
  2. /**  
  3.  * 代表的是 swoole里面 后续 所有 task异步 任务 都放这里来  
  4.  * Date: 18/3/27  
  5.  * Time: 上午1:20  
  6.  */ 
  7. namespace app\common;  
  8. // include 'Predis.php';  
  9.    
  10. class Task {  
  11.   //异步创建房间  
  12.   public function chuangjian($data,$serv)  
  13.   {  
  14.     $time=$data['time']*1000;  
  15.     swoole_timer_after($timefunction() use($data){  
  16.       //创建房间(修改拍卖商品状态)  
  17.       self::post("https://code.77wx.cn/index/index/in");  
  18.     });  
  19.   }  
  20.    
  21.   //进入房间并缓存信息  
  22.   public function jingru($data,$serv)  
  23.   {  
  24.     $fd=Predis::getInstance()->get('fd');  
  25.     //加入分组  
  26.     Predis::getInstance()->hset($data['name'],$data['uid'],$fd);  
  27.     //加入组集合  
  28.     Predis::getInstance()->sadd('group',$data['name']);  
  29.   }  
  30.    
  31.    
  32.   public function post($url,$params=false,$ispost=0)  
  33.   {  
  34.     $httpInfo = array();  
  35.     $ch = curl_init();  
  36.     curl_setopt( $ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 );  
  37.     curl_setopt( $ch, CURLOPT_USERAGENT , 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22' );  
  38.     curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT , 30 );  
  39.     curl_setopt( $ch, CURLOPT_TIMEOUT , 30);  
  40.     curl_setopt( $ch, CURLOPT_RETURNTRANSFER , true );  
  41.     if$ispost )  
  42.     {  
  43.       curl_setopt( $ch , CURLOPT_POST , true );  
  44.       curl_setopt( $ch , CURLOPT_POSTFIELDS , $params );  
  45.       curl_setopt( $ch , CURLOPT_URL , $url );  
  46.     }  
  47.     else 
  48.     {  
  49.       if($params){  
  50.         curl_setopt( $ch , CURLOPT_URL , $url.'?'.$params );  
  51.       }else{  
  52.         curl_setopt( $ch , CURLOPT_URL , $url);  
  53.       }  
  54.     }  
  55.     //执行  
  56.     $response = curl_exec( $ch );  
  57.     if ($response === FALSE) {  
  58.       //echo "cURL Error: " . curl_error($ch);  
  59.       return false;  
  60.     }  
  61.    
  62.     $httpCode = curl_getinfo( $ch , CURLINFO_HTTP_CODE );  
  63.     $httpInfo = array_merge$httpInfo , curl_getinfo( $ch ) );  
  64.     //关闭url请求  
  65.     curl_close( $ch );  
  66.     return json_decode($response,1);  
  67.   }  
  68.    

客户端 client.php

  1. <?php  
  2. namespace app\common;  
  3.    
  4. class Client  
  5. {  
  6.   public $msg='';  
  7.    
  8.   public $data=[];  
  9.    
  10.   public function lianjie(){  
  11.    
  12.     $cli = new \swoole_client(SWOOLE_SOCK_TCP);  
  13.     //判断连接状态(同步连接模式)  
  14.     $res=$cli->connect('127.0.0.1', 9502);  
  15.     if (emptyempty($res)) {  
  16.       return "连接失败";  
  17.     }  
  18.    
  19.     if (!emptyempty($this->data)) {  
  20.       //发送消息给server  
  21.       $rel=$cli->send(json_encode($this->data));  
  22.     }else{  
  23.       //发送消息给server  
  24.       $rel=$cli->send($this->msg);  
  25.     }  
  26.     if (!emptyempty($rel)) {  
  27.       return $rel;  
  28.     }else{  
  29.       return flash;  
  30.     }  
  31.   }  

控制器index.php

  1. <?php  
  2. namespace app\index\controller;  
  3.    
  4. use app\common\Client;  
  5. use app\common\Predis;  
  6. use app\common\Sql;  
  7. use app\index\model\User;  
  8.    
  9. class Index  
  10. {  
  11.   //创建房间(添加拍卖倒计时)  
  12.   public function chuangjian()  
  13.   {  
  14.     $data['time']=input("time");  
  15.     $data['id']=input("id");  
  16.     $cli = new Client();  
  17.     $cli->data = [  
  18.       'data' => 'chuangjian',  
  19.       'arr' => $data 
  20.     ];  
  21.     return $cli->lianjie();  
  22.   }  
  23.   //点击添加哈希(进入房间)  
  24.   public function jingru()  
  25.   {  
  26.     $data['name']=input("name");  
  27.     $data['uid']=input("uid");  
  28.     $cli = new Client();  
  29.     $cli->data = [  
  30.       'data' => 'jingru',  
  31.       'arr' => $data 
  32.     ];  
  33.     return $cli->lianjie();  
  34.   }  
  35.   //本房间推送(出价格成功并推送)  
  36.   public function pushfan()  
  37.   {  
  38.     $data['fan']=input("fan");  
  39.     $cli = new Client();  
  40.     $cli->data = [  
  41.       'data' => $data['fan'],  
  42.       'msg' => "恭喜用户111,喜当爹!!!!" 
  43.     ];  
  44.     return $cli->lianjie();  
  45.   }  
  46.   //时间结束并指定推送  
  47.   public function zhiding()  
  48.   {  
  49.     $data['fan']=input("fan");  
  50.     $cli = new Client();  
  51.     $cli->data = [  
  52.       'data' => $data['fan'],  
  53.       'msg' => "恭喜用户111,喜当爹!!!!" 
  54.     ];  
  55.     return $cli->lianjie();  
  56.   }  
  57.    
  58. }

Tags: swoole多人聊天室

分享到: