add 正向 ws adapter

This commit is contained in:
crazywhalecc
2023-05-20 18:27:04 +08:00
parent 34a46695b2
commit 5b882ad190
4 changed files with 57 additions and 11 deletions

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace ZM\Context\Trait; namespace ZM\Context\Trait;
use OneBot\Driver\Coroutine\Adaptive; use OneBot\Driver\Coroutine\Adaptive;
use OneBot\Driver\Interfaces\WebSocketClientInterface;
use OneBot\Util\Utils; use OneBot\Util\Utils;
use OneBot\V12\Object\Action; use OneBot\V12\Object\Action;
use OneBot\V12\Object\ActionResponse; use OneBot\V12\Object\ActionResponse;
@@ -72,7 +73,12 @@ trait BotActionTrait
logger()->error("机器人 [{$self['platform']}:{$self['user_id']}] 没有连接或未就绪,无法发送数据"); logger()->error("机器人 [{$self['platform']}:{$self['user_id']}] 没有连接或未就绪,无法发送数据");
return false; 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) { } elseif ($this instanceof BotConnectContext) {
// self 为空,说明可能是发送的元动作,需要通过 fd 来查找对应的 connect 连接 // self 为空,说明可能是发送的元动作,需要通过 fd 来查找对应的 connect 连接
$flag = $this->getFlag(); $flag = $this->getFlag();

View File

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

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ZM\Plugin\OneBot; namespace ZM\Plugin\OneBot;
use OneBot\Driver\Interfaces\WebSocketClientInterface;
use OneBot\V12\Object\OneBotEvent; use OneBot\V12\Object\OneBotEvent;
use ZM\Context\BotConnectContext; use ZM\Context\BotConnectContext;
use ZM\Context\BotContext; use ZM\Context\BotContext;
@@ -77,6 +78,22 @@ class BotMap
return true; 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 * 获取所有机器人对应的 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 public static function getBotContext(string|int $bot_id = '', string $platform = ''): BotContext
{ {
if (isset(self::$bot_ctx_cache[$platform][$bot_id])) { if (isset(self::$bot_ctx_cache[$platform][$bot_id])) {

View File

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