ClientWebSocket 示例挂起
Posted
技术标签:
【中文标题】ClientWebSocket 示例挂起【英文标题】:ClientWebSocket example hangs 【发布时间】:2020-02-11 16:23:27 【问题描述】:下页显示的示例不起作用: Using c# ClientWebSocket with streams
它挂在下面一行:
等待 ws.ConnectAsync(serverUri, CancellationToken.None);
似乎没有建立连接。
请指出使以下代码工作的最简单修改。我不想使用任何第三方工具或库。
private static async Task DoClientWebSocket()
using (ClientWebSocket ws = new ClientWebSocket())
Uri serverUri = new Uri("wss://echo.websocket.org/");
await ws.ConnectAsync(serverUri, CancellationToken.None);
while (ws.State == WebSocketState.Open)
string msg = "hello123";
ArraySegment<byte> bytesToSend = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg));
await ws.SendAsync(bytesToSend, WebSocketMessageType.Text, true, CancellationToken.None);
ArraySegment<byte> bytesReceived = new ArraySegment<byte>(new byte[1024]);
WebSocketReceiveResult result = await ws.ReceiveAsync(bytesReceived, CancellationToken.None);
Console.WriteLine(Encoding.UTF8.GetString(bytesReceived.Array, 0, result.Count));
【问题讨论】:
如果我转到websocket.org/echo.html,并查看示例,URI 是ws://echo.websocket.org
,而不是wss://echo.websocket.org/
。糟糕,我看到了两个 URI。
我尝试了 ws: 和 wss:。两者都在 javascript 中工作,在 c# 中都没有。
你让事情变得非常困难。 c# 中的默认请求标头与其他应用程序不同。通常要使代码正常工作,您必须添加缺少的标头或修改默认标头。解决问题的最佳方法是比较 java 或使用嗅探器与非工作应用程序一起工作的。将第一个请求与 java 和 c# 进行比较。
没有在 javascript 中添加标头:websocket = new WebSocket(wsUri);我必须在 C# 中添加哪些标头?
【参考方案1】:
你是对的。您无需添加任何标题即可使用wss://echo.websocket.org/
。你的代码在我结束时运行得很好。但我会建议一项改进,为您的ConnectAsync
、SendAsync
和ReceiveAsync
调用包括timeout
,这样它就不会长时间卡住。
我已将代码限制为仅调用 SendAsync
5 次,以便更容易验证输出。
[已编辑:] 包含通过多次调用 `ReceiveAsync 来接收完整响应的逻辑。
private static async Task DoClientWebSocket()
using (ClientWebSocket ws = new ClientWebSocket())
Uri serverUri = new Uri("wss://echo.websocket.org/");
//Implementation of timeout of 5000 ms
var source = new CancellationTokenSource();
source.CancelAfter(5000);
await ws.ConnectAsync(serverUri, source.Token);
var iterationNo = 0;
// restricted to 5 iteration only
while (ws.State == WebSocketState.Open && iterationNo++ < 5)
string msg = "hello0123456789123456789123456789123456789123456789123456789";
ArraySegment<byte> bytesToSend =
new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg));
await ws.SendAsync(bytesToSend, WebSocketMessageType.Text,
true, source.Token);
//Receive buffer
var receiveBuffer = new byte[200];
//Multipacket response
var offset = 0;
var dataPerPacket = 10; //Just for example
while (true)
ArraySegment<byte> bytesReceived =
new ArraySegment<byte>(receiveBuffer, offset, dataPerPacket);
WebSocketReceiveResult result = await ws.ReceiveAsync(bytesReceived,
source.Token);
//Partial data received
Console.WriteLine("Data:0",
Encoding.UTF8.GetString(receiveBuffer, offset,
result.Count));
offset += result.Count;
if (result.EndOfMessage)
break;
Console.WriteLine("Complete response: 0",
Encoding.UTF8.GetString(receiveBuffer, 0,
offset));
static void Main(string[] args)
var taskWebConnect = Task.Run(() => DoClientWebSocket());
taskWebConnect.Wait();
命令提示符的输出:
Data:hello01234
Data:5678912345
Data:6789123456
Data:7891234567
Data:8912345678
Data:9123456789
Complete response: hello0123456789123456789123456789123456789123456789123456789
【讨论】:
@Tester 很高兴知道。乐意效劳。您可以通过点击答案窗口左侧的Tick
符号来接受答案。
现在我需要从不同的 WebSocket 检索 100k。当我将 'ArraySegmentReceiveAsync
收到的响应的EndOfMessage
属性多次读取,直到读取所有数据。我会更新代码来解决它。以上是关于ClientWebSocket 示例挂起的主要内容,如果未能解决你的问题,请参考以下文章
ClientWebSocket.ConnectAsync 崩溃,没有任何错误信息
强制 HttpWebRequest 和 ClientWebSocket 使用 TLS 1.2
使用 ClientWebSocket .net 核心测试 TestHost.WebSocketClient
Xamarin Mono ClientWebSocket 实现不适用于安全套接字