前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >socket编程之swoole开发框架

socket编程之swoole开发框架

作者头像
老雷PHP全栈开发
发布2020-07-02 15:03:09
4360
发布2020-07-02 15:03:09
举报
文章被收录于专栏:老雷PHP全栈开发

Swoole:面向生产环境的 PHP 异步网络通信引擎,使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。

1.安装

1.搭好centos7虚拟机

2.安装php7.2

3.安装swoole

代码语言:javascript
复制
  git clone https://gitee.com/swoole/swoole.git
  cd swoole
  phpize
  ./configure
  make && make install

4.配置php

代码语言:javascript
复制
  cd /etc/php.d
  vi swoole.ini
  extension=swoole.so

5.服务server

htpp tcp udp websocket

6.定时器 timer

7.协程Coroutine

协程可以理解为纯用户态的线程,其通过协作而不是抢占来进行切换。

相对于进程或者线程,协程所有的操作都可以在用户态完成,创建和切换的消耗更低。

swoole 协程特点,异步高性能,简单。

8.异步任务

在Server程序中如果需要执行很耗时的操作,比如一个聊天服务器发送广播,Web服务器中发送邮件。如果直接去执行这些函数就会阻塞当前进程,导致服务器响应变慢。

Swoole提供了异步任务处理的功能,可以投递一个异步任务到TaskWorker进程池中执行,不影响当前请求的处理速度。

代码语言:javascript
复制
<?php
/**
 * 私聊 群聊
 */
class skyWebSocket{
  public $server;
  public $groupClients;
  public $uidClients;
  public $session;
  //用户检测
  public $timerClients=array();
  public function __construct($ip="0.0.0.0",$port="8282"){
    $this->server=new swoole_websocket_server($ip, $port);
    echo "ws://$ip:$port";
  }
  public function connect($client){
    $this->timerClients[$client]=1;
  }
  public function send($client_id,$msg){
    return $this->server->push($client_id, json_encode($msg));
  }
  /**绑定用户**/
  public function bindUid($client_id,$uid){
    $this->uidClients[$uid][$client_id]=$uid;
  }
  public function unBindUid($client_id,$uid=0){
    unset($this->uidClients[$uid][$client_id]);
  }
  public function clearUid($uid){
    unset($this->uidClients[$uid]);
  }
  /**给用户发送**/
  public function sendToUid($uid,$msg){
    if(isset($this->uidClients[$uid])){
      foreach($this->uidClients[$uid] as $client_id){
        //clientid不存在 要做检测 移除$client_id
        if(!$this->send($client_id,$msg)){
          $this->unBindUid($client_id,$uid);
        }
        
      }
    }
  }
  public function isInGroup($gid,$client_id){
    if(!isset($this->groupClients[$gid][$client_id])){
      return false;
    }
    return true;
  }
  public function joinGroup($gid,$client_id){
    $this->groupClients[$gid][$client_id]=$client_id;
  }
  public function unJoinGroup($gid,$client_id){
    unset($this->groupClients[$gid][$client_id]);
  }
  public function clearGroup($gid){
    unset($this->groupClients[$gid]);
  }
  public function sendGroup($gid,$msg){
    foreach($this->groupClients[$gid] as $client_id){
      if(!$this->send($client_id, $msg)){
        $this->unJoinGroup($gid,$client_id);
      }
    }
  }
  public function sendToClient($client_id,$msg){
    $this->send($client_id, $msg);
  }
  
  public function isUidOnline($uid){
    if(isset($this->uidClients[$uid])){
      foreach($this->uidClients[$uid] as $client_id){
        //clientid不存在 要做检测 移除$client_id
        if(!$this->send($client_id,$msg)){
          $this->unBindUid($client_id,$uid);
        }else{
          return true;
        }
        
      }
    }
  }  
  
  public function run(){
    $this->server->start();
    
  }
  public function session_set($client_id,$k,$v){
    $this->session[$client_id][$k]=$v;
  }
  public function session_get($client_id,$k){
    return $this->session[$client_id][$k];
  }
  
  public function session_del($client_id){
    unset($this->session[$client_id]);
  }
  
  public function clientClose($client_id){
    $this->session_del($client_id);
    //删除所有加入的群
    if(!empty($this->groupClients)){
      foreach($this->groupClients as $gid=>$clients){
        foreach($clients as $k=>$cid){
          if($client_id=$cid){
            unset($this->groupClients[$gid][$k]);
          }
        }
      }
    }
    //删除所有绑定的uid
    if(!empty($this->uidClients)){
      foreach($this->uidClients as $uid=>$clients){
        foreach($clients as $k=>$cid){
          if($cid==$client_id){
            unset($this->uidClients[$cid][$k]);
          }
        }
      }
    }
  }
}
$ws= new skyWebSocket();
$ws->server->on('open', function($server, $req) use($ws) {
  $ws->connect($req->fd);
        echo "connection open: {$req->fd}\n";
});
$ws->server->on('message', function($server, $frame) use ($ws) {
  $client_id=$frame->fd;
  $msg=json_decode($frame->data,true);
  echo $frame->data." \n";
  if(isset($msg["gid"])){
    if(!$ws->isInGroup($msg["gid"],$client_id)){
      $ws->joinGroup($msg["gid"],$client_id);
    }
    
    $ws->sendGroup($msg["gid"],$msg);
    
  }else{
    
    if(isset($msg["wsclient_to"])){
      $to_client_id=$msg["wsclient_to"];
      $ws->sendToClient($to_client_id,$msg);
    }else{
      //需要可登录
      $ws->sendToClient($client_id,$msg);
    }
    
  }
});
$ws->server->on('close', function($server, $fd) {
  echo "connection close: {$fd}\n";
});
$ws->run();
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老雷PHP全栈开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档