Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.WebSockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using XWorld.Framework.Protocol;
|
||||
|
||||
namespace XWorld.Server.Gateway.Tests
|
||||
{
|
||||
// 集成测试用 WS 客户端:连接、发帧、带超时收一帧并解码
|
||||
internal sealed class WsTestClient : IDisposable
|
||||
{
|
||||
private readonly ClientWebSocket _ws = new ClientWebSocket();
|
||||
|
||||
public async Task ConnectAsync(string wsBaseUrl, int pid)
|
||||
{
|
||||
await _ws.ConnectAsync(new Uri($"{wsBaseUrl}/ws?pid={pid}"), CancellationToken.None);
|
||||
}
|
||||
|
||||
public async Task SendFrameAsync(Frame frame)
|
||||
{
|
||||
byte[] bytes = FrameCodec.Encode(frame);
|
||||
await _ws.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Binary, true, CancellationToken.None);
|
||||
}
|
||||
|
||||
// 在 timeout 内收一条 WS 消息并解码为 Frame;超时抛 TimeoutException
|
||||
public async Task<Frame> ReceiveFrameAsync(int timeoutMs = 5000)
|
||||
{
|
||||
using var cts = new CancellationTokenSource(timeoutMs);
|
||||
var buf = new byte[8192];
|
||||
using var ms = new MemoryStream();
|
||||
WebSocketReceiveResult res;
|
||||
do
|
||||
{
|
||||
res = await _ws.ReceiveAsync(new ArraySegment<byte>(buf), cts.Token);
|
||||
if (res.MessageType == WebSocketMessageType.Close)
|
||||
throw new InvalidOperationException("server closed");
|
||||
ms.Write(buf, 0, res.Count);
|
||||
} while (!res.EndOfMessage);
|
||||
return FrameCodec.Decode(ms.ToArray());
|
||||
}
|
||||
|
||||
public async Task CloseAsync()
|
||||
{
|
||||
try { await _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", CancellationToken.None); }
|
||||
catch { /* 忽略 */ }
|
||||
}
|
||||
|
||||
public void Dispose() => _ws.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user