当前位置:首页 > 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. { 
  3.  if ('start' == $this->send) { 
  4.  try { 
  5.   $this->start($this->daemon); 
  6.  } catch (\Exception $e) { 
  7.   $this->stderr($e->getMessage() . "\n", Console::FG_RED); 
  8.  } 
  9.  } else if ('stop' == $this->send) { 
  10.  $this->stop(); 
  11.  } else if ('restart' == $this->send) { 
  12.  $this->restart(); 
  13.  } else if ('reload' == $this->send) { 
  14.  $this->reload(); 
  15.  } else if ('status' == $this->send) { 
  16.  $this->status(); 
  17.  } else if ('connections' == $this->send) { 
  18.  $this->connections(); 
  19.  } 
  20. } 

添加初始化模块

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

添加启动模块

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

添加停止模块

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

添加重启模块

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

添加重载模块

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

添加状态模块

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

添加链接数模块

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

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.  } 
  23. } 

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

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

分享到: