当我尝试从三个以上的 websocket 接收数据时出现异常。如果我只尝试一个、两个或三个网络套接字,它就可以完美工作。
我在这一行中得到了异常:
tasks.Add(Send(webSocket, "11"));
异常消息:
异常:System.Net.WebSockets.WebSocketException(0x80004005):
“System.Net.WebSockets.InternalClientWebSocket”实例不能
用于通信,因为它已转变为
“中止”状态。 ---> System.OperationCanceledException: 操作
取消了。在
System.Threading.CancellationToken.ThrowOperationCanceledException()
在
System.Net.WebSockets.WebSocketConnectionStream.d__21.MoveNext()
--- 从先前抛出异常的位置开始的堆栈跟踪结束 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务
任务)在
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
任务)在
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(任务任务)
在
System.Net.WebSockets.WebSocketBase.WebSocketOperation.d__19.MoveNext()
--- 从先前抛出异常的位置开始的堆栈跟踪结束 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务
任务)在
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
任务)在
System.Net.WebSockets.WebSocketBase.d__45.MoveNext()
在 System.Net.WebSockets.WebSocketBase.ThrowIfAborted(布尔值中止,
异常内部异常)在
System.Net.WebSockets.WebSocketBase.ThrowIfConvertibleException(字符串
methodName、Exception异常、CancellationToken取消令牌、
布尔运算中止)于
System.Net.WebSockets.WebSocketBase.d__45.MoveNext()
--- 从先前抛出异常的位置开始的堆栈跟踪结束 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务
任务)在
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
任务)在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
--- 从先前抛出异常的位置开始的堆栈跟踪结束 --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务
任务)在
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
任务)在 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
这是我的代码:
using System;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RTLS_GetData_From_WebSockets.App_Code;
namespace RTLS_GetData_From_WebSockets
{
class Program
{
private static object consoleLock = new object();
private const int sendChunkSize = 256;
private const int receiveChunkSize = 256;
private const bool verbose = true;
private static readonly TimeSpan delay = TimeSpan.FromMilliseconds(30000);
private static WebSocket client;
const string host = "ws://localhost:8080";
static void Main(string[] args)
{
Connect(host).Wait();
}
public static async Task Connect(string uri)
{
ClientWebSocket webSocket = null;
try
{
webSocket = new ClientWebSocket();
await webSocket.ConnectAsync(new Uri(uri), CancellationToken.None);
List<Task> tasks = new List<Task>();
tasks.Add(Receive(webSocket));
tasks.Add(Send(webSocket, "9"));
tasks.Add(Send(webSocket, "10"));
tasks.Add(Send(webSocket, "11"));
await Task.WhenAll(tasks);
}
catch (Exception ex)
{
Console.WriteLine("Exception: {0}", ex);
}
finally
{
if (webSocket != null)
webSocket.Dispose();
Console.WriteLine();
lock (consoleLock)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("WebSocket closed.");
Console.ResetColor();
}
}
}
static UTF8Encoding encoder = new UTF8Encoding();
private static async Task Send(ClientWebSocket webSocket, string ZoneID)
{
byte[] buffer = encoder.GetBytes("{\"method\":\"subscribe\", \"resource\":\"/zones/" + ZoneID + "\"}");
await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
while (webSocket.State == WebSocketState.Open)
{
LogStatus(false, buffer, buffer.Length);
await Task.Delay(delay);
}
}
private static async Task Receive(ClientWebSocket webSocket)
{
byte[] buffer = new byte[receiveChunkSize];
while (webSocket.State == WebSocketState.Open)
{
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close)
{
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
}
else
{
LogStatus(true, buffer, result.Count);
}
}
}
private static void LogStatus(bool receiving, byte[] buffer, int length)
{
lock (consoleLock)
{
Console.ForegroundColor = receiving ? ConsoleColor.Green : ConsoleColor.Gray;
if (verbose)
{
string tmp = encoder.GetString(buffer);
var data = JsonConvert.DeserializeObject<Zones>(tmp);
Console.WriteLine(data.body.status);
Console.WriteLine();
}
Console.ResetColor();
}
}
}
}
[DataContract]
public class Zones
{
[DataMember(Name = "body")]
public ZoneBody body { get; set; }
}
public class ZoneBody
{
[DataMember(Name = "feed_id")]
public string feed_id { get; set; }
[DataMember(Name = "zone_id")]
public string zone_id { get; set; }
[DataMember(Name = "status")]
public string status { get; set; }
[DataMember(Name = "at")]
public string at { get; set; }
}