Yii2結(jié)合Workerman的websocket示例詳解
前言
本文主要給大家介紹了關(guān)于Yii2結(jié)合Workerman的websocket的相關(guān)內(nèi)容,兩者都是好東西,我就想著能不能結(jié)合起來,這樣Yii2出現(xiàn)瓶頸的時(shí)候有些業(yè)務(wù)就可以平滑地遷移到Workerman中。下面話不多說了,來隨著小編來一起看看詳細(xì)的介紹吧
步驟如下
1、安裝workerman
composer require workerman/workerman
2、啟動(dòng)workerman
創(chuàng)建commands/WorkermanWebSocketController.php文件
創(chuàng)建actionIndex()函數(shù),用來啟動(dòng),代碼如下
public function actionIndex()
{
if ('start' == $this->send) {
try {
$this->start($this->daemon);
} catch (\Exception $e) {
$this->stderr($e->getMessage() . "\n", Console::FG_RED);
}
} else if ('stop' == $this->send) {
$this->stop();
} else if ('restart' == $this->send) {
$this->restart();
} else if ('reload' == $this->send) {
$this->reload();
} else if ('status' == $this->send) {
$this->status();
} else if ('connections' == $this->send) {
$this->connections();
}
}
添加初始化模塊
public function initWorker()
{
$ip = isset($this->config['ip']) ? $this->config['ip'] : $this->ip;
$port = isset($this->config['port']) ? $this->config['port'] : $this->port;
$wsWorker = new Worker("websocket://{$ip}:{$port}");
// 4 processes
$wsWorker->count = 4;
// Emitted when new connection come
$wsWorker->onConnect = function ($connection) {
echo "New connection\n";
};
// Emitted when data received
$wsWorker->onMessage = function ($connection, $data) {
// Send hello $data
$connection->send('hello ' . $data);
};
// Emitted when connection closed
$wsWorker->onClose = function ($connection) {
echo "Connection closed\n";
};
}
添加啟動(dòng)模塊
/**
* workman websocket start
*/
public function start()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'start';
if ($this->daemon) {
$argv[2] = '-d';
}
// Run worker
Worker::runAll();
}
添加停止模塊
/**
* workman websocket stop
*/
public function stop()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'stop';
if ($this->gracefully) {
$argv[2] = '-g';
}
// Run worker
Worker::runAll();
}
添加重啟模塊
/**
* workman websocket restart
*/
public function restart()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'restart';
if ($this->daemon) {
$argv[2] = '-d';
}
if ($this->gracefully) {
$argv[2] = '-g';
}
// Run worker
Worker::runAll();
}
添加重載模塊
/**
* workman websocket reload
*/
public function reload()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'reload';
if ($this->gracefully) {
$argv[2] = '-g';
}
// Run worker
Worker::runAll();
}
添加狀態(tài)模塊
/**
* workman websocket status
*/
public function status()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'status';
if ($this->daemon) {
$argv[2] = '-d';
}
// Run worker
Worker::runAll();
}
添加鏈接數(shù)模塊
/**
* workman websocket connections
*/
public function connections()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'connections';
// Run worker
Worker::runAll();
}
3、前端調(diào)用
<script>
// Create WebSocket connection.
const ws = new WebSocket('ws://{{ app.request.hostName }}:2347/'); // 這里是獲取的網(wǎng)站的域名,測試的時(shí)候可以改為自己的本地的ip地址
// Connection opened
ws.addEventListener('open', function (event) {
ws.send('Hello Server!');
});
// Listen for messages
ws.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
setTimeout(function() {
ws.send('ssssss');
}, 10000);
</script>
4、config參數(shù)配置
修改console.php并添加如下代碼
'controllerMap' => [ 'workerman-web-socket' => [ 'class' => 'app\commands\WorkermanWebSocketController', 'config' => [ 'ip' => '127.0.0.1', 'port' => '2346', 'daemonize' => true, ], ], ],
5、nginx配置
為什么會(huì)用 nginx, 我們正常部署上線是不可能直接使用ip的,這個(gè)戶存在安全隱患,最好是綁定一個(gè)域名
server {
charset utf-8;
client_max_body_size 128M;
listen 2347;
server_name www.gowhich.com; # 這里改為自己的域名
access_log /xxx.workerman.access.log; # 換成自己服務(wù)器的nginx日志路徑
error_log /xxx.workerman.error.log; # 換成自己服務(wù)器的nginx日志路徑
location / {
proxy_pass http://127.0.0.1:2346; # 代理2346 也可以根據(jù)項(xiàng)目配置為自己的端口
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
重新nginx
nginx -s relad 或者 sudo nginx -s reload
然后將第3步的代碼加入自己做的視圖中,如果沒有問題的話,websocket啟動(dòng)后就能正常通訊了。
6、啟動(dòng)workerman websocket
// 啟動(dòng) ./yii workerman-web-socket -s start -d
如果沒有問題的話會(huì)得到類似如下的結(jié)果
$ ./yii workerman-web-socket -s start -d Workerman[workerman-web-socket] start in DAEMON mode ----------------------- WORKERMAN ----------------------------- Workerman version:3.5.13 PHP version:7.1.16 ------------------------ WORKERS ------------------------------- user worker listen processes status durban none websocket://127.0.0.1:2346 4 [OK] ---------------------------------------------------------------- Input "php workerman-web-socket stop" to stop. Start success.
7、其他
commands/WorkermanWebSocketController.php 完整代碼如下
<?php
/**
* WorkmanWebSocket 服務(wù)相關(guān)
*/
namespace app\commands;
use Workerman\Worker;
use yii\console\Controller;
use yii\helpers\Console;
/**
*
* WorkermanWebSocket
*
* @author durban.zhang <durban.zhang@gmail.com>
*/
class WorkermanWebSocketController extends Controller
{
public $send;
public $daemon;
public $gracefully;
// 這里不需要設(shè)置,會(huì)讀取配置文件中的配置
public $config = [];
private $ip = '127.0.0.1';
private $port = '2346';
public function options($actionID)
{
return ['send', 'daemon', 'gracefully'];
}
public function optionAliases()
{
return [
's' => 'send',
'd' => 'daemon',
'g' => 'gracefully',
];
}
public function actionIndex()
{
if ('start' == $this->send) {
try {
$this->start($this->daemon);
} catch (\Exception $e) {
$this->stderr($e->getMessage() . "\n", Console::FG_RED);
}
} else if ('stop' == $this->send) {
$this->stop();
} else if ('restart' == $this->send) {
$this->restart();
} else if ('reload' == $this->send) {
$this->reload();
} else if ('status' == $this->send) {
$this->status();
} else if ('connections' == $this->send) {
$this->connections();
}
}
public function initWorker()
{
$ip = isset($this->config['ip']) ? $this->config['ip'] : $this->ip;
$port = isset($this->config['port']) ? $this->config['port'] : $this->port;
$wsWorker = new Worker("websocket://{$ip}:{$port}");
// 4 processes
$wsWorker->count = 4;
// Emitted when new connection come
$wsWorker->onConnect = function ($connection) {
echo "New connection\n";
};
// Emitted when data received
$wsWorker->onMessage = function ($connection, $data) {
// Send hello $data
$connection->send('dddd hello ' . $data);
};
// Emitted when connection closed
$wsWorker->onClose = function ($connection) {
echo "Connection closed\n";
};
}
/**
* workman websocket start
*/
public function start()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'start';
if ($this->daemon) {
$argv[2] = '-d';
}
// Run worker
Worker::runAll();
}
/**
* workman websocket restart
*/
public function restart()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'restart';
if ($this->daemon) {
$argv[2] = '-d';
}
if ($this->gracefully) {
$argv[2] = '-g';
}
// Run worker
Worker::runAll();
}
/**
* workman websocket stop
*/
public function stop()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'stop';
if ($this->gracefully) {
$argv[2] = '-g';
}
// Run worker
Worker::runAll();
}
/**
* workman websocket reload
*/
public function reload()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'reload';
if ($this->gracefully) {
$argv[2] = '-g';
}
// Run worker
Worker::runAll();
}
/**
* workman websocket status
*/
public function status()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'status';
if ($this->daemon) {
$argv[2] = '-d';
}
// Run worker
Worker::runAll();
}
/**
* workman websocket connections
*/
public function connections()
{
$this->initWorker();
// 重置參數(shù)以匹配Worker
global $argv;
$argv[0] = $argv[1];
$argv[1] = 'connections';
// Run worker
Worker::runAll();
}
}
workerman websocket支持的其他命令
重啟
$ ./yii workerman-web-socket -s restart -d Workerman[workerman-web-socket] restart Workerman[workerman-web-socket] is stopping ... Workerman[workerman-web-socket] stop success ----------------------- WORKERMAN ----------------------------- Workerman version:3.5.13 PHP version:7.1.16 ------------------------ WORKERS ------------------------------- user worker listen processes status durban none websocket://127.0.0.1:2346 4 [OK] ---------------------------------------------------------------- Input "php workerman-web-socket stop" to stop. Start success.
重載
$ ./yii workerman-web-socket -s reload Workerman[workerman-web-socket] reload
狀態(tài)
$ ./yii workerman-web-socket -s status -g Workerman[workerman-web-socket] status ----------------------------------------------GLOBAL STATUS---------------------------------------------------- Workerman version:3.5.13 PHP version:7.1.16 start time:2018-09-10 11:22:15 run 0 days 0 hours load average: 1.79, 2, 2 event-loop:\Workerman\Events\Swoole 1 workers 4 processes worker_name exit_status exit_count none 0 12 ----------------------------------------------PROCESS STATUS--------------------------------------------------- pid memory listening worker_name connections send_fail timers total_request qps status 8283 4M websocket://127.0.0.1:2346 none 0 0 0 0 0 [idle] 8284 4M websocket://127.0.0.1:2346 none 0 0 0 0 0 [idle] 8285 4M websocket://127.0.0.1:2346 none 0 0 0 0 0 [idle] 8286 4M websocket://127.0.0.1:2346 none 0 0 0 0 0 [idle] ----------------------------------------------PROCESS STATUS--------------------------------------------------- Summary 16M - - 0 0 0 0 0 [Summary]
連接數(shù)
./yii workerman-web-socket -s connections Workerman[workerman-web-socket] connections --------------------------------------------------------------------- WORKERMAN CONNECTION STATUS -------------------------------------------------------------------------------- PID Worker CID Trans Protocol ipv4 ipv6 Recv-Q Send-Q Bytes-R Bytes-W Status Local Address Foreign Address
我這里暫時(shí)連接的,所以沒有連接的信息
停止
$ ./yii workerman-web-socket -s stop Workerman[workerman-web-socket] stop Workerman[workerman-web-socket] is stopping ... Workerman[workerman-web-socket] stop success
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
PHP判斷用戶是否已經(jīng)登錄(跳轉(zhuǎn)到不同頁面或者執(zhí)行不同動(dòng)作)
這篇文章主要介紹了PHP判斷用戶是否已經(jīng)登錄(跳轉(zhuǎn)到不同頁面或者執(zhí)行不同動(dòng)作)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
ThinkPHP5&5.1框架關(guān)聯(lián)模型分頁操作示例
這篇文章主要介紹了ThinkPHP5&5.1框架關(guān)聯(lián)模型分頁操作,結(jié)合實(shí)例形式分析了thinkPHP5、5.1關(guān)聯(lián)模型的建立、控制器、模型的實(shí)現(xiàn)及分頁操作相關(guān)技巧,需要的朋友可以參考下2019-08-08
ThinkPHP框架任意代碼執(zhí)行漏洞的利用及其修復(fù)方法
這篇文章主要介紹了ThinkPHP框架任意代碼執(zhí)行漏洞的利用及其修復(fù)方法,該漏洞的修復(fù)對(duì)于廣大使用ThinkPHP的開發(fā)人員來說尤為重要!需要的朋友可以參考下2014-07-07
ThinkPHP中pathinfo的訪問模式、路徑訪問模式及URL重寫總結(jié)
這篇文章主要介紹了ThinkPHP中pathinfo的訪問模式、路徑訪問模式及URL重寫總結(jié),是ThinkPHP路由訪問的基礎(chǔ)知識(shí),在ThinkPHP開發(fā)中非常重要,需要的朋友可以參考下2014-08-08
Yii2實(shí)現(xiàn)自定義獨(dú)立驗(yàn)證器的方法
這篇文章主要介紹了Yii2實(shí)現(xiàn)自定義獨(dú)立驗(yàn)證器的方法,結(jié)合實(shí)例形式分析了Yii2自定義獨(dú)立驗(yàn)證器的實(shí)現(xiàn)與使用方法,需要的朋友可以參考下2017-05-05

