- think-swoole3擴展的websocket通訊庫使用的是socket.io的模式.關于此模式網上有較多教程,因此不在此贅述.
-在app目錄下新建一個`websocket`目錄并繼續新建一個`privater`目錄.
-在privater目錄下新建`Handler.php` `Packet.php`與`Parser.php`類文件
<details>
<summary>Handler.php</summary>
~~~
<?php
namespace app\websocket\privater;
use Swoole\Server;
use Swoole\Websocket\Frame;
use Swoole\WebSocket\Server as WebsocketServer;
use think\Config;
use think\Request;
use think\swoole\contract\websocket\HandlerInterface;
//Handler全部返回false,將邏輯全部交給WebsocketEvent處理
class Handler implements HandlerInterface
{
/** @var WebsocketServer */
protected $server;
/** @var Config */
protected $config;
public function __construct(Server $server, Config $config)
{
$this->server = $server;
$this->config = $config;
}
/**
* "onOpen" listener.
*
* @param int $fd
* @param Request $request
*/
public function onOpen($fd, Request $request)
{
//交給Connect監聽處理
return false;
}
/**
* "onMessage" listener.
* only triggered when event handler not found/返回false觸發監聽,返回true直接完成
*
* @param Frame $frame
* @return bool
*/
public function onMessage(Frame $frame)
{
//返回false觸發全局監聽
return false;
}
/**
* "onClose" listener.
*
* @param int $fd
* @param int $reactorId
*/
public function onClose($fd, $reactorId)
{
return false;
}
}
~~~
</details>
<details>
<summary>Parser.php</summary>
~~~
<?php
namespace app\websocket\privater;
use think\swoole\contract\websocket\ParserInterface;
class Parser implements ParserInterface
{
/**
* Encode output payload for websocket push.
*
* @param string $event
* @param mixed $data
*
* @return mixed
*/
public function encode(string $event, $data)
{
return json_encode(['event' => $event, 'data' => $data], 320);
}
/**
* Decode message from websocket client.
* Define and return payload here.
*
* @param \Swoole\Websocket\Frame $frame
*
* @return array
*/
public function decode($frame)
{
$payload = Packet::getPayload($frame->data);
return [
'event' => $payload['event'] ?? null,
'data' => $payload['data'] ?? null,
];
}
}
~~~
</details>
<details>
<summary>Packet.php</summary>
~~~
<?php
namespace app\websocket\privater;
/**
* Class Packet
*/
class Packet
{
/**
* Get data packet from a raw payload.
*
* @param string $packet
*
* @return array|null
*/
public static function getPayload(string $packet)
{
$packet = trim($packet);
// 判斷是否為json字符串
$data = json_decode($packet, true);
if (is_null($data)) {
return;
}
return [
'event' => $data['event'],
'data' => $data['data'] ?? null,
];
}
}
~~~
</details>
> 這里簡要說明下這幾個文件用的用處:
<blockquote class="danger"> Handler.php用于websocket事件的響應,如open/message等.必要文件</blockquote >
<blockquote class="danger">Parser .php用于消息體的解析,這里使用的格式為json,若換成其他通訊格式只要下對encode/decode編解碼方法重寫即可.必要文件</blockquote >
<blockquote class="info">Packet.php僅對原有文件目錄保持完整而出現.非必要文件</blockquote >
<blockquote class="danger">替換swoole.php配置文件中的handler與parser</blockquote >
~~~
'handler' => app\websocket\privater\Handler::class,
'parser' => app\websocket\privater\Parser::class,
~~~
至此,對擴展的websocket接管完成.