当前位置:首页 > CMS教程 > 其它CMS > 列表

Yii2结合Workerman的websocket示例详解

发布:smiling 来源: PHP粉丝网  添加日期:2021-10-29 09:53:03 浏览: 评论:0 

这篇文章主要给大家介绍了关于Yii2结合Workerman的websocket的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧。

前言

本文主要给大家介绍了关于Yii2结合Workerman的websocket的相关内容,两者都是好东西,我就想着能不能结合起来,这样Yii2出现瓶颈的时候有些业务就可以平滑地迁移到Workerman中。下面话不多说了,来随着小编来一起看看详细的介绍吧

步骤如下

1、安装workerman

composer require workerman/workerman

2、启动workerman

创建commands/WorkermanWebSocketController.php文件

创建actionIndex()函数,用来启动,代码如下

  1. public function actionIndex() 
  2.  if ('start' == $this->send) { 
  3.  try { 
  4.   $this->start($this->daemon); 
  5.  } catch (\Exception $e) { 
  6.   $this->stderr($e->getMessage() . "\n", Console::FG_RED); 
  7.  } 
  8.  } else if ('stop' == $this->send) { 
  9.  $this->stop(); 
  10.  } else if ('restart' == $this->send) { 
  11.  $this->restart(); 
  12.  } else if ('reload' == $this->send) { 
  13.  $this->reload(); 
  14.  } else if ('status' == $this->send) { 
  15.  $this->status(); 
  16.  } else if ('connections' == $this->send) { 
  17.  $this->connections(); 
  18.  } 

添加初始化模块

  1. public function initWorker() 
  2.  $ip = isset($this->config['ip']) ? $this->config['ip'] : $this->ip; 
  3.  $port = isset($this->config['port']) ? $this->config['port'] : $this->port; 
  4.  $wsWorker = new Worker("websocket://{$ip}:{$port}"); 
  5.  
  6.  // 4 processes 
  7.  $wsWorker->count = 4; 
  8.  
  9.  // Emitted when new connection come 
  10.  $wsWorker->onConnect = function ($connection) { 
  11.  echo "New connection\n"
  12.  }; 
  13.  
  14.  // Emitted when data received 
  15.  $wsWorker->onMessage = function ($connection$data) { 
  16.  // Send hello $data 
  17.  $connection->send('hello ' . $data); 
  18.  }; 
  19.  
  20.  // Emitted when connection closed 
  21.  $wsWorker->onClose = function ($connection) { 
  22.  echo "Connection closed\n"
  23.  }; 

添加启动模块

  1. /** 
  2.  * workman websocket start 
  3.  */ 
  4. public function start() 
  5.  $this->initWorker(); 
  6.  // 重置参数以匹配Worker 
  7.  global $argv
  8.  $argv[0] = $argv[1]; 
  9.  $argv[1] = 'start'
  10.  if ($this->daemon) { 
  11.  $argv[2] = '-d'
  12.  } 
  13.  
  14.  // Run worker 
  15.  Worker::runAll(); 

添加停止模块

  1. /** 
  2.  * workman websocket stop 
  3.  */ 
  4. public function stop() 
  5.  $this->initWorker(); 
  6.  // 重置参数以匹配Worker 
  7.  global $argv
  8.  $argv[0] = $argv[1]; 
  9.  $argv[1] = 'stop'
  10.  if ($this->gracefully) { 
  11.  $argv[2] = '-g'
  12.  } 
  13.  
  14.  // Run worker 
  15.  Worker::runAll(); 

添加重启模块

  1. /** 
  2.  * workman websocket restart 
  3.  */ 
  4. public function restart() 
  5.  $this->initWorker(); 
  6.  // 重置参数以匹配Worker 
  7.  global $argv
  8.  $argv[0] = $argv[1]; 
  9.  $argv[1] = 'restart'
  10.  if ($this->daemon) { 
  11.  $argv[2] = '-d'
  12.  } 
  13.  
  14.  if ($this->gracefully) { 
  15.  $argv[2] = '-g'
  16.  } 
  17.  
  18.  // Run worker 
  19.  Worker::runAll(); 

添加重载模块

  1. /** 
  2.  * workman websocket reload 
  3.  */ 
  4. public function reload() 
  5.  $this->initWorker(); 
  6.  // 重置参数以匹配Worker 
  7.  global $argv
  8.  $argv[0] = $argv[1]; 
  9.  $argv[1] = 'reload'
  10.  if ($this->gracefully) { 
  11.  $argv[2] = '-g'
  12.  } 
  13.  
  14.  // Run worker 
  15.  Worker::runAll(); 

添加状态模块

  1. /** 
  2.  * workman websocket status 
  3.  */ 
  4. public function status() 
  5.  $this->initWorker(); 
  6.  // 重置参数以匹配Worker 
  7.  global $argv
  8.  $argv[0] = $argv[1]; 
  9.  $argv[1] = 'status'
  10.  if ($this->daemon) { 
  11.  $argv[2] = '-d'
  12.  } 
  13.  
  14.  // Run worker 
  15.  Worker::runAll(); 

添加链接数模块

  1. /** 
  2.  * workman websocket connections 
  3.  */ 
  4. public function connections() 
  5.  $this->initWorker(); 
  6.  // 重置参数以匹配Worker 
  7.  global $argv
  8.  $argv[0] = $argv[1]; 
  9.  $argv[1] = 'connections'
  10.  
  11.  // Run worker 
  12.  Worker::runAll(); 

3、前端调用

  1. <script> 
  2.  // Create WebSocket connection. 
  3.  const ws = new WebSocket('ws://{{ app.request.hostName }}:2347/'); // 这里是获取的网站的域名,测试的时候可以改为自己的本地的ip地址 
  4.  
  5.  // Connection opened 
  6.  ws.addEventListener('open'function (event) { 
  7.  ws.send('Hello Server!'); 
  8.  }); 
  9.  
  10.  // Listen for messages 
  11.  ws.addEventListener('message'function (event) { 
  12.  console.log('Message from server ', event.data); 
  13.  }); 
  14.  
  15.  setTimeout(function() { 
  16.  ws.send('ssssss'); 
  17.  }, 10000); 
  18.  
  19. </script> 

4、config参数配置

修改console.php并添加如下代码

  1. 'controllerMap' => [ 
  2.  'workerman-web-socket' => [ 
  3.  'class' => 'app\commands\WorkermanWebSocketController'
  4.  'config' => [ 
  5.   'ip' => '127.0.0.1'
  6.   'port' => '2346'
  7.   'daemonize' => true, 
  8.  ], 
  9.  ], 
  10. ], 

5、nginx配置

