Mirai-NET-Shelter / Mirai.Net

Mirai.Net是基于mirai-api-http实现的轻量级mirai社区sdk。
GNU Affero General Public License v3.0
186 stars 26 forks source link

[BUG]升级2.4.4之后无法订阅到事件 #46

Closed 05u closed 2 years ago

05u commented 2 years ago

发生了什么事? 升级2.4.4之后无法订阅到事件,回退2.4.3后正常

怎么复现? bot.MessageReceived .OfType() .Subscribe(async r => { if (r.Sender.Id != bot.QQ) { var msg = r.MessageChain.GetPlainMessage().Trim(); var repMsg = await robotService.GeneralMessageProcess(msg, r.Sender.Id); await r.SendMessageAsync(repMsg); _logger.LogInformation($"回复好友消息:{repMsg}"); } });

环境

05u commented 2 years ago

似乎不是版本问题,降版本后只成功一次 DateTime:2022-07-21 17:11:29.3710 EventId: Level:ERROR LoggerName:Websocket.Client.WebsocketClient Message:[WEBSOCKET CLIENT] Error while listening to websocket stream, error: 'Websocket传回错误的响应' Mirai.Net.Data.Exceptions.InvalidWebsocketReponseException: Websocket传回错误的响应 at Mirai.Net.Sessions.MiraiBot.ProcessWebSocketData(String data) at Mirai.Net.Sessions.MiraiBot.b__42_2(ResponseMessage message) at System.Reactive.AnonymousSafeObserver1.OnNext(T value) in d:\a\1\s\Rx.NET\Source\src\System.Reactive\AnonymousSafeObserver.cs:line 43 at System.Reactive.Subjects.Subject1.OnNext(T value) in d:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\Subject.cs:line 139 at Websocket.Client.WebsocketClient.Listen(WebSocket client, CancellationToken token) Url: Action:

SinoAHpx commented 2 years ago

请提供mirai-api-http配置文件以及你是如何初始化MiraiBot对象的

05u commented 2 years ago
## 配置文件中的值,全为默认值

## 启用的 adapter, 内置有 http, ws, reverse-ws, webhook
adapters:
  - http
  - ws

## 是否开启认证流程, 若为 true 则建立连接时需要验证 verifyKey
## 建议公网连接时开启
enableVerify: true
verifyKey: 123456

## 开启一些调式信息
debug: false

## 是否开启单 session 模式, 若为 true,则自动创建 session 绑定 console 中登录的 bot
## 开启后,接口中任何 sessionKey 不需要传递参数
## 若 console 中有多个 bot 登录,则行为未定义
## 确保 console 中只有一个 bot 登陆时启用
singleMode: false

## 历史消息的缓存大小
## 同时,也是 http adapter 的消息队列容量
cacheSize: 4096

## adapter 的单独配置,键名与 adapters 项配置相同
adapterSettings:
  ## 详情看 http adapter 使用说明 配置
  http:
    ## http server 监听的本地地址
    ## 一般为 localhost 即可, 如果多网卡等情况,自定设置
    host: 192.168.6.10

    ## http server 监听的端口
    ## 与 websocket server 可以重复, 由于协议与路径不同, 不会产生冲突
    port: 18080

    ## 配置跨域, 默认允许来自所有域名
    cors: ["*"]

  ## 详情看 websocket adapter 使用说明 配置
  ws:
    host: 192.168.6.10
    port: 18080
    reservedSyncId: -1
05u commented 2 years ago
var bot = new MiraiBot
                {
                    Address = new ConnectConfig
                    {
                        HttpAddress = new ConnectConfig.AdapterConfig("192.168.6.10", "18080"),
                        WebsocketAddress = new ConnectConfig.AdapterConfig("192.168.6.10", "18080")
                    },
                    VerifyKey = "123456",
                    QQ = "1256090066"
                };
05u commented 2 years ago

上面的配置文件被github格式化处理了,看起来有点奇怪

05u commented 2 years ago

作者您好,经过反复测试,我得补充一些信息以使得问题的描述更加准确 1.2.4.4版本 websocket无法收到消息后,我尝试降版本到2.4.3,成功了一次,但似乎是间接性的,并不是每次都能成功,有时成功有时失败 2.在2.4.4和2.4.2版本下测试从未成功

报错的日志


