Realization of multi person chat room based on swoole

  • 2021-10-16 01:12:58
  • OfStack

This article example for everyone to share swoole create multi-person multi-room chat room specific code, for your reference, the specific content is as follows

Core swoole code

The basic cs (client-sercer) structure remains unchanged, and the hash of redis and set are used here to store and group; So as to achieve the functions of grouping, statistics, timing push and the like; Finally, the onclose event is used to eliminate the disconnected connection. The whole code is as follows: (If you don't do the front end, you won't show it.)

Core swoole ws. php


<?php 
 
namespace app\common; 
require_once 'Predis.php'; 
require_once 'Task.php'; 
/** 
*  socket Object-oriented compilation  
*/ 
class Ws 
{ 
  CONST HOST='0.0.0.0'; 
  CONST PORT='9501'; 
  public $ws=null; 
  public $getmsg=null; 
  public $server=null; 
 
  public function __construct() 
  {   
    $this->ws=new \swoole_websocket_server(self::HOST,self::PORT); 
    $this->ws->set([ 
      // Start task You must set its quantity  
      'worker_num' => 4, 
      'task_worker_num' => 2, 
      // 'heartbeat_check_interval' => 5, 
      // 'heartbeat_idle_time' => 10, 
    ]); 
    // Listen for a new port  
    $this->server=$this->ws->listen("127.0.0.1", 9502, SWOOLE_SOCK_TCP); 
    // Shut down websocket Mode  
    $this->server->set([ 
      'open_websocket_protocol' => false, 
    ]); 
 
    $this->ws->on("start", [$this, 'onStart']); 
    $this->ws->on('open',[$this,'onopen']); 
    $this->server->on("receive", [$this, 'onReceive']); 
    $this->ws->on('task',[$this,'onTask']); 
    $this->ws->on('finish',[$this,'onFinish']); 
    $this->ws->on('message',[$this,'onmessage']); 
    $this->ws->on('close',[$this,'onclose']); 
    $this->server->on("close", [$this, 'oncloses']); 
    $this->ws->start(); 
  } 
  // Listen for data reception events  
  public function onReceive($serv, $fd, $from_id, $data) 
  { 
    $shuju=json_decode($data,ture); 
    // print_r($shuju).PHP_EOL; 
    if (empty($shuju['data'])) { 
      $this->ws->push(Predis::getInstance()->get('fd'), $data); 
    }else{ 
      if (empty($shuju['msg'])) { 
        // Perform asynchronous tasks  
        $this->ws->task($shuju); 
      }else{ 
        $push_arr=Predis::getInstance()->hvals($shuju['data']); 
        // echo " Cluster is :".print_r($push_arr); 
        foreach ($push_arr as $v) { 
          $this->ws->push($v, $shuju['msg']); 
        } 
      } 
    } 
  } 
  /** 
   *  Set the process name to restart the process smoothly for the follow-up  
   * @param $server 
   */ 
  public function onStart($server) { 
    swoole_set_process_name("live_master"); 
  }    
  /** 
     Listening for callbacks to open events  
  */ 
  public function onopen($server, $request) 
  { 
    print_r(" At this time fd Yes :",$request->fd); 
    Predis::getInstance()->set('fd',$request->fd); 
  } 
   
  /** 
     Listening for callbacks to receive events  
  */ 
  public function onmessage($server, $frame) 
  { 
    $server->push($frame->fd, "{$frame->data}"); 
  } 
  /** 
     Listen for callbacks for shutdown events  
  */ 
  public function onclose($ser, $fd) 
  { 
    print_r(" How do you do , Mine {$fd}\n"); 
    // Exit and delete redundant groupings fd 
    $group=Predis::getInstance()->sMembers('group'); 
    foreach ($group as $v) { 
      $fangjian=Predis::getInstance()->hgetall($v); 
      foreach ($fangjian as $k => $vv) { 
        if ($fd == $vv) { 
          Predis::getInstance()->hdel($v,$k); 
        } 
      } 
    } 
  } 
  public function oncloses($ser, $fd) 
  { 
    print_r(" This is client{$fd}\n"); 
  } 
 
  /** 
  *  $serv       Services  
  *  $task_id     Mission ID , by swoole Automatically generated within the extension to distinguish different tasks  
  *  $src_worker_id $task_id And $src_worker_id Combined is the global only 1 Of, different worker Tasks delivered by the process ID There may be the same  
  *  $data       Is the content of the task  
  */ 
   public function onTask($serv,$task_id,$src_worker_id,$data) 
  { 
    // Introducing task  
    $obj = new Task; 
    $method = $data['data']; 
    $arr = $data['arr']; 
    // Publish specific tasks  
    $flag = $obj->$method($arr, $serv); 
    return $flag; //  Tell worker 
  } 
  /** 
  *  $task_id     It's a task ID 
  *  $data       Is the result content of task processing  
  */ 
   public function onFinish($serv,$task_id,$data) 
  { 
    print_r($data).'/n'; 
  } 
 
} 
 
