- 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接管完成.