Mirai-CSharp icon indicating copy to clipboard operation
Mirai-CSharp copied to clipboard

依赖注入无效

Open DUWENINK opened this issue 2 years ago • 16 comments

版本 Mirai-CSharp, Version=2.1.4.0 miral版本 v2.11.0-M1 平台 net7.0 preview1 +netcore 7.0(aspnetcore) 代码: 依赖注入

services.AddMiraiBaseFramework()   // 表示使用基于基础框架的构建器
        .AddHandler<MiraiPlugin>()
        .AddHandler<ExamplePlugin>()
        .Services // 虽然可以把 HttpApiPlugin 作为泛型参数塞入, 但不建议这么做

        .AddDefaultMiraiHttpFramework() // 表示使用 mirai-api-http 实现的构建器
        .ResolveParser<DynamicPlugin>() // 只提前解析 DynamicPlugin 将要用到的消息解析器
        .AddInvoker<MiraiHttpMessageHandlerInvoker>() // 使用默认的调度器
        .AddHandler<HttpApiPlugin>() // 可以如此添加更多消息处理器
        .AddHandler<ProcessFriendAddPlugin>()
        .AddClient<MiraiHttpSession>() // 使用默认的客户端
        .Services
        // 由于 MiraiHttpSession 使用 IOptions<MiraiHttpSessionOptions>, 其作为 Singleton 被注册
        // 配置此项将配置基于此 IServiceProvider 全局的连接配置
        // 如果你想一个作用域一个配置的话
        // 自行做一个实现类, 继承MiraiHttpSession, 构造参数中使用 IOptionsSnapshot<MiraiHttpSessionOptions>
        // 并将其传递给父类的构造参数
        // 然后在每一个作用域中!先!配置好 IOptionsSnapshot<MiraiHttpSessionOptions>, 再尝试获取 IMiraiHttpSession
        .Configure<MiraiHttpSessionOptions>(options =>
        {
            options.Host = "192.168.0.27";
            options.Port = 3652; // 端口
            options.AuthKey = "mahuatengnb"; // 凭据
        })
        .AddLogging();

好友处理程序

    // 为此消息处理类标定所需要使用到的消息解析器
    // 标定的特性仅在使用 IMessageFrameworkBuilder.AddHandler 和 IMessageFrameworkBuilder.ResolveParser 时才会
    [RegisterMiraiHttpParser(typeof(DefaultMappableMiraiHttpMessageParser<INewFriendApplyEventArgs, NewFriendApplyEventArgs>))]
    public partial class ProcessFriendAddPlugin : IMiraiHttpMessageHandler<INewFriendApplyEventArgs>
    {
        public async Task HandleMessageAsync(IMiraiHttpSession session, INewFriendApplyEventArgs e)
        {
            await session.HandleNewFriendApplyAsync(e, FriendApplyAction.Deny, "略略略");
            // 把整个事件信息直接作为第一个参数即可, 然后根据自己需要选择一个 FriendApplyAction 枚举去处理请求
            // 你也可以暂存 INewFriendApplyEventArgs e, 之后再调用 session 处理
            e.BlockRemainingHandlers = false;
        }
    }

发送消息可以正常发送 但是无法处理机器人被加请求

DUWENINK avatar Mar 10 '22 12:03 DUWENINK

辛苦提供一下 mirai-api-http 的版本 仔细看了看实现应该是没问题的

Executor-Cheng avatar Mar 10 '22 15:03 Executor-Cheng

辛苦提供一下 mirai-api-http 的版本 仔细看了看实现应该是没问题的

my mirai-api-http version is v2.4.0

DUWENINK avatar Mar 11 '22 01:03 DUWENINK

在 .NET6.0&.NET 7.0, mirai v2.9.2 + mirai-api-http v2.4.0 下可以正确处理以及响应加好友信息 ~~我怀疑是 mirai-api-http 与最新版本的 mirai 不兼容导致 mirai-api-http 未能收到加好友消息~~ ~~还需要辛苦你检查一下 mirai-console 输出~~

Executor-Cheng avatar Mar 11 '22 08:03 Executor-Cheng

我已经检查过了,console里边输出正常

DUWENINK avatar Mar 11 '22 08:03 DUWENINK

刚刚看了看, 不排除你ws连接已被断开, 而你没有修改 ExamplePlugin.Disconnected.cs 中欲连接的QQ号导致无法收悉消息 建议你先使用最小方法重新复现一次问题:

using System;
using System.Threading.Tasks;
using Mirai.CSharp.HttpApi.Handlers;
using Mirai.CSharp.HttpApi.Models.EventArgs;
using Mirai.CSharp.HttpApi.Session;

// IDisconnectedEventArgs 和 IUnknownMessageEventArgs 不需要标定 RegisterMiraiHttpParserAttribute
public partial class ReconnectPlugin : IMiraiHttpMessageHandler<IDisconnectedEventArgs>
{
    public async Task HandleMessageAsync(IMiraiHttpSession session, IDisconnectedEventArgs e)
    {
        // e.Exception: 引发掉线的响应异常, 按需处理
        while (true)
        {
            try
            {
                await session.ConnectAsync(e.LastConnectedQQNumber);
                e.BlockRemainingHandlers = true;
                break;
            }
            catch (ObjectDisposedException) // session 已被释放
            {
                break;
            }
            catch (Exception)
            {
                await Task.Delay(1000);
            }
        }
    }
}
services.AddDefaultMiraiHttpFramework() // 表示使用 mirai-api-http 实现的构建器
        .AddInvoker<MiraiHttpMessageHandlerInvoker>() // 使用默认的调度器
        .AddHandler<ProcessFriendAddPlugin>()
        .AddHandler<ReconnectPlugin>()
        .AddClient<MiraiHttpSession>() // 使用默认的客户端
        .Services
        .Configure<MiraiHttpSessionOptions>(options =>
        {
            options.Host = "192.168.0.27";
            options.Port = 3652; // 端口
            options.AuthKey = "mahuatengnb"; // 凭据
        })
        .AddLogging();

~~顺便发现了我忘了在 ExamplePlugin.Disconnected.cs 里边写 break; 这件事~~

Executor-Cheng avatar Mar 11 '22 09:03 Executor-Cheng

代码在netcore console中运行没问题 ,但是改到aspnetcore webapi中 则收不到事件处理信息 老哥有兴趣搞一个aspnetcore 的demo吗 ,it will help more person

DUWENINK avatar Mar 12 '22 01:03 DUWENINK

嗯……我觉得是包的问题。他引入了两个不同版本的DI 今天我会把#119 合并了, 发2.1.5版本出来解决一下在.NET 7.0下的依赖问题

Executor-Cheng avatar Mar 12 '22 05:03 Executor-Cheng

嗯……我觉得是包的问题。他引入了两个不同版本的DI 今天我会把#119 合并了, 发2.1.5版本出来解决一下在.NET 7.0下的依赖问题

在netcore console中没有问题(但是如果我取消wile的循环则相当于console运行一次停止),为了模拟出常驻后台效果 我把这个封装在topshelf中删除while语句问题则和使用aspnetcore 一样,因此我猜想是运行完毕释放导致的 建议参考盛派SDK的实现 //使用中间件注册 MessageHandler,指定 CustomMessageHandler 为自定义处理方法 app.UseMessageHandlerForMp("/WeChat", (stream, postModel, maxRecordCount, serviceProvider) => new SaasMessageHandler(stream, postModel, maxRecordCount, false, serviceProvider), options => { options.AccountSettingFunc = context => senparcWeixinSetting.Value; });类似这种 然后自己在自定义的处理类中实现相关逻辑即可

DUWENINK avatar Mar 12 '22 05:03 DUWENINK

那我还有一些问题 既然你是在ASP.NET Core下使用本框架, 本框架的 MiraiHttpFrameworkBuilder 注册 Invoker, Handler, Client, Subscription, SubscriptionResolver 时, 其生命周期默认为 Scoped。注册 ParserParserResolver 时, 其生命周期默认为 Singleton 意味着你需要在正确的DI容器下解析才是正确操作 并且你不能自行调用这些服务的 Dispose 方法 可以确认一下不?

Executor-Cheng avatar Mar 13 '22 04:03 Executor-Cheng

Dispose

是的 我是正常注册的 并且没有调用Dispose

DUWENINK avatar Mar 13 '22 10:03 DUWENINK

我已经发布了 v2.1.5, 添加了对.NET 7.0的支持, 你可以试一试在这个版本下问题是否仍存续 不止是要正常注册, 你还需要在 IServiceScope 中解析 Scoped 服务, 在这里就是需要在其中解析 IMiraiHttpSession, 而不是在根容器中解析

Executor-Cheng avatar Mar 14 '22 05:03 Executor-Cheng

@DUWENINK 老哥, 问题还存续嘛

Executor-Cheng avatar Mar 20 '22 12:03 Executor-Cheng

@DUWENINK 老哥, 问题还存续嘛

比较抱歉,问题还是存在的 老哥 强烈建议你分平台展示你的demo 我现在没办法直接用的topshelf把netcore console封装成服务运行的

DUWENINK avatar Mar 21 '22 02:03 DUWENINK

好的, demo两天内我会进行完善 在这期间可以辛苦clone一次本项目, 然后在你的项目中直接引用本项目, 在以下地方置一个断点帮助我解决问题不: https://github.com/Executor-Cheng/Mirai-CSharp/blob/430f2f482233a5e146454de73bb45133e43f4a88/Mirai-CSharp.HttpApi/Session/MiraiHttpSession.ReceiveMessage.cs#L55 置好断点后发一次好友请求, 看看断点是否有命中

Executor-Cheng avatar Mar 21 '22 12:03 Executor-Cheng

我已经简单做了一个ASP.NET Core 7.0的项目来测试加好友是否能正确收悉和处理, 测试是通过的 示例在这个提交里: Executor-Cheng/Mirai-CSharp@5da2ff8 如果你想要自己玩一玩, 你需要改好 Startup.cs 里边的凭据, 访问 http://127.0.0.1:5000/robot/add?robotQQ=0000000, 然后再用测试账号加你的机器人账号, 看看是否正确拒绝 正确拒绝将出现以下提示: p1

Executor-Cheng avatar Mar 22 '22 22:03 Executor-Cheng

我已经简单做了一个ASP.NET Core 7.0的项目来测试加好友是否能正确收悉和处理, 测试是通过的 示例在这个提交里: 5da2ff8 如果你想要自己玩一玩, 你需要改好 Startup.cs 里边的凭据, 访问 http://127.0.0.1:5000/robot/add?robotQQ=0000000, 然后再用测试账号加你的机器人账号, 看看是否正确拒绝 正确拒绝将出现以下提示: p1

谢谢你的demo 我打算采用你的代码进行测试,等我的消息

DUWENINK avatar Mar 23 '22 02:03 DUWENINK

问题是解决的 谢谢老哥

DUWENINK avatar Jan 31 '23 04:01 DUWENINK