Skip to content

Commit eb5cda8

Browse files
committed
-Websocket.Client
1 parent c038016 commit eb5cda8

5 files changed

Lines changed: 137 additions & 90 deletions

File tree

src/HuaJiBot.NET.Plugin.MessageBridge/HuaJiBot.NET.Plugin.MessageBridge.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
</PropertyGroup>
77
<ItemGroup>
88
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
9-
<PackageReference Include="Websocket.Client" Version="5.3.0" />
109
</ItemGroup>
1110
<ItemGroup>
1211
<ProjectReference Include="..\HuaJiBot.NET\HuaJiBot.NET.csproj" />

src/HuaJiBot.NET.Plugin.MessageBridge/PluginMain.cs

Lines changed: 66 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
using System.Collections.Concurrent;
2-
using System.Net.WebSockets;
32
using System.Reflection;
43
using System.Text;
54
using HuaJiBot.NET.Bot;
65
using HuaJiBot.NET.Commands;
76
using HuaJiBot.NET.Events;
7+
using HuaJiBot.NET.MQ;
88
using HuaJiBot.NET.Plugin.MessageBridge.Types;
99
using HuaJiBot.NET.Plugin.MessageBridge.Types.Packet;
10+
using Microsoft.Extensions.Logging;
1011
using Newtonsoft.Json;
1112
using Newtonsoft.Json.Converters;
12-
using Websocket.Client;
1313
using ClientEventType = HuaJiBot.NET.Plugin.MessageBridge.PluginConfig.GroupConfig.ClientEventType;
1414

