首頁  >  文章  >  php框架  >  利用ThinkPHP6實現Websocket廣播

利用ThinkPHP6實現Websocket廣播

WBOY
WBOY原創
2023-06-20 08:41:341636瀏覽

隨著現代web應用程式的不斷發展,即時通訊成為了必須的功能之一。而WebSocket 技術就是其中一種最受歡迎的即時通訊方式,能夠在伺服器和用戶端之間建立持久的雙向連接,實現即時通訊。

ThinkPHP 是一個非常流行的 PHP 框架,ThinkPHP 6 自帶了 Swoole 擴充包,使得在使用 WebSocket 技術時變得非常簡單。本文將介紹如何使用 ThinkPHP 6 框架來實作一個 WebSocket 廣播功能。

環境需求

在開始之前,需要準備以下環境:

  • PHP 7.2
  • Swoole 擴充功能
  • ##Composer
  • 基本的Web 開發知識
建立專案

首先,我們需要建立一個新的專案:

composer create-project topthink/think my-project

然後,為了方便使用WebSocket ,我們需要在專案的

composer.json 檔案中新增Swoole 擴充功能:

"require": {
    "topthink/think-swoole": "^2.0",
    "swoole/swoole": "^4.7"
}

完成後,執行下列指令進行安裝:

composer install

建立控制器

接下來,我們需要建立一個控制器來處理WebSocket 的請求。在

app/controller 目錄下建立一個名為Websocket.php 的文件,寫入以下程式碼:

<?php

declare(strict_types=1);

namespace appcontroller;

use thinkswooleWebsocket as SwooleWebsocket;
use SwooleWebSocketFrame;

class Websocket extends SwooleWebsocket
{
    /**
     * 监听连接事件
     * @param SwooleWebSocketServer $server
     * @param SwooleHttpRequest $request
     */
    public function onOpen($server, $request)
    {
    }

    /**
     * 监听接收消息事件
     * @param SwooleWebSocketServer $server
     * @param Frame $frame
     */
    public function onMessage($server, Frame $frame)
    {
    }

    /**
     * 监听关闭事件
     * @param SwooleWebSocketServer $server
     * @param int $fd
     */
    public function onClose($server, $fd)
    {
    }
}

在上面的程式碼中,我們繼承了

thinkswooleWebsocket 類,並重寫了其中的三個方法:

  • onOpen 方法用於監聽連接事件;
  • # onMessage 方法用於監聽接收訊息事件;
  • onClose 方法用於監聽關閉事件。
目前,這些方法並沒有做任何事情,接下來我們將會在這些方法中加入 WebSocket 通訊的邏輯。

註冊路由

在控制器建立好之後,我們需要在路由中進行註冊。在

app/route.php 檔案中加入以下內容:

use thinkacadeRoute;

Route::post('/ws', 'Websocket@onMessage')->middleware(    hinkmiddlewareAllowCrossDomain::class);

這裡使用了

Route::post 方法來註冊路由。這個路由的請求方式是 POST,路徑為 /ws,並將請求對應到了 Websocket 控制器的 onMessage 方法上。

編寫 WebSocket 通訊邏輯

現在,我們已經完成了 WebSocket 路由和控制器的建立與註冊。接下來,我們需要在控制器中新增 WebSocket 通訊的邏輯。我們將使用 Swoole 的 WebSocket 服務端來實作 WebSocket 通訊。

onOpen 方法中,我們可以取得客戶端的連接對象,並將其儲存起來,以便後續使用。在 onMessage 方法中,我們可以取得客戶端所傳送的訊息,並將這則訊息廣播給其它客戶端。在 onClose 方法中,我們需要將客戶端從連線池中移除。

app/controller 目錄下建立一個名為WebSocketServer.php 的文件,寫入以下程式碼:

<?php

declare(strict_types=1);

namespace appcontroller;

use SwooleHttpResponse;
use SwooleWebSocketFrame;
use SwooleWebSocketServer;
use thinkswoolewebsocketHandlerInterface;

class WebSocketServer implements HandlerInterface
{
    /**
     * @var array $connections
     */
    private $connections = [];

    /**
     * 监听连接事件
     * @param Server $server
     * @param SwooleHttpRequest $request
     */
    public function onOpen(Server $server, SwooleHttpRequest $request): void
    {
        $this->connections[$request->fd] = $request->fd;

        echo "client-{$request->fd} is connected
";
    }

    /**
     * 监听消息事件
     * @param Server $server
     * @param Frame $frame
     */
    public function onMessage(Server $server, Frame $frame): void
    {
        foreach ($this->connections as $fd) {
            $info = $server->getClientInfo((int)$fd);
            if ($info && isset($info['websocket_status']) && $info['websocket_status'] == WEBSOCKET_STATUS_FRAME) {
                $server->push($fd, $frame->data);
            } else {
                unset($this->connections[$fd]);
            }
        }

        echo "received message from client-{$frame->fd}: {$frame->data}
";
    }

    /**
     * 监听关闭事件
     * @param Server $server
     * @param int $fd
     * @param int $reactorId
     */
    public function onClose(Server $server, int $fd, int $reactorId): void
    {
        unset($this->connections[$fd]);

        echo "client-{$fd} is closed
";
    }

    /**
     * @param Response $response
     */
    public function onHandShake(Request $request, Response $response): bool
    {
        // Do nothing
        return true;
    }
}

設定WebSocket 服務

在寫入WebSocket 的服務程式碼之前,我們需要在

config 目錄下建立一個名為swoole.php 的設定文件,寫入以下內容:

return [
    'socket_type' => 'websocket',
    'host'        => '0.0.0.0',
    'port'        => 9501,
    'mode'        => SWOOLE_PROCESS,
    'sock_type'   => SWOOLE_SOCK_TCP,
    'settings' => [
        'worker_num' => swoole_cpu_num(),
    ],
    'handler' => ppcontrollerWebSocketServer::class,
];

在上面的程式碼中,我們透過設定檔告訴應用程式如何啟動Swoole WebSocket 服務。我們啟動

websocket socket 類型,綁定在 0.0.0.0:9501 上,並開啟了多進程模式,使用 TCP 協定。 worker_num 配置項目設定了伺服器的進程數,這裡使用了swoole_cpu_num() 用於返回系統CPU 數量;handler 配置項目指定了我們在上文中建立的WebSocketServer 類別。

執行 WebSocket 服務

在完成了建立、設定 WebSocket 服務的程式碼後,我們需要執行一下程式碼,來開啟 WebSocket 服務。在命令列中執行以下命令即可:

php think swoole start --mode=websocket

Websocket 服務已經啟動,你可以透過存取你的應用程式來測試它。你可以使用這個位址:

ws://your-domain:9501/ws。在瀏覽器中開啟多個選項卡,分別測試 WebSocket 的連線、訊息傳送和接收等功能。

小結

本文介紹如何使用 ThinkPHP 6 框架來實作一個 WebSocket 廣播功能。我們透過建立控制器、註冊路由和編寫 WebSocket 通訊邏輯,以及配置 WebSocket 服務,來完成這項功能。這個範例可以作為一個簡單 WebSocket 最佳實踐,為我們開發更高級的 WebSocket 功能提供了參考。

以上是利用ThinkPHP6實現Websocket廣播的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn