Skip to content

Commit c038016

Browse files
committed
+WebsocketClientLite.PCL
1 parent c8213c4 commit c038016

8 files changed

Lines changed: 443 additions & 120 deletions

File tree

src/HuaJiBot.NET.Plugin.GitHubBridge/HuaJiBot.NET.Plugin.GitHubBridge.csproj

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

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

Lines changed: 46 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
using System.Net.WebSockets;
2-
using System.Text;
1+
using HuaJiBot.NET.MQ;
32
using HuaJiBot.NET.Plugin.GitHubBridge.EventDispatch;
43
using HuaJiBot.NET.Plugin.GitHubBridge.Types;
54
using HuaJiBot.NET.Plugin.GitHubBridge.Types.IssueCommentEventBody;
65
using HuaJiBot.NET.Plugin.GitHubBridge.Types.IssuesEventBody;
76
using HuaJiBot.NET.Plugin.GitHubBridge.Types.PushEventBody;
87
using HuaJiBot.NET.Plugin.GitHubBridge.Types.WorkflowRunEventBody;
9-
using Newtonsoft.Json;
10-
using Newtonsoft.Json.Linq;
11-
using Websocket.Client;
128

139
namespace HuaJiBot.NET.Plugin.GitHubBridge;
1410

@@ -50,118 +46,62 @@ public partial class PluginMain : PluginBase, IPluginWithConfig<PluginConfig>
5046
//配置
5147
public PluginConfig Config { get; } = new();
5248