1515
namespace HuaJiBot.NET.Plugin.MessageBridge;
@@ -70,81 +70,61 @@ public partial class PluginMain : PluginBase, IPluginWithConfig<PluginConfig>
7070
{
7171
//配置
7272
public PluginConfig Config { get; } = new();
73-
private readonly Dictionary<PluginConfig.ClientInfo, WebsocketClient> _clients = new();
73+
private readonly Dictionary<PluginConfig.ClientInfo, IServerlessMQ> _clients = new();
7474

7575
//初始化
7676
protected override async Task InitializeAsync()
7777
{
7878
foreach (var clientInfo in Config.Clients)
7979
{
80-
WebsocketClient client =
81-
new(
82-
new Uri(clientInfo.Address),
83-
() =>
84-
{
85-
var cfg = new ClientWebSocket
86-
{
87-
Options =
88-
{
89-
KeepAliveInterval = TimeSpan.FromSeconds(5),
90-
CollectHttpResponseDetails = true,
91-
},
92-
};
93-
if (!string.IsNullOrEmpty(clientInfo.Token))
94-
{
95-
cfg.Options.SetRequestHeader(
96-
"Authorization",
97-
"Bearer " + clientInfo.Token
98-
);
99-
cfg.Options.SetRequestHeader("client-type", "IM");
100-
cfg.Options.SetRequestHeader("client-subtype", "QQ");
101-
cfg.Options.SetRequestHeader(
102-
"client-name",
103-
BasePacket.DefaultInformation?.Name
104-
);
105-
cfg.Options.SetRequestHeader(
106-
"client-version",
107-
BasePacket.DefaultInformation?.Version
108-
);
109-
cfg.Options.SetRequestHeader("address", clientInfo.Address);
110-
}
111-
return cfg;
112-
}
113-
)
114-
{
115-
IsReconnectionEnabled = true,
116-
ReconnectTimeout = null,
117-
MessageEncoding = Encoding.UTF8,
118-
IsTextMessageConversionEnabled = true,
119-
};
120-
client.MessageReceived.Subscribe(msg =>
80+
// 构建自定义请求头
81+
var headers = new Dictionary<string, string>
12182
{
122-
if (msg.MessageType == WebSocketMessageType.Text)
83+
["client-type"] = "IM",
84+
["client-subtype"] = "QQ",
85+
["client-name"] = BasePacket.DefaultInformation?.Name ?? "Unknown",
86+
["client-version"] = BasePacket.DefaultInformation?.Version ?? "Unknown",
87+
["address"] = clientInfo.Address,
88+
};
89+
90+
// 创建 ILogger
91+
ILogger logger = Service.Logger;
92+
93+
var client = new ServerlessMQ(
94+
url: clientInfo.Address,
95+
token: clientInfo.Token,
96+
logger: logger,
97+
headers: headers
98+
);
99+
100+
// 订阅连接事件
101+
client.OnConnected += info =>
102+
{
103+
var status = info.IsReconnect ? "重新连接" : "连接";
104+
Info($"[{clientInfo.Address}] {status}成功 - {info.Timestamp:HH:mm:ss}");
105+
};
106+
107+
client.OnClosed += info =>
108+
{
109+
Info(
110+
$"[{clientInfo.Address}] 连接断开 - 类型: {info.Type}, 原因: {info.Reason ?? "未知"}"
111+
);
112+
};
113+
114+
// 订阅消息接收事件
115+
client.OnPacket += async data =>
116+
{
117+
try
123118
{
124-
try
125-
{
126-
_ = ProcessMessageFromClientAsync(
127-
msg.Text ?? throw new NullReferenceException("msg.Text"),
128-
clientInfo
129-
);
130-
}
131-
catch (Exception e)
132-
{
133-
Error("处理消息时出现异常:", e);
134-
}
119+
var messageRaw = data.ToString();
120+
await ProcessMessageFromClientAsync(messageRaw, clientInfo);
135121
}
136-
else
122+
catch (Exception e)
137123
{
138-
Info("收到非文本消息!");
124+
Error($"[{clientInfo.Address}] 处理消息时出现异常:", e);
139125
}
140-
});
141-
client.DisconnectionHappened.Subscribe(info =>
142-
Info("Disconnection Happened " + info.Type)
143-
);
144-
client.ReconnectionHappened.Subscribe(info =>
145-
Info("Reconnection Happened " + info.Type)
146-
);
147-
await client.Start();
126+
};
127+
148128
_clients.Add(clientInfo, client);
149129
}
150130

@@ -332,16 +312,10 @@ private static bool StringToToggle(string input, out bool result)
332312
{
333313
switch (input.ToLower())
334314
{
335-
case "开"
336-
or "开启"
337-
or "on"
338-
or "true":
315+
case "开" or "开启" or "on" or "true":
339316
result = true;
340317
return true;
341-
case "关"
342-
or "关闭"
343-
or "off"
344-
or "false":
318+
case "关" or "关闭" or "off" or "false":
345319
result = false;
346320
return true;
347321
default:
@@ -409,7 +383,8 @@ select EnumToAttributeName(x)
409383
Config
410384
.Clients.SelectMany(x => x.Groups)
411385
.FirstOrDefault(x => x is { Enabled: true })
412-
?.ForwardFromClientDisabledEvent.Contains(type) ?? true;
386+
?.ForwardFromClientDisabledEvent.Contains(type)
387+
?? true;
413388
e.Reply("状态 可选:true、false\n" + $"当前{name}状态:{!currentStatusDisabled}");
414389
return;
415390
}
@@ -432,5 +407,20 @@ select EnumToAttributeName(x)
432407
e.Reply($"未找到群 {e.GroupId} 的配置");
433408
}
434409

435-
protected override void Unload() { }
410+
protected override void Unload()
411+
{
412+
// 释放所有 WebSocket 连接
413+
foreach (var (_, client) in _clients)
414+
{
415+
try
416+
{
417+
client.Dispose();
418+
}
419+
catch (Exception e)
420+
{
421+
Warn("释放 WebSocket 连接时出现异常:", e);
422+
}
423+
}
424+
_clients.Clear();
425+
}
436426
}

src/HuaJiBot.NET/Logger/ConsoleLogger.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Reflection;
2+
using Microsoft.Extensions.Logging;
23

34
namespace HuaJiBot.NET.Logger;
45

