Laravel 5.4 結(jié)合 Workerman 實現(xiàn) TCP 長連接

沒有聽說過或者沒有用過 workerman 的童鞋建議先去官網(wǎng)看下文檔剥纷。

一、安裝 workerman

在項目根目錄執(zhí)行

composer require workerman/workerman
二伟姐、創(chuàng)建自定義 artisan 命令來啟動 workerman 服務(wù)

由于 laravel 不能直接在根目錄下執(zhí)行 php 命令,所以需要創(chuàng)建 artisan 命令用于后面 workerman 服務(wù)的開啟。

1付魔,生成 WorkermanCommand 文件

php artisan make:command WorkermanCommand

執(zhí)行以上命令行會在 app/Console/Commands/ 目錄下生成 WorkermanCommand.php 文件。

<?php

namespace App\Console\Commands;

use Workerman\Worker;
use Illuminate\Console\Command;

class WorkermanCommand extends Command
{
    private $server;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'wk {action}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Start a Workerman server.';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        global $argv;
        $arg = $this->argument('action');
        $argv[1] = $argv[2];
        $argv[2] = isset($argv[3]) ? "-{$argv[3]}" : '';
        switch ($arg) {
            case 'start':
                $this->start();
                break;
            case 'stop':
                break;
            case 'restart':
                break;
            case 'reload':
                break;
            case 'status':
                break;
            case 'connections':
                break;
        }
    }

    private function start()
    {
        // 創(chuàng)建一個Worker監(jiān)聽20002端口飞蹂,不使用任何應(yīng)用層協(xié)議
        $this->server = new Worker("tcp://0.0.0.0:20002");
        // 啟動4個進(jìn)程對外提供服務(wù)
        $this->server->count = 4;
        $handler = \App::make('handlers\WorkermanHandler');
        // 連接時回調(diào)
        $this->server->onConnect = [$handler, 'onConnect'];
        // 收到客戶端信息時回調(diào)
        $this->server->onMessage = [$handler, 'onMessage'];
        // 進(jìn)程啟動后的回調(diào)
        $this->server->onWorkerStart = [$handler, 'onWorkerStart'];
        // 斷開時觸發(fā)的回調(diào)
        $this->server->onClose = [$handler, 'onClose'];
        // 運行worker
        Worker::runAll();
    }
}

我只實現(xiàn)了 start 命令几苍,其他命令童鞋們自行實現(xiàn)吧。
這里使用了 PHP 類方法的回調(diào)陈哑。(PHP幾種回調(diào)寫法
這里我們創(chuàng)建了一個自定義命令 wk [action] 妻坝,通過此命令即可開啟 workerman 服務(wù)。
在這個自定義命令還引用了其他的類文件惊窖,如:

$handler = \App::make('handlers\WorkermanHandler');

所以刽宪,需要創(chuàng)建一個 WorkermanHandler.php 的文件來處理對應(yīng)的操作。

2爬坑,創(chuàng)建 WorkermanHandler.php
創(chuàng)建文件 app/handlers/WorkermanHandler.php

<?php

namespace handlers;

use Workerman\Lib\Timer;

// 心跳間隔10秒
define('HEARTBEAT_TIME', 10);

class WorkermanHandler
{
    // 處理客戶端連接
    public function onConnect($connection)
    {
        echo "new connection from ip " . $connection->getRemoteIp() . "\n";
    }

    // 處理客戶端消息
    public function onMessage($connection, $data)
    {
        // 向客戶端發(fā)送hello $data
        $connection->send('Hello, your send message is: ' . $data);
    }

    // 處理客戶端斷開
    public function onClose($connection)
    {
        echo "connection closed from ip {$connection->getRemoteIp()}\n";
    }

    public function onWorkerStart($worker)
    {
        Timer::add(1, function () use ($worker) {
            $time_now = time();
            foreach ($worker->connections as $connection) {
                // 有可能該connection還沒收到過消息纠屋,則lastMessageTime設(shè)置為當(dāng)前時間
                if (empty($connection->lastMessageTime)) {
                    $connection->lastMessageTime = $time_now;
                    continue;
                }
                // 上次通訊時間間隔大于心跳間隔,則認(rèn)為客戶端已經(jīng)下線盾计,關(guān)閉連接
                if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
                    echo "Client ip {$connection->getRemoteIp()} timeout!!!\n";
                    $connection->close();
                }
            }
        });
    }
}

3售担,修改 composer.json 文件,讓 app/Protocols 文件夾下的類文件自動加載署辉。

"autoload": {
    "classmap": [
        ...
        "app/Protocols"
    ],
    ...
},

至此族铆。workman的命令定義已經(jīng)完成。

使用:
php artisan wk start

如果看到以下內(nèi)容哭尝,說明 workerman 服務(wù)啟動正常:

Workerman[artisan] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.5.4          PHP version:7.1.4
------------------------ WORKERS -------------------------------
user          worker        listen                   processes status
root          none          tcp://0.0.0.0:20002   1         [OK] 
----------------------------------------------------------------
Press Ctrl+C to quit. Start success.

幫助文檔:
心跳包
如何與其它框架整合
利用WorkerMan給客戶端推送數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哥攘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逝淹,老刑警劉巖耕姊,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異栅葡,居然都是意外死亡茉兰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門欣簇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來规脸,“玉大人,你說我怎么就攤上這事熊咽∧迹” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵横殴,是天一觀的道長被因。 經(jīng)常有香客問我,道長滥玷,這世上最難降的妖魔是什么氏身? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮惑畴,結(jié)果婚禮上蛋欣,老公的妹妹穿的比我還像新娘。我一直安慰自己如贷,他們只是感情好陷虎,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杠袱,像睡著了一般尚猿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上楣富,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天凿掂,我揣著相機(jī)與錄音,去河邊找鬼纹蝴。 笑死庄萎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的塘安。 我是一名探鬼主播糠涛,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兼犯!你這毒婦竟也來了忍捡?” 一聲冷哼從身側(cè)響起集漾,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎砸脊,沒想到半個月后具篇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡凌埂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年栽连,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侨舆。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖绢陌,靈堂內(nèi)的尸體忽然破棺而出挨下,到底是詐尸還是另有隱情,我是刑警寧澤脐湾,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布臭笆,位于F島的核電站,受9級特大地震影響秤掌,放射性物質(zhì)發(fā)生泄漏愁铺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一闻鉴、第九天 我趴在偏房一處隱蔽的房頂上張望茵乱。 院中可真熱鬧,春花似錦孟岛、人聲如沸瓶竭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斤贰。三九已至,卻和暖如春次询,著一層夾襖步出監(jiān)牢的瞬間荧恍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工屯吊, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留送巡,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓雌芽,卻偏偏與公主長得像授艰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子世落,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,182評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理淮腾,服務(wù)發(fā)現(xiàn)糟需,斷路器,智...
    卡卡羅2017閱讀 134,667評論 18 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫谷朝、插件洲押、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,107評論 4 62
  • 我與友口味具是刁鉆专钉,平日外食專撿些口口相傳的小館子挑童,而非大酒樓亦或裝潢不勝華美的新興門店。細(xì)想來也不...
    衡槊閱讀 2,039評論 0 2
  • 到底是持有現(xiàn)金尽楔,還是持有資產(chǎn)? ——從長期來看第练,要持有資產(chǎn)±觯現(xiàn)金是紙幣時代最大的坑,長期持有紙幣的損失娇掏,...
    老樹根茶舍閱讀 640評論 0 1