首页 文章

InternalClientWebSocket实例不能用于通信,因为它已转换为'Aborted'状态

提问于
浏览
2

当我尝试从三个以上的websockets接收数据时,我有一个例外 . 如果我只尝试一个,两个或三个腹围,它可以完美地工作 . 我在这一行得到了例外:

tasks.Add(Send(webSocket, "11"));

异常消息:

异常:System.Net.WebSockets.WebSocketException(0x80004005):'System.Net.WebSockets.InternalClientWebSocket'实例不能用于通信,因为它已转换为'Aborted'状态 . ---> System.OperationCanceledException:操作被取消 . 在System.Threading.Chreading.CancellationToken.ThrowOperationCanceledException()at System.Net.WebSockets.WebSocketConnectionStream.d__21.MoveNext()---从抛出异常的上一个位置的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter . System.Net.WebSockets.WebSocketBase.WebSocketOperation.d__19.MoveNext()上的System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的ThrowForNonSuccess(任务任务) - - 从抛出异常的先前位置开始的堆栈跟踪结束---在System.Net.WebSockets上System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)处System.Net.WebSockets.WebSocketBase.ThrowIfConvertibleE上的System.Net.WebSockets.WebSocketBase.ThrowIfAborted(Boolean aborted,Exception innerException)中的.WebSocketBase.d__45.MoveNext() System.Net.WebSockets.WebSocketBase.d__45.MoveNext()的xception(String methodName,异常异常,CancellationToken cancellationToken,布尔中止)---从抛出异常的上一个位置的堆栈跟踪结束---在System.Runtime . System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)---来自先前位置的堆栈跟踪结束,其中异常是抛出---位于System.Runtime.CompilerServices.TaskAwaiter.GetResult()的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)

这是我的代码:

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; }
    }

1 回答

  • 2

    这是来自MSDN,这里是link .

    此操作不会阻止 . 在ClientWebSocket实例上的发送请求完成后,返回的Task对象将完成 . 每个ClientWebSocket对象并行支持一个发送和一个接收 .

    逐个调用Connect方法 .

相关问题