@@ -34,4 +35,59 @@ public void LogError(object message, object? detail)
3435
+ $"{Environment.NewLine}---"
3536
);
3637
}
38+
39+
// Implementation of Microsoft.Extensions.Logging.ILogger interface
40+
public void Log<TState>(
41+
LogLevel logLevel,
42+
EventId eventId,
43+
TState state,
44+
Exception? exception,
45+
Func<TState, Exception?, string> formatter
46+
)
47+
{
48+
if (!IsEnabled(logLevel))
49+
return;
50+
51+
var message = formatter(state, exception);
52+
var timestamp = Utils.NetworkTime.Now;
53+
var logLevelStr = logLevel switch
54+
{
55+
LogLevel.Trace => "TRACE",
56+
LogLevel.Debug => "DEBUG",
57+
LogLevel.Information => "INFO",
58+
LogLevel.Warning => "WARN",
59+
LogLevel.Error => "ERROR",
60+
LogLevel.Critical => "CRITICAL",
61+
LogLevel.None => "NONE",
62+
_ => logLevel.ToString().ToUpper()
63+
};
64+
65+
if (exception != null)
66+
{
67+
Console.WriteLine(
68+
$"[{timestamp:yyyy-MM-dd HH:mm:ss}] [{logLevelStr}] {message}"
69+
+ $"{Environment.NewLine}---{Environment.NewLine}"
70+
+ $"{exception}"
71+
+ $"{Environment.NewLine}---"
72+
);
73+
}
74+
else
75+
{
76+
Console.WriteLine($"[{timestamp:yyyy-MM-dd HH:mm:ss}] [{logLevelStr}] {message}");
77+
}
78+
}
79+
80+
public bool IsEnabled(LogLevel logLevel)
81+
{
82+
// Enable all log levels by default
83+
return logLevel != LogLevel.None;
84+
}
85+
86+
public IDisposable? BeginScope<TState>(TState state)
87+
where TState : notnull
88+
{
89+
// Console logger doesn't support scopes by default
90+
// Return null to indicate no scope is created
91+
return null;
92+
}
3793
}

src/HuaJiBot.NET/Logger/ILogger.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
namespace HuaJiBot.NET.Logger;
1+
using Microsoft.Extensions.Logging;
22

3-
public interface ILogger
3+
namespace HuaJiBot.NET.Logger;
4+
5+
public interface ILogger : Microsoft.Extensions.Logging.ILogger
46
{
57
/// <summary>
68
/// 日志

src/HuaJiBot.NET/MQ/IServerlessMQ.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class ConnectionInfo
2222
/// 连接时间
2323
/// </summary>
2424
public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.Now;
25-
25+
2626
/// <summary>
2727
/// 是否为重连
2828
/// </summary>
@@ -38,22 +38,22 @@ public class DisconnectionInfo
3838
/// 断开时间
3939
/// </summary>
4040
public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.Now;
41-
41+
4242
/// <summary>
4343
/// 断开类型
4444
/// </summary>
4545
public DisconnectionType Type { get; set; }
46-
46+
4747
/// <summary>
4848
/// 断开原因描述
4949
/// </summary>
5050
public string? Reason { get; set; }
51-
51+
5252
/// <summary>
5353
/// 关闭状态码
5454
/// </summary>
5555
public int? CloseStatus { get; set; }
56-
56+
5757
/// <summary>
5858
/// 异常信息
5959
/// </summary>
@@ -69,29 +69,29 @@ public enum DisconnectionType
6969
/// 未知原因
7070
/// </summary>
7171
Unknown,
72-
72+
7373
/// <summary>
7474
/// 主动关闭
7575
/// </summary>
7676
ByUser,
77-
77+
7878
/// <summary>
7979
/// 服务器关闭
8080
/// </summary>
8181
ByServer,
82-
82+
8383
/// <summary>
8484
/// 网络错误
8585
/// </summary>
8686
Error,
87-
87+
8888
/// <summary>
8989
/// 连接丢失
9090
/// </summary>
9191
Lost,
92-
92+
9393
/// <summary>
9494
/// 超时
9595
/// </summary>
96-
Timeout
96+
Timeout,
9797
}

0 commit comments

Comments
 (0)