为什么会用 nginx, 我们正常部署上线是不可能直接使用ip的,这个户存在安全隐患,最好是绑定一个域名

  1. server { 
  2.  charset utf-8; 
  3.  client_max_body_size 128M; 
  4.  
  5.  listen 2347; 
  6.  
  7.  server_name www.gowhich.com; # 这里改为自己的域名 
  8.  
  9.  access_log /xxx.workerman.access.log; # 换成自己服务器的nginx日志路径 
  10.  error_log /xxx.workerman.error.log; # 换成自己服务器的nginx日志路径 
  11.  
  12.  location / { 
  13.  proxy_pass http://127.0.0.1:2346; # 代理2346 也可以根据项目配置为自己的端口 
  14.  
  15.  proxy_set_header X-Real-IP $remote_addr; 
  16.  proxy_set_header Host $host; 
  17.  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
  18.  
  19.  proxy_http_version 1.1; 
  20.  proxy_set_header Upgrade $http_upgrade; 
  21.  proxy_set_header Connection "upgrade"; 
  22.  } 

重新nginx

nginx -s relad 或者 sudo nginx -s reload

然后将第3步的代码加入自己做的视图中,如果没有问题的话,websocket启动后就能正常通讯了。

6、启动workerman websocket

// 启动

./yii workerman-web-socket -s start -d

如果没有问题的话会得到类似如下的结果

  1. $ ./yii workerman-web-socket -s start -d 
  2. Workerman[workerman-web-socket] start in DAEMON mode 
  3. ----------------------- WORKERMAN ----------------------------- 
  4. Workerman version:3.5.13   PHP version:7.1.16 
  5. ------------------------ WORKERS ------------------------------- 
  6. user   worker  listen      processes status 
  7. durban  none   websocket://127.0.0.1:2346 4   [OK]  
  8. ---------------------------------------------------------------- 
  9. Input "php workerman-web-socket stop" to stop. Start success. 

7、其他

commands/WorkermanWebSocketController.php 完整代码如下

  1. <?php 
  2. /** 
  3.  * WorkmanWebSocket 服务相关 
  4.  */ 
  5.  
  6. namespace app\commands; 
  7.  
  8. use Workerman\Worker; 
  9. use yii\console\Controller; 
  10. use yii\helpers\Console; 
  11.  
  12. /** 
  13.  * 
  14.  * WorkermanWebSocket 
  15.  * 
  16.  * @author durban.zhang <durban.zhang@gmail.com> 
  17.  */ 
  18.  
  19. class WorkermanWebSocketController extends Controller 
  20.  public $send
  21.  public $daemon
  22.  public $gracefully
  23.  
  24.  // 这里不需要设置,会读取配置文件中的配置 
  25.  public $config = []; 
  26.  private $ip = '127.0.0.1'
  27.  private $port = '2346'
  28.  
  29.  public function options($actionID
  30.  { 
  31.   return ['send''daemon''gracefully']; 
  32.  } 
  33.  
  34.  public function optionAliases() 
  35.  { 
  36.   return [ 
  37.    's' => 'send'
  38.    'd' => 'daemon'
  39.    'g' => 'gracefully'
  40.   ]; 
  41.  } 
  42.  
  43.  public function actionIndex() 
  44.  { 
  45.   if ('start' == $this->send) { 
  46.    try { 
  47.     $this->start($this->daemon); 
  48.    } catch (\Exception $e) { 
  49.     $this->stderr($e->getMessage() . "\n", Console::FG_RED); 
  50.    } 
  51.   } else if ('stop' == $this->send) { 
  52.    $this->stop(); 
  53.   } else if ('restart' == $this->send) { 
  54.    $this->restart(); 
  55.   } else if ('reload' == $this->send) { 
  56.    $this->reload(); 
  57.   } else if ('status' == $this->send) { 
  58.    $this->status(); 
  59.   } else if ('connections' == $this->send) { 
  60.    $this->connections(); 
  61.   } 
  62.  } 
  63.  
  64.  public function initWorker() 
  65.  { 
  66.   $ip = isset($this->config['ip']) ? $this->config['ip'] : $this->ip; 
  67.   $port = isset($this->config['port']) ? $this->config['port'] : $this->port; 
  68.   $wsWorker = new Worker("websocket://{$ip}:{$port}"); 
  69.  
  70.   // 4 processes 
  71.   $wsWorker->count = 4; 
  72.  
  73.   // Emitted when new connection come 
  74.   $wsWorker->onConnect = function ($connection) { 
  75.    echo "New connection\n"
  76.   }; 
  77.  
  78.   // Emitted when data received 
  79.   $wsWorker->onMessage = function ($connection$data) { 
  80.    // Send hello $data 
  81.    $connection->send('dddd hello ' . $data); 
  82.   }; 
  83.  
  84.   // Emitted when connection closed 
  85.   $wsWorker->onClose = function ($connection) { 
  86.    echo "Connection closed\n"
  87.   }; 
  88.  } 
  89.  
  90.  /** 
  91.   * workman websocket start 
  92.   */ 
  93.  public function start() 
  94.  { 
  95.   $this->initWorker(); 
  96.   // 重置参数以匹配Worker 
  97.   global $argv
  98.   $argv[0] = $argv[1]; 
  99.   $argv[1] = 'start'
  100.   if ($this->daemon) { 
  101.    $argv[2] = '-d'
  102.   } 
  103.  
  104.   // Run worker 
  105.   Worker::runAll(); 
  106.  } 
  107.  
  108.  /** 
  109.   * workman websocket restart 
  110.   */ 
  111.  public function restart() 
  112.  { 
  113.   $this->initWorker(); 
  114.   // 重置参数以匹配Worker 
  115.   global $argv
  116.   $argv[0] = $argv[1]; 
  117.   $argv[1] = 'restart'
  118.   if ($this->daemon) { 
  119.    $argv[2] = '-d'
  120.   } 
  121.  
  122.   if ($this->gracefully) { 
  123.    $argv[2] = '-g'
  124.   } 
  125.  
  126.   // Run worker 
  127.   Worker::runAll(); 
  128.  } 
  129.  
  130.  /** 
  131.   * workman websocket stop 
  132.   */ 
  133.  public function stop() 
  134.  { 
  135.   $this->initWorker(); 
  136.   // 重置参数以匹配Worker 
  137.   global $argv
  138.   $argv[0] = $argv[1]; 
  139.   $argv[1] = 'stop'
  140.   if ($this->gracefully) { 
  141.    $argv[2] = '-g'
  142.   } 
  143.  
  144.   // Run worker 
  145.   Worker::runAll(); 
  146.  } 
  147.  
  148.  /** 
  149.   * workman websocket reload 
  150.   */ 
  151.  public function reload() 
  152.  { 
  153.   $this->initWorker(); 
  154.   // 重置参数以匹配Worker 
  155.   global $argv
  156.   $argv[0] = $argv[1]; 
  157.   $argv[1] = 'reload'
  158.   if ($this->gracefully) { 
  159.    $argv[2] = '-g'
  160.   } 
  161.  
  162.   // Run worker 
  163.   Worker::runAll(); 
  164.  } 
  165.  
  166.  /** 
  167.   * workman websocket status 
  168.   */ 
  169.  public function status() 
  170.  { 
  171.   $this->initWorker(); 
  172.   // 重置参数以匹配Worker 
  173.   global $argv
  174.   $argv[0] = $argv[1]; 
  175.   $argv[1] = 'status'
  176.   if ($this->daemon) { 
  177.    $argv[2] = '-d'
  178.   } 
  179.  
  180.   // Run worker 
  181.   Worker::runAll(); 
  182.  } 
  183.  
  184.  /** 
  185.   * workman websocket connections 
  186.   */ 
  187.  public function connections() 
  188.  { 
  189.   $this->initWorker(); 
  190.   // 重置参数以匹配Worker 
  191.   global $argv
  192.   $argv[0] = $argv[1]; 
  193.   $argv[1] = 'connections'
  194.  
  195.   // Run worker 
  196.   Worker::runAll(); 
  197.  } 

workerman websocket支持的其他命令

重启

  1. $ ./yii workerman-web-socket -s restart -d 
  2. Workerman[workerman-web-socket] restart  
  3. Workerman[workerman-web-socket] is stopping ... 
  4. Workerman[workerman-web-socket] stop success 
  5. ----------------------- WORKERMAN ----------------------------- 
  6. Workerman version:3.5.13   PHP version:7.1.16 
  7. ------------------------ WORKERS ------------------------------- 
  8. user   worker  listen      processes status 
  9. durban  none   websocket://127.0.0.1:2346 4   [OK]  
  10. ---------------------------------------------------------------- 
  11. Input "php workerman-web-socket stop" to stop. Start success. 

重载

$ ./yii workerman-web-socket -s reload

Workerman[workerman-web-socket] reload

状态

  1. $ ./yii workerman-web-socket -s status -g 
  2. Workerman[workerman-web-socket] status  
  3. ----------------------------------------------GLOBAL STATUS---------------------------------------------------- 
  4. Workerman version:3.5.13   PHP version:7.1.16 
  5. start time:2018-09-10 11:22:15 run 0 days 0 hours  
  6. load average: 1.79, 2, 2   event-loop:\Workerman\Events\Swoole 
  7. 1 workers  4 processes 
  8. worker_name exit_status  exit_count 
  9. none   0    12 
  10. ----------------------------------------------PROCESS STATUS--------------------------------------------------- 
  11. pid memory listening     worker_name connections send_fail timers total_request qps status 
  12. 8283 4M  websocket://127.0.0.1:2346 none   0   0   0  0    0  [idle] 
  13. 8284 4M  websocket://127.0.0.1:2346 none   0   0   0  0    0  [idle] 
  14. 8285 4M  websocket://127.0.0.1:2346 none   0   0   0  0    0  [idle] 
  15. 8286 4M  websocket://127.0.0.1:2346 none   0   0   0  0    0  [idle] 
  16. ----------------------------------------------PROCESS STATUS--------------------------------------------------- 
  17. Summary 16M  -       -   0   0   0  0    0  [Summary] 

连接数

  1. ./yii workerman-web-socket -s connections 
  2. Workerman[workerman-web-socket] connections  
  3. --------------------------------------------------------------------- WORKERMAN CONNECTION STATUS -------------------------------------------------------------------------------- 
  4. PID  Worker   CID  Trans Protocol  ipv4 ipv6 Recv-Q  Send-Q  Bytes-R  Bytes-W  Status   Local Address   Foreign Address 

我这里暂时连接的,所以没有连接的信息

停止

  1. $ ./yii workerman-web-socket -s stop    
  2. Workerman[workerman-web-socket] stop  
  3. Workerman[workerman-web-socket] is stopping ... 
  4. Workerman[workerman-web-socket] stop success

Tags: Yii2 Workerman websocket

分享到: