XFEExtension
【DLL】XFE各类拓展是一个C#的DLL库,旨在优化C#代码中常用语句的使用,并提供更简洁的访问方式,同时提供Xunit测试框架,快速搭建服务器/客户端,免费ChatGPTAPI接口,免费通讯服务器,XFE下载器,新增格式等
关注
0
Fork
0
Star
0
返回提交历史
Modified
XFE各类拓展/CyberComm.cs
+63
-33
Modified
XFE各类拓展/XCCNetWork.cs
+66
-25
XFEstudio/XFEExtension
XCC助手修复bug,修复XCC网络通讯bug
4ff231e
代码差异
2 个文件
+129
-58
@@ -588,7 +588,7 @@ namespace XFE各类拓展.CyberComm
588
588
/// </summary>
589
589
public class CyberCommGroup
590
590
{
591
private readonly List<WebSocket> webSockets = new List<WebSocket>();
591
private readonly List<CyberCommServerEventArgs> cyberCommList = new List<CyberCommServerEventArgs>();
592
592
/// <summary>
593
593
/// 组ID
594
594
/// </summary>
@@ -596,18 +596,18 @@ namespace XFE各类拓展.CyberComm
596
596
/// <summary>
597
597
/// 添加客户端
598
598
/// </summary>
599
/// <param name="webSocket">客户端</param>
600
public void Add(WebSocket webSocket)
599
/// <param name="e">客户端</param>
600
public void Add(CyberCommServerEventArgs e)
601
601
{
602
webSockets.Add(webSocket);
602
cyberCommList.Add(e);
603
603
}
604
604
/// <summary>
605
/// 获取指定的客户端
605
/// 移除指定的客户端
606
606
/// </summary>
607
607
/// <param name="webSocket">客户端</param>
608
608
public void Remove(WebSocket webSocket)
609
609
{
610
webSockets.Remove(webSocket);
610
cyberCommList.Remove(cyberCommList.Find(x => x.CurrentWebSocket == webSocket));
611
611
}
612
612
/// <summary>
613
613
/// 移除指定索引的客户端
@@ -615,14 +615,14 @@ namespace XFE各类拓展.CyberComm
615
615
/// <param name="index">客户单索引</param>
616
616
public void RemoveAt(int index)
617
617
{
618
webSockets.RemoveAt(index);
618
cyberCommList.RemoveAt(index);
619
619
}
620
620
/// <summary>
621
621
/// 清空列表
622
622
/// </summary>
623
623
public void Clear()
624
624
{
625
webSockets.Clear();
625
cyberCommList.Clear();
626
626
}
627
627
/// <summary>
628
628
/// 群组客户端数量
@@ -631,19 +631,19 @@ namespace XFE各类拓展.CyberComm
631
631
{
632
632
get
633
633
{
634
return webSockets.Count;
634
return cyberCommList.Count;
635
635
}
636
636
}
637
637
/// <summary>
638
638
/// 索引器
639
639
/// </summary>
640
/// <param name="index">索引</param>
640
/// <param name="findFunc">查找</param>
641
641
/// <returns>客户端</returns>
642
public WebSocket this[int index]
642
public CyberCommServerEventArgs this[Predicate<CyberCommServerEventArgs> findFunc]
643
643
{
644
644
get
645
645
{
646
return webSockets[index];
646
return cyberCommList.Find(findFunc);
647
647
}
648
648
}
649
649
/// <summary>
@@ -652,27 +652,29 @@ namespace XFE各类拓展.CyberComm
652
652
/// <param name="message">群发文本消息</param>
653
653
public async Task SendGroupTextMessage(string message)
654
654
{
655
byte[] sendBuffer = Encoding.UTF8.GetBytes(message);
656
foreach (WebSocket webSocket in webSockets)
655
List<Task> tasks = new List<Task>();
656
foreach (CyberCommServerEventArgs cyberCommServerEventArgs in cyberCommList)
657
657
{
658
await webSocket.SendAsync(new ArraySegment<byte>(sendBuffer), WebSocketMessageType.Text, true, CancellationToken.None);
658
tasks.Add(cyberCommServerEventArgs.ReplyMessage(message));
659
659
}
660
await Task.WhenAll(tasks);
660
661
}
661
662
/// <summary>
662
/// 向除了指定的WS客户端外的客户端发送群组文本消息
663
/// 向指定的WS客户端发送群组文本消息
663
664
/// </summary>
664
665
/// <param name="message">群发文本消息</param>
665
/// <param name="exceptWebSocket">除了指定的WS客户端外的客户端</param>
666
public async Task SendGroupTextMessageExcept(string message, WebSocket exceptWebSocket)
666
/// <param name="findFunc">指定的WS客户端</param>
667
public async Task SendGroupTextMessage(string message, Func<CyberCommServerEventArgs, bool> findFunc)
667
668
{
668
byte[] sendBuffer = Encoding.UTF8.GetBytes(message);
669
foreach (WebSocket webSocket in webSockets)
669
List<Task> tasks = new List<Task>();
670
foreach (CyberCommServerEventArgs cyberCommServerEventArgs in cyberCommList)
670
671
{
671
if (webSocket != exceptWebSocket)
672
if (findFunc.Invoke(cyberCommServerEventArgs))
672
673
{
673
await webSocket.SendAsync(new ArraySegment<byte>(sendBuffer), WebSocketMessageType.Text, true, CancellationToken.None);
674
tasks.Add(cyberCommServerEventArgs.ReplyMessage(message));
674
675
}
675
676
}
677
await Task.WhenAll(tasks);
676
678
}
677
679
/// <summary>
678
680
/// 发送群组二进制消息
@@ -680,25 +682,29 @@ namespace XFE各类拓展.CyberComm
680
682
/// <param name="bytes">群发二进制消息</param>
681
683
public async Task SendGroupBinaryMessage(byte[] bytes)
682
684
{
683
foreach (WebSocket webSocket in webSockets)
685
List<Task> tasks = new List<Task>();
686
foreach (CyberCommServerEventArgs cyberCommServerEventArgs in cyberCommList)
684
687
{
685
await webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Binary, true, CancellationToken.None);
688
tasks.Add(cyberCommServerEventArgs.ReplyBinaryMessage(bytes));
686
689
}
690
await Task.WhenAll(tasks);
687
691
}
688
692
/// <summary>
689
/// 向除了指定的WS客户端外的客户端发送群组二进制消息
693
/// 向指定的WS客户端发送群组二进制消息
690
694
/// </summary>
691
695
/// <param name="bytes">群发二进制消息</param>
692
/// <param name="exceptWebSocket">除了指定的WS客户端外的客户端</param>
693
public async Task SendGroupBinaryMessageExcept(byte[] bytes, WebSocket exceptWebSocket)
696
/// <param name="findFunc">指定的WS客户端</param>
697
public async Task SendGroupBinaryMessage(byte[] bytes, Func<CyberCommServerEventArgs, bool> findFunc)
694
698
{
695
foreach (WebSocket webSocket in webSockets)
699
List<Task> tasks = new List<Task>();
700
foreach (CyberCommServerEventArgs cyberCommServerEventArgs in cyberCommList)
696
701
{
697
if (webSocket != exceptWebSocket)
702
if (findFunc.Invoke(cyberCommServerEventArgs))
698
703
{
699
await webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Binary, true, CancellationToken.None);
704
tasks.Add(cyberCommServerEventArgs.ReplyBinaryMessage(bytes));
700
705
}
701
706
}
707
await Task.WhenAll(tasks);
702
708
}
703
709
/// <summary>
704
710
/// 客户端群组
@@ -712,11 +718,35 @@ namespace XFE各类拓展.CyberComm
712
718
/// 客户端群组
713
719
/// </summary>
714
720
/// <param name="GroupId">群组ID</param>
715
/// <param name="webSockets">客户端群组</param>
716
public CyberCommGroup(string GroupId, List<WebSocket> webSockets)
721
/// <param name="cyberCommList">客户端群组</param>
722
public CyberCommGroup(string GroupId, List<CyberCommServerEventArgs> cyberCommList)
717
723
{
718
724
this.GroupId = GroupId;
719
this.webSockets = webSockets;
725
this.cyberCommList = cyberCommList;
726
}
727
}
728
/// <summary>
729
/// 代签名的WebSocket
730
/// </summary>
731
public class SignedWebSocket
732
{
733
/// <summary>
734
/// 签名
735
/// </summary>
736
public string Signature { get; set; }
737
/// <summary>
738
/// 服务器
739
/// </summary>
740
public WebSocket WebSocket { get; set; }
741
/// <summary>
742
/// 签名WebSocket
743
/// </summary>
744
/// <param name="signature">签名</param>
745
/// <param name="webSocket">WebSocket</param>
746
public SignedWebSocket(string signature, WebSocket webSocket)
747
{
748
Signature = signature;
749
WebSocket = webSocket;
720
750
}
721
751
}
722
752
/// <summary>
@@ -139,7 +139,7 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
139
139
/// <returns></returns>
140
140
public XCCGroup CreateGroup(string groupId, string sender)
141
141
{
142
var group = new XCCGroupImpl(groupId, sender, xCCNetWorkBase);
142
var group = new XCCGroupImpl(Guid.NewGuid().ToString(), groupId, sender, xCCNetWorkBase);
143
143
Groups.Add(group);
144
144
return group;
145
145
}
@@ -162,6 +162,10 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
162
162
private int reconnectTimes = -1;
163
163
#region 公有属性
164
164
/// <summary>
165
/// 客户端标识名
166
/// </summary>
167
public string Signature { get; }
168
/// <summary>
165
169
/// 群组ID
166
170
/// </summary>
167
171
public string GroupId { get; }
@@ -170,6 +174,14 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
170
174
/// </summary>
171
175
public string Sender { get; }
172
176
/// <summary>
177
/// 明文传输服务器是否连接
178
/// </summary>
179
public bool TextMessageClientConnected { get; private set; } = false;
180
/// <summary>
181
/// 文件传输服务器是否连接
182
/// </summary>
183
public bool FileTransportClientConnected { get; private set; } = false;
184
/// <summary>
173
185
/// WebSocket明文传输客户端
174
186
/// </summary>
175
187
public ClientWebSocket TextMessageClientWebSocket { get; private set; }
@@ -177,10 +189,6 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
177
189
/// WebSocket文件传输客户端
178
190
/// </summary>
179
191
public ClientWebSocket FileTransportClientWebSocket { get; private set; }
180
/// <summary>
181
/// 是否已连接
182
/// </summary>
183
public bool IsConnected { get; private set; } = false;
184
192
#endregion
185
193
#region 公有方法
186
194
/// <summary>
@@ -213,6 +221,7 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
213
221
TextMessageClientWebSocket.Options.SetRequestHeader("Group", base64GroupId);
214
222
TextMessageClientWebSocket.Options.SetRequestHeader("Sender", base64SenderId);
215
223
TextMessageClientWebSocket.Options.SetRequestHeader("Type", "Text");
224
TextMessageClientWebSocket.Options.SetRequestHeader("Signature", Signature);
216
225
reconnectTimes++;
217
226
try
218
227
{
@@ -221,11 +230,11 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
221
230
}
222
231
catch (Exception ex)
223
232
{
224
if (IsConnected == true)
233
if (TextMessageClientConnected == true)
225
234
{
226
235
workBase.connectionClosed?.Invoke(this, new XCCConnectionClosedEventArgsImpl(this, XCCClientType.TextMessageClient, TextMessageClientWebSocket, FileTransportClientWebSocket, false));
227
236
}
228
IsConnected = false;
237
TextMessageClientConnected = false;
229
238
if (autoReconnect)
230
239
{
231
240
if (reconnectTimes <= reconnectMaxTimes || reconnectMaxTimes == -1)
@@ -241,8 +250,8 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
241
250
}
242
251
}
243
252
reconnectTimes = 0;
253
TextMessageClientConnected = true;
244
254
workBase.connected?.Invoke(this, new XCCConnectedEventArgsImpl(this, XCCClientType.TextMessageClient, TextMessageClientWebSocket, FileTransportClientWebSocket));
245
IsConnected = true;
246
255
while (TextMessageClientWebSocket.State == WebSocketState.Open)
247
256
{
248
257
try
@@ -318,11 +327,11 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
318
327
catch (Exception ex)
319
328
{
320
329
try { await TextMessageClientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close", CancellationToken.None); } catch { }
321
if (IsConnected == true)
330
if (TextMessageClientConnected == true)
322
331
{
323
332
workBase.connectionClosed?.Invoke(this, new XCCConnectionClosedEventArgsImpl(this, XCCClientType.TextMessageClient, TextMessageClientWebSocket, FileTransportClientWebSocket, false));
324
333
}
325
IsConnected = false;
334
TextMessageClientConnected = false;
326
335
if (autoReconnect)
327
336
{
328
337
if (autoReconnect)
@@ -358,6 +367,7 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
358
367
FileTransportClientWebSocket.Options.SetRequestHeader("Group", base64GroupId);
359
368
FileTransportClientWebSocket.Options.SetRequestHeader("Sender", base64SenderId);
360
369
FileTransportClientWebSocket.Options.SetRequestHeader("Type", "File");
370
FileTransportClientWebSocket.Options.SetRequestHeader("Signature", Signature);
361
371
reconnectTimes++;
362
372
try
363
373
{
@@ -366,11 +376,11 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
366
376
}
367
377
catch (Exception ex)
368
378
{
369
if (IsConnected == true)
379
if (FileTransportClientConnected == true)
370
380
{
371
381
workBase.connectionClosed?.Invoke(this, new XCCConnectionClosedEventArgsImpl(this, XCCClientType.FileTransportClient, TextMessageClientWebSocket, FileTransportClientWebSocket, false));
372
382
}
373
IsConnected = false;
383
FileTransportClientConnected = false;
374
384
if (autoReconnect)
375
385
{
376
386
if (reconnectTimes <= reconnectMaxTimes || reconnectMaxTimes == -1)
@@ -386,20 +396,20 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
386
396
}
387
397
}
388
398
reconnectTimes = 0;
399
FileTransportClientConnected = true;
389
400
workBase.connected?.Invoke(this, new XCCConnectedEventArgsImpl(this, XCCClientType.FileTransportClient, TextMessageClientWebSocket, FileTransportClientWebSocket));
390
IsConnected = true;
391
401
while (FileTransportClientWebSocket.State == WebSocketState.Open)
392
402
{
393
403
try
394
404
{
395
405
byte[] receiveBuffer = new byte[1024];
396
WebSocketReceiveResult receiveResult = await TextMessageClientWebSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
406
WebSocketReceiveResult receiveResult = await FileTransportClientWebSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
397
407
var bufferList = new List<byte>();
398
408
bufferList.AddRange(receiveBuffer.Take(receiveResult.Count));
399
409
//ReceiveCompletedMessageByUsingWhile
400
410
while (!receiveResult.EndOfMessage)
401
411
{
402
receiveResult = await TextMessageClientWebSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
412
receiveResult = await FileTransportClientWebSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
403
413
bufferList.AddRange(receiveBuffer.Take(receiveResult.Count));
404
414
}
405
415
var receivedBinaryBuffer = bufferList.ToArray();
@@ -447,12 +457,12 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
447
457
}
448
458
catch (Exception ex)
449
459
{
450
try { await TextMessageClientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close", CancellationToken.None); } catch { }
451
if (IsConnected == true)
460
try { await FileTransportClientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close", CancellationToken.None); } catch { }
461
if (FileTransportClientConnected == true)
452
462
{
453
463
workBase.connectionClosed?.Invoke(this, new XCCConnectionClosedEventArgsImpl(this, XCCClientType.FileTransportClient, TextMessageClientWebSocket, FileTransportClientWebSocket, false));
454
464
}
455
IsConnected = false;
465
FileTransportClientConnected = false;
456
466
if (autoReconnect)
457
467
{
458
468
if (autoReconnect)
@@ -472,7 +482,15 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
472
482
workBase.connectionClosed?.Invoke(this, new XCCConnectionClosedEventArgsImpl(this, XCCClientType.FileTransportClient, TextMessageClientWebSocket, FileTransportClientWebSocket, true));
473
483
}
474
484
/// <summary>
475
/// 发送文本消息,返回消息ID
485
/// 等待明文服务器和文件服务器均连接
486
/// </summary>
487
/// <returns></returns>
488
public async Task WaitConnect()
489
{
490
await Task.Run(() => { while (!TextMessageClientConnected || !FileTransportClientConnected) { } });
491
}
492
/// <summary>
493
/// 发送文本消息
476
494
/// </summary>
477
495
/// <param name="message">待发送的文本</param>
478
496
/// <param name="timeout">最长超时时长</param>
@@ -528,7 +546,7 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
528
546
}
529
547
}
530
548
/// <summary>
531
/// 发送签名二进制消息,返回消息ID
549
/// 发送签名二进制消息
532
550
/// </summary>
533
551
/// <param name="message">二进制消息</param>
534
552
/// <param name="signature">签名标识</param>
@@ -553,7 +571,7 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
553
571
try
554
572
{
555
573
var xFEBuffer = new XFEBuffer(Sender, message, "Type", Encoding.UTF8.GetBytes(signature), "ID", Encoding.UTF8.GetBytes(messageId));
556
await TextMessageClientWebSocket.SendAsync(new ArraySegment<byte>(xFEBuffer.ToBuffer()), WebSocketMessageType.Binary, true, CancellationToken.None);
574
await FileTransportClientWebSocket.SendAsync(new ArraySegment<byte>(xFEBuffer.ToBuffer()), WebSocketMessageType.Binary, true, CancellationToken.None);
557
575
var endTask = Task.Run(async () =>
558
576
{
559
577
await Task.Delay(timeout);
@@ -703,8 +721,9 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
703
721
}
704
722
}
705
723
#endregion
706
internal XCCGroup(string groupId, string sender, XCCNetWorkBase xCCNetWorkBase)
724
internal XCCGroup(string signature, string groupId, string sender, XCCNetWorkBase xCCNetWorkBase)
707
725
{
726
Signature = signature;
708
727
GroupId = groupId;
709
728
Sender = sender;
710
729
workBase = xCCNetWorkBase;
@@ -989,6 +1008,28 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
989
1008
SaveFile(xCCFile);
990
1009
}
991
1010
}
1011
else
1012
{
1013
var fileType = XCCFileType.Image;
1014
switch (e.MessageType)
1015
{
1016
case XCCBinaryMessageType.Image:
1017
fileType = XCCFileType.Image;
1018
break;
1019
case XCCBinaryMessageType.Audio:
1020
fileType = XCCFileType.Audio;
1021
break;
1022
case XCCBinaryMessageType.AudioBuffer:
1023
break;
1024
case XCCBinaryMessageType.Video:
1025
fileType = XCCFileType.Video;
1026
break;
1027
default:
1028
break;
1029
}
1030
xCCFileDictionary.Add(e.MessageId, new XCCFile(e.GroupId, e.MessageId, fileType, e.Sender, null, e.BinaryMessage));
1031
FileReceived?.Invoke(e.)
1032
}
992
1033
}
993
1034
/// <summary>
994
1035
/// XCC消息接收器
@@ -1038,7 +1079,7 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
1038
1079
/// <summary>
1039
1080
/// 发送时间
1040
1081
/// </summary>
1041
public DateTime SendTime { get; }
1082
public DateTime? SendTime { get; }
1042
1083
/// <summary>
1043
1084
/// XCC文件类型
1044
1085
/// </summary>
@@ -1070,7 +1111,7 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
1070
1111
/// <param name="sender">发送者</param>
1071
1112
/// <param name="sendTime">发送时间</param>
1072
1113
/// <param name="fileBuffer">文件的Buffer</param>
1073
public XCCFile(string groupId, string messageId, XCCFileType fileType, string sender, DateTime sendTime, byte[] fileBuffer = null)
1114
public XCCFile(string groupId, string messageId, XCCFileType fileType, string sender, DateTime? sendTime, byte[] fileBuffer = null)
1074
1115
{
1075
1116
GroupId = groupId;
1076
1117
MessageId = messageId;
@@ -1435,7 +1476,7 @@ namespace XFE各类拓展.CyberComm.XCCNetWork
1435
1476
}
1436
1477
class XCCGroupImpl : XCCGroup
1437
1478
{
1438
internal XCCGroupImpl(string groupId, string sender, XCCNetWorkBase xCCNetWorkBase) : base(groupId, sender, xCCNetWorkBase) { }
1479
internal XCCGroupImpl(string signature, string groupId, string sender, XCCNetWorkBase xCCNetWorkBase) : base(signature, groupId, sender, xCCNetWorkBase) { }
1439
1480
}
1440
1481
class XCCConnectionClosedEventArgsImpl : XCCConnectionClosedEventArgs
1441
1482
{