new Ws(); 

Distribution task task. php


<?php 
/** 
 *  It represents the  swoole Inside   Follow-up   All  task Asynchronous   Mission   Put them all here  
 * Date: 18/3/27 
 * Time:  Morning 1:20 
 */ 
namespace app\common; 
// include 'Predis.php'; 
 
class Task { 
  // Create a room asynchronously  
  public function chuangjian($data,$serv) 
  { 
    $time=$data['time']*1000; 
    swoole_timer_after($time, function() use($data){ 
      // Create a room ( Modify the status of auction items ) 
      self::post("https://code.77wx.cn/index/index/in"); 
    }); 
  } 
 
  // Enter the room and cache the information  
  public function jingru($data,$serv) 
  { 
    $fd=Predis::getInstance()->get('fd'); 
    // Join grouping  
    Predis::getInstance()->hset($data['name'],$data['uid'],$fd); 
    // Join a group collection  
    Predis::getInstance()->sadd('group',$data['name']); 
  } 
 
 
  public function post($url,$params=false,$ispost=0) 
  { 
    $httpInfo = array(); 
    $ch = curl_init(); 
    curl_setopt( $ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 ); 
    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' ); 
    curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT , 30 ); 
    curl_setopt( $ch, CURLOPT_TIMEOUT , 30); 
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER , true ); 
    if( $ispost ) 
    { 
      curl_setopt( $ch , CURLOPT_POST , true ); 
      curl_setopt( $ch , CURLOPT_POSTFIELDS , $params ); 
      curl_setopt( $ch , CURLOPT_URL , $url ); 
    } 
    else 
    { 
      if($params){ 
        curl_setopt( $ch , CURLOPT_URL , $url.'?'.$params ); 
      }else{ 
        curl_setopt( $ch , CURLOPT_URL , $url); 
      } 
    } 
    // Execute  
    $response = curl_exec( $ch ); 
    if ($response === FALSE) { 
      //echo "cURL Error: " . curl_error($ch); 
      return false; 
    } 
 
    $httpCode = curl_getinfo( $ch , CURLINFO_HTTP_CODE ); 
    $httpInfo = array_merge( $httpInfo , curl_getinfo( $ch ) ); 
    // Shut down url Request  
    curl_close( $ch ); 
    return json_decode($response,1); 
  } 
 
} 

Client client. php


<?php 
namespace app\common; 
 
class Client 
{ 
  public $msg=''; 
 
  public $data=[]; 
 
  public function lianjie(){ 
 
    $cli = new \swoole_client(SWOOLE_SOCK_TCP); 
    // Determine the connection status (synchronous connection mode)  
    $res=$cli->connect('127.0.0.1', 9502); 
    if (empty($res)) { 
      return " Connection failed "; 
    } 
 
    if (!empty($this->data)) { 
      // Send a message to server 
      $rel=$cli->send(json_encode($this->data)); 
    }else{ 
      // Send a message to server 
      $rel=$cli->send($this->msg); 
    } 
    if (!empty($rel)) { 
      return $rel; 
    }else{ 
      return flash; 
    } 
  } 
} 

Controller index. php


<?php 
namespace app\index\controller; 
 
use app\common\Client; 
use app\common\Predis; 
use app\common\Sql; 
use app\index\model\User; 
 
class Index 
{ 
  // Create a room ( Add auction countdown ) 
  public function chuangjian() 
  { 
    $data['time']=input("time"); 
    $data['id']=input("id"); 
    $cli = new Client(); 
    $cli->data = [ 
      'data' => 'chuangjian', 
      'arr' => $data 
    ]; 
    return $cli->lianjie(); 
  } 
  // Click Add Hash ( Enter a room ) 
  public function jingru() 
  { 
    $data['name']=input("name"); 
    $data['uid']=input("uid"); 
    $cli = new Client(); 
    $cli->data = [ 
      'data' => 'jingru', 
      'arr' => $data 
    ]; 
    return $cli->lianjie(); 
  } 
  // Push in this room ( The price is successful and pushed ) 
  public function pushfan() 
  { 
    $data['fan']=input("fan"); 
    $cli = new Client(); 
    $cli->data = [ 
      'data' => $data['fan'], 
      'msg' => " Congratulations to users 111, Be happy to be a father !!!!" 
    ]; 
    return $cli->lianjie(); 
  } 
  // End of time and specify push  
  public function zhiding() 
  { 
    $data['fan']=input("fan"); 
    $cli = new Client(); 
    $cli->data = [ 
      'data' => $data['fan'], 
      'msg' => " Congratulations to users 111, Be happy to be a father !!!!" 
    ]; 
    return $cli->lianjie(); 
  } 
 
} 

Related articles: