InternalClientWebSocket 实例无法用于通信,因为它已转换为“已中止”状态

2024-04-02

当我尝试从三个以上的 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; }
    }

这是来自MSDN的,这里是link https://msdn.microsoft.com/en-us/library/system.net.websockets.clientwebsocket.sendasync(v=vs.110).aspx.

该操作不会阻塞。返回的任务对象将完成 ClientWebSocket 实例上的发送请求完成后。

每个 ClientWebSocket 均支持一次发送和一次接收 平行的物体。

一一调用您的 Connect 方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

InternalClientWebSocket 实例无法用于通信,因为它已转换为“已中止”状态 的相关文章

随机推荐