c# - ClientWebSocket 示例挂起
问题描述
下页显示的示例不起作用: Using c# ClientWebSocket with streams
它挂在以下行:
等待 ws.ConnectAsync(serverUri, CancellationToken.None);
似乎没有建立连接。
请指出使以下代码工作的最简单修改。我不想使用任何 3rd 方工具或库。
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));
}
}
}
解决方案
你是对的。您无需添加任何标题即可使用wss://echo.websocket.org/
. 你的代码在我结束时运行得很好。但我会建议timeout
您的ConnectAsync
,SendAsync
和ReceiveAsync
调用包括一项改进,以免它长时间卡住。
我将代码限制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
推荐阅读
- openstreetmap - 如何确保 geopy 中区域的身份?
- laravel-8 - Kreait Firebase 异常 Invalid Argument Exception 具有权限的 URI 的路径必须以斜杠“/”开头或在 laravel8 中为空
- javascript - WebGL - Three.JS 和 Blazor 的黑色画布和控制台错误
- stored-procedures - 雪花存储在使用抛出错误而不是返回错误时给出不同的错误
- html - 遵循 html/css 教程后无法显示背景图像
- java - LDAP 身份验证异常错误代码 49
- javascript - 如何找到块数组中所有子数组的长度
- python - 如何将 keras 网络更改为 channels_last 而不是 channels_first?
- javascript - 垂直滚动实际上是使用鼠标滚轮库的水平滚动
- r - xlsx R:循环遍历文件列表以检查所有工作表名称;如果不存在则创建一个空白表