add 正向 ws adapter

This commit is contained in:
crazywhalecc 2023-05-20 18:27:04 +08:00
parent 34a46695b2
commit 5b882ad190
No known key found for this signature in database
GPG Key ID: 1F4BDD59391F2680
4 changed files with 57 additions and 11 deletions

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace ZM\Context\Trait;
use OneBot\Driver\Coroutine\Adaptive;
use OneBot\Driver\Interfaces\WebSocketClientInterface;
use OneBot\Util\Utils;
use OneBot\V12\Object\Action;
use OneBot\V12\Object\ActionResponse;
@ -72,7 +73,12 @@ trait BotActionTrait
logger()->error("机器人 [{$self['platform']}:{$self['user_id']}] 没有连接或未就绪,无法发送数据");
return false;
}
$result = ws_socket($fd_map[0])->send(json_encode($a->jsonSerialize()), $fd_map[1]);
// 如果没指定 flag但指定了第三个参数且为 WebSocketClientInterface就是客户端模式
if ($fd_map[0] === null && ($fd_map[2] ?? null) instanceof WebSocketClientInterface) {
$result = $fd_map[2]->send(json_encode($a->jsonSerialize()));
} else {
$result = ws_socket($fd_map[0])->send(json_encode($a->jsonSerialize()), $fd_map[1]);
}
} elseif ($this instanceof BotConnectContext) {
// self 为空,说明可能是发送的元动作,需要通过 fd 来查找对应的 connect 连接
$flag = $this->getFlag();

View File

@ -48,6 +48,7 @@ class WebSocketFilter implements MiddlewareInterface, PipelineInterface
return false;
}
// 过滤连接信息
// 这里需要考虑一下 ws client 的情况TODO
$conn = ConnectionUtil::getConnection($event->getFd());
foreach ($this->args as $k => $v) {
if (!isset($conn[$k])) {

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ZM\Plugin\OneBot;
use OneBot\Driver\Interfaces\WebSocketClientInterface;
use OneBot\V12\Object\OneBotEvent;
use ZM\Context\BotConnectContext;
use ZM\Context\BotContext;
@ -77,6 +78,22 @@ class BotMap
return true;
}
/**
* 通过 ws client 注册机器人
*
* @param int|string $bot_id 机器人 ID
* @param string $platform 机器人平台
* @param bool $status 机器人状态
* @param WebSocketClientInterface $client 机器人对应的 ws client
*/
public static function registerBotWithWSClient(string|int $bot_id, string $platform, bool $status, WebSocketClientInterface $client): bool
{
logger()->debug('正在注册机器人:' . "{$platform}:{$bot_id}, client fd:{$client->getFd()}");
self::$bot_fds[$platform][strval($bot_id)] = [null, $client->getFd(), $client];
self::$bot_status[$platform][strval($bot_id)] = $status;
return true;
}
/**
* 获取所有机器人对应的 fd
*
@ -117,6 +134,21 @@ class BotMap
}
}
public static function unregisterBotByWSClient(WebSocketClientInterface $client): void
{
$unreg_list = [];
foreach (self::$bot_fds as $platform => $bots) {
foreach ($bots as $bot_id => $bot_fd) {
if (isset($bot_fd[2]) && $bot_fd[2] === $client) {
$unreg_list[] = [$platform, $bot_id];
}
}
}
foreach ($unreg_list as $item) {
self::unregisterBot($item[1], $item[0]);
}
}
public static function getBotContext(string|int $bot_id = '', string $platform = ''): BotContext
{
if (isset(self::$bot_ctx_cache[$platform][$bot_id])) {

View File

@ -5,6 +5,8 @@ declare(strict_types=1);
namespace ZM\Plugin\OneBot;
use Choir\Http\HttpFactory;
use DI\DependencyException;
use DI\NotFoundException;
use OneBot\Driver\Coroutine\Adaptive;
use OneBot\Driver\Event\StopException;
use OneBot\Driver\Event\WebSocket\WebSocketCloseEvent;
@ -171,25 +173,30 @@ class OneBot12Adapter extends ZMPlugin
/**
* [CALLBACK] 处理 status_update 事件,更新 BotMap
*
* @param OneBotEvent $event 机器人事件
* @param OneBotEvent $event 机器人事件
* @throws DependencyException
* @throws NotFoundException
*/
public function handleStatusUpdate(OneBotEvent $event, WebSocketMessageEvent $message_event): void
public function handleStatusUpdate(OneBotEvent $event): void
{
$status = $event->get('status');
$old = BotMap::getBotFds();
if (($status['good'] ?? false) === true) {
foreach (($status['bots'] ?? []) as $bot) {
BotMap::registerBotWithFd(
bot_id: $bot['self']['user_id'],
platform: $bot['self']['platform'],
status: $bot['good'] ?? false,
fd: $message_event->getFd(),
flag: $message_event->getSocketFlag()
);
if (container()->has(WebSocketMessageEvent::class)) {
$message_event = container()->get(WebSocketMessageEvent::class);
BotMap::registerBotWithFd(
bot_id: $bot['self']['user_id'],
platform: $bot['self']['platform'],
status: $bot['good'] ?? false,
fd: $message_event->getFd(),
flag: $message_event->getSocketFlag()
);
}
if (isset($old[$bot['self']['platform']][$bot['self']['user_id']])) {
unset($old[$bot['self']['platform']][$bot['self']['user_id']]);
}
logger()->error("[{$bot['self']['platform']}.{$bot['self']['user_id']}] 已接入,状态:" . (($bot['good'] ?? false) ? 'OK' : 'Not OK'));
logger()->notice("[{$bot['self']['platform']}.{$bot['self']['user_id']}] 已接入,状态:" . (($bot['good'] ?? false) ? 'OK' : 'Not OK'));
}
} else {
logger()->debug('该实现状态目前不是正常的,不处理 bots 列表');