53-
//处理消息
54-
private async Task ProcessMessageAsync(string msg)
55-
{
56-
var jsonObject = JObject.Parse(msg);
57-
if (jsonObject.TryGetValue("type", out var pktTypeObj))
58-
{
59-
var pktType = pktTypeObj.Value<string>();
60-
if (pktType == "active_clients_change")
61-
{
62-
var data = jsonObject["data"]!.Value<JArray>("clients")!;
63-
var clients = data.Select(x =>
64-
x.Value<string>("address")
65-
+ "("
66-
+ (x["headers"]?["Cf-Ipcountry"]?[0] ?? "?")
67-
+ ":"
68-
+ (x["headers"]?["X-Forwarded-For"]?[0] ?? "?")
69-
+ ")"
70-
)
71-
.ToArray();
72-
Info("当前在线客户端:" + string.Join(", ", clients));
73-
}
74-
else if (pktType == "webhook")
75-
{
76-
var e = jsonObject["data"]!.ToObject<Event>()!;
77-
{
78-
switch (e.Body)
79-
{
80-
case PushEventBody body: //推送事件
81-
await this.DispatchPushEventAsync(body);
82-
break;
83-
case IssuesEventBody body: //issue事件
84-
await this.DispatchIssuesEventAsync(body);
85-
break;
86-
case IssueCommentEventBody body: //issue comment事件
87-
await this.DispatchIssueCommentEventAsync(body);
88-
break;
89-
case WorkflowRunEventBody body: //actions构建事件
90-
await this.DispatchWorkflowRunEventAsync(body);
91-
break;
92-
case UnknownEventBody body:
93-
Info("收到未实现的事件!" + e.Headers.XGithubEvent[0]);
94-
break;
95-
}
96-
}
97-
}
98-
return;
99-
}
100-
}
101-
10249
//初始化
10350
protected override async Task InitializeAsync()
10451
{
10552
ShortLinkApi = new ShortLinkApi(Config.ShortLinkToken);
106-
WebsocketClient client = new(
107-
new Uri(Config.Address),
108-
() =>
53+
ServerlessMQ client = new(Config.Address, Config.AuthBearer);
54+
client.OnWebhook += async data =>
55+
{
56+
var e = data.ToObject<Event>()!;
10957
{
110-
var client = new ClientWebSocket
58+
switch (e.Body)
11159
{
112-
Options = { CollectHttpResponseDetails = true },
113-
};
114-
client.Options.SetRequestHeader("Authorization", $"Bearer {Config.AuthBearer}");
115-
return client;
60+
case PushEventBody body: //推送事件
61+
await this.DispatchPushEventAsync(body);
62+
break;
63+
case IssuesEventBody body: //issue事件
64+
await this.DispatchIssuesEventAsync(body);
65+
break;
66+
case IssueCommentEventBody body: //issue comment事件
67+
await this.DispatchIssueCommentEventAsync(body);
68+
break;
69+
case WorkflowRunEventBody body: //actions构建事件
70+
await this.DispatchWorkflowRunEventAsync(body);
71+
break;
72+
case UnknownEventBody body:
73+
Info("收到未实现的事件!" + e.Headers.XGithubEvent[0]);
74+
break;
75+
}
11676
}
117-
)
77+
};
78+
client.OnConnected += info =>
11879
{
119-
IsReconnectionEnabled = true,
120-
ReconnectTimeout = null,
121-
MessageEncoding = Encoding.UTF8,
122-
IsTextMessageConversionEnabled = true,
80+
var status = info.IsReconnect ? "重新连接成功" : "连接成功";
81+
Info($"{status} - 时间: {info.Timestamp:yyyy-MM-dd HH:mm:ss}");
12382
};
124-
client.MessageReceived.Subscribe(msg =>
83+
client.OnClosed += info =>
12584
{
126-
if (msg.MessageType == WebSocketMessageType.Text)
127-
{
128-
try
129-
{
130-
ProcessMessageAsync(msg.Text ?? throw new NullReferenceException("msg.Text"))
131-
.ContinueWith(
132-
task =>
133-
{
134-
var ex = task.Exception;
135-
if (ex is not null)
136-
Error("ProcessMessage 处理消息时出现异常:", ex);
137-
if (msg.Text is { } raw)
138-
Error("ProcessMessage 处理消息时出现异常Raw:", raw);
139-
},
140-
TaskContinuationOptions.OnlyOnFaulted
141-
);
142-
}
143-
catch (Exception e)
144-
{
145-
Error("处理消息时出现异常:", e);
146-
if (msg.Text is { } raw)
147-
Error("处理消息时出现异常Raw:", raw);
148-
}
149-
}
150-
else
151-
{
152-
Info("收到非文本消息!");
153-
}
154-
});
155-
client.DisconnectionHappened.Subscribe(info =>
15685
Info(
157-
"Disconnection Happened. Type:"
158-
+ info.Type
159-
+ " Description:"
160-
+ info.CloseStatusDescription
161-
)
162-
);
163-
client.ReconnectionHappened.Subscribe(info => Info("Reconnection Happened " + info.Type));
164-
await client.Start();
86+
$"连接断开 - 类型: {info.Type}, 原因: {info.Reason ?? "未知"}, 时间: {info.Timestamp:yyyy-MM-dd HH:mm:ss}"
87+
+ (info.CloseStatus.HasValue ? $", 状态码: {info.CloseStatus}" : "")
88+
);
89+
};
90+
client.OnClientChanged += async clients =>
91+
{
92+
var data = clients.Clients;
93+
var clientsStr = data.Select(x =>
94+
x.Address
95+
+ "("
96+
+ (x.Headers.GetValueOrDefault("Cf-Ipcountry")?[0] ?? "?")
97+
+ ":"
98+
+ (x.Headers.GetValueOrDefault("X-Forwarded-For")?[0] ?? "?")
99+
+ ")"
100+
)
101+
.ToArray();
102+
Info("当前在线客户端:" + string.Join(", ", clientsStr));
103+
};
104+
165105
Info("启动成功!");
166106
}
167107

src/HuaJiBot.NET.Plugin.MessageBridge/Types/BasePacket.cs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Newtonsoft.Json;
2+
using Newtonsoft.Json.Linq;
23
using Newtonsoft.Json.Serialization;
34

45
namespace HuaJiBot.NET.Plugin.MessageBridge.Types;
@@ -10,24 +11,25 @@ public abstract class BasePacket
1011

1112
public string ToJson() => JsonConvert.SerializeObject(this, SerializerSettings.Value);
1213

14+
public static BasePacket? FromJson(JObject json) =>
15+
json.ToObject<BasePacket>(JsonSerializer.Create(SerializerSettings.Value));
16+
1317
public static BasePacket? FromJson(string json) =>
1418
JsonConvert.DeserializeObject<BasePacket>(json, SerializerSettings.Value);
1519

16-
private static readonly Lazy<JsonSerializerSettings> SerializerSettings =
17-
new(
18-
() =>
19-
new()
20-
{
21-
ContractResolver = new DefaultContractResolver
22-
{
23-
NamingStrategy = new SnakeCaseNamingStrategy()
24-
},
25-
Converters = [new PacketConverter()]
26-
}
27-
);
20+
private static readonly Lazy<JsonSerializerSettings> SerializerSettings = new(() =>
21+
new()
22+
{
23+
ContractResolver = new DefaultContractResolver
24+
{
25+
NamingStrategy = new SnakeCaseNamingStrategy(),
26+
},
27+
Converters = [new PacketConverter()],
28+
}
29+
);
2830

2931
[JsonIgnore]
30-
public static SenderInformation? DefaultInformation = new SenderInformation(
32+
public static SenderInformation? DefaultInformation = new(
3133
"QQGroup",
3234
"HuaJiBot.NET.Plugin.MessageBridge",
3335
"?"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using HuaJiBot.NET.Logger;
2+
using HuaJiBot.NET.MQ;
3+
using Microsoft.Extensions.Logging;
4+
using Newtonsoft.Json;
5+
using Newtonsoft.Json.Linq;
6+
7+
namespace HuaJiBot.NET.UnitTest;
8+
9+
internal class WebsocketTest
10+
{
11+
private Lazy<ServerlessMQ> _mq = new(() =>
12+
new(
13+
"wss://mq.nbtca.space/github",
14+
"nbtca_github_17126334-0997-4ba7-bdfc-4ab505064ea5",
15+
LoggerFactory
16+
.Create(builder =>
17+
{
18+
builder.AddConsole().SetMinimumLevel(LogLevel.Debug); // 控制台输出最低级别
19+
})
20+
.CreateLogger(nameof(WebsocketTest))
21+
)
22+
);
23+
24+
private ServerlessMQ MQ => _mq.Value;
25+
26+
[Test]
27+
public async Task TestClientChanged()
28+
{
29+
TaskCompletionSource<ActiveBroadcastPacketData> tcs = new();
30+
MQ.OnClientChanged += (e) =>
31+
{
32+
tcs.SetResult(e);
33+
return ValueTask.CompletedTask;
34+
};
35+
var result = await tcs.Task;
36+
Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));
37+
}
38+
39+
[Test]
40+
public async Task TestWebhook()
41+
{
42+
TaskCompletionSource<JToken> tcs = new();
43+
MQ.OnWebhook += e =>
44+
{
45+
tcs.SetResult(e);
46+
return ValueTask.CompletedTask;
47+
};
48+
var result = await tcs.Task;
49+
Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));
50+
}
51+
52+
[Test]
53+
public async Task TestPacket()
54+
{
55+
TaskCompletionSource<JToken> tcs = new();
56+
MQ.OnPacket += (e) =>
57+
{
58+
tcs.SetResult(e);
59+
return ValueTask.CompletedTask;
60+
};
61+
var result = await tcs.Task;
62+
Console.WriteLine(JsonConvert.SerializeObject(result, Formatting.Indented));
63+
}
64+
}

src/HuaJiBot.NET/HuaJiBot.NET.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<PackageReference Include="SixLabors.Fonts" Version="2.1.3" />
1616
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
1717
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
18+
<PackageReference Include="WebsocketClientLite.PCL" Version="8.2.0" />
1819
</ItemGroup>
1920

2021
<ItemGroup>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace HuaJiBot.NET.MQ;
2+
3+
public class ActiveBroadcastPacketData
4+
{
5+
public required ClientInfo[] Clients;
6+
7+
public class ClientInfo
8+
{
9+
public required string Address;
10+
public required Dictionary<string, string[]> Headers;
11+
}
12+
}

0 commit comments

Comments
 (0)