laravel-swoole和websocket入門(二)

laravel-swoole和websocket入門(一)中,我們已經(jīng)就 擴(kuò)展的安裝和啟動(dòng)作了介紹, laravel-swoole除了能大幅度的提升系統(tǒng)性能之后,還有一個(gè)很大的功能是 websocket長鏈接,這篇將詳細(xì)介紹長鏈接部分。

1,啟動(dòng)長鏈接

  • 首先我們要開放端口,比如我們要啟動(dòng)1215端口為長鏈接端口,那么服務(wù)器要先放行1215端口,具體放行的方法各種服務(wù)器不一樣,就不細(xì)說了。
  • 修改 config/swoole_http.php 部分配置
'server' => [
        //服務(wù)地址 用0.0.0.0代替127.0.0.1 具體原因不知,反正127.0.0.1連不上
        'host' => env('SWOOLE_HTTP_HOST', '0.0.0.0'), 
        'port' => env('SWOOLE_HTTP_PORT', '1215'),

      //是否后臺(tái)運(yùn)行,測試階段可以不用后臺(tái)運(yùn)行,方便查看運(yùn)行狀態(tài) 生產(chǎn)的時(shí)候后臺(tái)運(yùn)行
        'daemonize' => env('SWOOLE_HTTP_DAEMONIZE', false), 
]

'websocket' => [
        //這里是 websocket的總開關(guān), true和falsefalse,看著辦
        'enabled' => env('SWOOLE_HTTP_WEBSOCKET', true), 
    ],
  • 在路由文件里輸出下測試 route/websocket.php
Websocket::on('connect', function ($websocket, Request $request) {
    echo "connect";
    // called while socket on connect
});

Websocket::on('disconnect', function ($websocket) {
    // called while socket on disconnect
    echo "disconnect";
});

現(xiàn)在我們啟動(dòng)服務(wù),鏈接測試一下

php artisan swoole:http restart

客戶端可以使用這個(gè)網(wǎng)站來測試

微信截圖_20200616153724.png

在控制臺(tái)我們可以看到連接成功的提示


微信截圖_20200616154928.png

查看代碼

2,如何接收客戶端發(fā)送的信息,并在系統(tǒng)中進(jìn)行業(yè)務(wù)處理

建立一個(gè)長鏈接并不難,網(wǎng)上也有很多其他的方法,一個(gè)單文件腳本就可以建起長鏈接,但是我們很難在一個(gè)單文件里進(jìn)行復(fù)雜的業(yè)務(wù)處理。使用 swoole-websocket,我們可以很方便的把長鏈接發(fā)送的數(shù)據(jù)經(jīng)過路由轉(zhuǎn)到 Controller,就像處理正常的 http請(qǐng)求一樣,處理websocket, laravel里面的大部分功能都可以正常使用,如 Model,Cache等。可以和我們的業(yè)務(wù)邏輯高度契合。

  • 首先我們約定所有的數(shù)據(jù)傳輸都是 json格式,必須包含兩個(gè)字段event,data。event就類似于請(qǐng)求的 route路由, data是請(qǐng)求的數(shù)據(jù)
{
  "event": "login",
  "data": {
    "uid": 1
  }
}

返回的數(shù)據(jù)也是類似

{
  "event": "return",
  "data": "我收到了你的消息{"uid":1}"
}

以下是大概思路,具體還請(qǐng)查看代碼

  • 1,創(chuàng)建一個(gè)WebsocketHandler類,放在哪都行,我是放在了 app\Swoole
    這個(gè)類主要是對(duì) websocket的一個(gè)操作類,有三個(gè)事件onOpen,onMessage,onClose,我這里只用了 onOpen事件,就是長鏈接建立鏈接事件,這里我要返回 fd(客戶端的一個(gè)編號(hào),后面所有向客戶端發(fā)信息都需要這個(gè) fd),當(dāng)然也可以做其他的處理
public function onOpen($fd, Request $request)
    {
        /**
         * 客戶端建立起長鏈接后,返回客戶端fd
         */
        $this->server->push($fd, json_encode(['event' => 'open', 'data' => ['fd' => $fd]]));
        return true;
    }

鏈接建立后客戶端會(huì)收到信息

{
    "event": "open",
    "data": {
        "fd": 2
    }
}
  • 2,創(chuàng)建一個(gè)Parser類,仍然放在app\Swoole
    這個(gè)類主要是對(duì)長鏈接傳送的數(shù)據(jù)進(jìn)行 encode和 decode,如果不想用 json或者有其他的數(shù)據(jù)轉(zhuǎn)換可以在這里面
public function encode(string $event, $data)
    {
        $string = ['event' => $event, 'data' => $data];
        return json_encode($string);
    }

public function decode($frame)
    {
        //這里是解析客戶端發(fā)來的數(shù)據(jù),我們約定所有的傳輸都是json
        $json = $frame->data;
        $data = json_decode($json, true);
        if (!$data || !isset($data['event'])) {
            return ['event' => 'error', 'data' => $frame->data];
        }
        return ['event' => $data['event'], 'data' => $data['data'] ?? ''];
    }
  • 3,創(chuàng)建一條路由,route/websocket.php
/**
 * 定義一個(gè)login路由,指向控制器方法,和http類似
 */
Websocket::on('login','App\Http\Controllers\Index\LoginController@index');
  • 4,修改 config/swoole_websocket.php config/swoole_websocket.php,設(shè)置我們剛才自已添加的兩個(gè)類
'handler' => \App\Swoole\WebsocketHandler::class,
'parser' => \App\Swoole\Parser::class,
  • 5, 創(chuàng)建控制器方法App\Http\Controllers\Index\LoginController
public function index(Websocket $websocket, $data)
    {
        /**
         * 這里就可以做業(yè)務(wù)處理,比如綁定用戶和fd等
         */
        $websocket->emit('return', "我收到了你的消息" . json_encode($data));
    }

這里面注入兩個(gè)變量,一個(gè)是 websocket,用來操作 websocket的,比如回復(fù)信息,data就是客戶端發(fā)送的數(shù)據(jù)

到此就可以測試了


微信截圖_20200616172054.png

查看代碼

有問題請(qǐng)留言

未完待續(xù)

2,在普通http請(qǐng)求中,服務(wù)器主動(dòng)向客戶端推送長鏈接消息

3,聊天室,群發(fā)功能

4,wss長鏈接證書配置

5,長鏈接的負(fù)載均衡問題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容