DateTime:2022-07-21 17:22:27.0016
EventId:
Level:ERROR
LoggerName:Websocket.Client.WebsocketClient
Message:[WEBSOCKET CLIENT] Error while listening to websocket stream, error: 'Websocket传回错误的响应' Mirai.Net.Data.Exceptions.InvalidWebsocketReponseException: Websocket传回错误的响应
   at Mirai.Net.Sessions.MiraiBot.ProcessWebSocketData(String data)
   at Mirai.Net.Sessions.MiraiBot.<StartWebsocketListenerAsync>b__42_2(ResponseMessage message)
   at System.Reactive.AnonymousSafeObserver`1.OnNext(T value) in d:\a\1\s\Rx.NET\Source\src\System.Reactive\AnonymousSafeObserver.cs:line 43
   at System.Reactive.Subjects.Subject`1.OnNext(T value) in d:\a\1\s\Rx.NET\Source\src\System.Reactive\Subjects\Subject.cs:line 139
   at Websocket.Client.WebsocketClient.Listen(WebSocket client, CancellationToken token)
Url: 
Action: 
------------------------------------------End-------------------------------------

DateTime:2022-07-21 17:26:20.2765
EventId:
Level:ERROR
LoggerName:Websocket.Client.WebsocketClient
Message:[WEBSOCKET CLIENT] Error while listening to websocket stream, error: 'The remote party closed the WebSocket connection without completing the close handshake.' System.Net.WebSockets.WebSocketException (0x80004005): The remote party closed the WebSocket connection without completing the close handshake.
 ---> System.IO.IOException: Unable to read data from the transport connection: 远程主机强迫关闭了一个现有的连接。.
 ---> System.Net.Sockets.SocketException (10054): 远程主机强迫关闭了一个现有的连接。
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
   at System.Net.Http.HttpConnection.ReadBufferedAsyncCore(Memory`1 destination)
   at System.Net.Http.HttpConnection.RawConnectionStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
   at System.Net.WebSockets.ManagedWebSocket.EnsureBufferContainsAsync(Int32 minimumRequiredBytes, CancellationToken cancellationToken, Boolean throwOnPrematureClosure)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate[TResult](Memory`1 payloadBuffer, CancellationToken cancellationToken)
   at System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate[TResult](Memory`1 payloadBuffer, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
--- End of stack trace from previous location ---
   at Websocket.Client.WebsocketClient.Listen(WebSocket client, CancellationToken token)
Url: 
Action: ```
SinoAHpx commented 2 years ago

试试把配置文件中的192.168.6.10改为localhost,参考以下示例代码:

using System.Reactive.Linq;
using Mirai.Net.Data.Messages.Receivers;
using Mirai.Net.Data.Sessions;
using Mirai.Net.Sessions;
using Mirai.Net.Utils.Scaffolds;

var bot = new MiraiBot
{
    Address = "localhost:18080",
    VerifyKey = "1145141919810",
    QQ = "xxx"
};

await bot.LaunchAsync();

bot.MessageReceived
    .OfType<GroupMessageReceiver>()
    .Subscribe(async msg =>
    {
        if (msg.MessageChain.GetPlainMessage() == "echo")
        {
            await msg.SendMessageAsync("Hello, World!");
        }
    });

System.Console.WriteLine("Launched");

while (true)
{

}
05u commented 2 years ago

20220721175940 遗憾的是,这并不工作(使用最新2.4.4版本)

SinoAHpx commented 2 years ago

很明显,我所提供的代码进行的是对GroupMessageReceiver也就是群聊消息的监听,而你好像在对bot进行私聊

05u commented 2 years ago

感谢回复,问题已经得到解决.

如同您的例子那样,可以正常工作.我仅改动了初始化MiraiBot对象的代码.

原代码

var bot = new MiraiBot
                {
                    Address = new ConnectConfig
                    {
                        HttpAddress = new ConnectConfig.AdapterConfig("192.168.6.10", "18080"),
                        WebsocketAddress = new ConnectConfig.AdapterConfig("192.168.6.10", "18080")
                    },
                    VerifyKey = "123456",
                    QQ = "1256090066"
                };

修改后

var bot = new MiraiBot
                    {
                        Address = "192.168.6.10:18080",
                        VerifyKey = "123456",
                        QQ = "1256090066"
                    };
SinoAHpx commented 2 years ago

然而即使是这样的代码也是可以正常工作的(

var bot = new MiraiBot
{
    Address = new ConnectConfig
    {
        HttpAddress = new ConnectConfig.AdapterConfig("localhost", "18080"),
        WebsocketAddress = new ConnectConfig.AdapterConfig("localhost", "18080")
    },
    VerifyKey = "1145141919810",
    QQ = "xxx"
};