ClientWebSocket.ConnectAsync 崩溃,没有任何错误信息

Posted

技术标签:

【中文标题】ClientWebSocket.ConnectAsync 崩溃,没有任何错误信息【英文标题】:ClientWebSocket.ConnectAsync crashes with out any error info 【发布时间】:2017-04-24 10:46:50 【问题描述】:

我正在尝试从 C# 控制台应用程序连接到 WebSocket API。

我的代码在 ConnectAsync 方法上崩溃,它不会落入 catch block 或给出任何错误。

这是我的代码

public async System.Threading.Tasks.Task<Details> Get(string locationUid, string eventType)

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls |
                                           SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
    var cancellationTokenSource = new CancellationTokenSource();
    using (ClientWebSocket clientWebSocket = new ClientWebSocket())
    
        Uri serverUri = new Uri(Endpoint.WebSocketUrl);
        try
        
            await clientWebSocket.ConnectAsync(serverUri, cancellationTokenSource.Token);
        
        catch (Exception e)
        
            Console.WriteLine(e);
            throw;
        

        while (clientWebSocket.State == WebSocketState.Open)
        
            string bodyMessage = $"\"locationUid\":\"locationUid\",\"eventTypes\":[\"eventType\"]";
            ArraySegment<byte> bytesToSend = new ArraySegment<byte>(Encoding.UTF8.GetBytes(bodyMessage));
            await clientWebSocket.SendAsync(bytesToSend, WebSocketMessageType.Text, true, CancellationToken.None);
            ArraySegment<byte> bytesReceived = new ArraySegment<byte>(new byte[1024]);
            WebSocketReceiveResult result = await clientWebSocket.ReceiveAsync(bytesReceived, CancellationToken.None);
            var response = Encoding.UTF8.GetString(bytesReceived.Array, 0, result.Count);
        
    
    return null;

应用程序在 await clientWebSocket.ConnectAsync(serverUri, cancellationTokenSource.Token); 崩溃,甚至没有落入 catch 块

我将 connectAsync 行更改为如下

clientWebSocket.ConnectAsync(serverUri, cancellationTokenSource.Token).Wait(cancellationTokenSource.Token);

现在它会落下 catch 块,但有以下异常

请求被中止:无法创建 SSL/TLS 安全通道。

堆栈跟踪

   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.ClientWebSocket.<ConnectAsyncCore>d__21.MoveNext()

然后我在方法开始之前添加了以下行

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls |
                                                   SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

新异常

无法连接到远程服务器 远程服务器返回错误:(400) Bad Request。

堆栈跟踪:

   at System.Net.WebSockets.ClientWebSocket.<ConnectAsyncCore>d__21.MoveNext()

   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.ClientWebSocket.<ConnectAsyncCore>d__21.MoveNext()

【问题讨论】:

你解决过这个问题吗? 是的。现在发布我的答案。 【参考方案1】:

这就是我的工作方式。

public async Task<string> GetAllAsync(string url, string bodyMessage,
            Dictionary<string, string> additionalHeaders)
        
            _securityService.SetClientToken().Wait();
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls |
                                                   SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

            var cancellationTokenSource = new CancellationTokenSource(new TimeSpan(1, 1, 0, 0));
            using (ClientWebSocket clientWebSocket = new ClientWebSocket())
            
                Uri serverUri = new Uri(url);
                clientWebSocket.Options.SetRequestHeader("Authorization", $"Bearer Endpoint.ClientAccessToken");
                foreach (var additionalHeader in additionalHeaders)
                
                    clientWebSocket.Options.SetRequestHeader(additionalHeader.Key, additionalHeader.Value);
                
                try
                
                    clientWebSocket.ConnectAsync(serverUri, cancellationTokenSource.Token)
                        .Wait(cancellationTokenSource.Token);
                
                catch (Exception exception)
                
                    Console.WriteLine(exception);
                    throw;
                
                while (clientWebSocket.State == WebSocketState.Open)
                
                    ArraySegment<byte> bytesToSend = new ArraySegment<byte>(Encoding.UTF8.GetBytes(bodyMessage));
                    await clientWebSocket.SendAsync(bytesToSend, WebSocketMessageType.Text, true,
                        CancellationToken.None);
                    ArraySegment<byte> bytesReceived = new ArraySegment<byte>(new byte[1024]);
                    WebSocketReceiveResult result =
                        await clientWebSocket.ReceiveAsync(bytesReceived, CancellationToken.None);
                    var response = Encoding.UTF8.GetString(bytesReceived.Array, 0, result.Count);
                    return response;
                
            
            return null;
        

【讨论】:

什么是“_securityService.SetClientToken().Wait();”,更具体地说,是“_secrityService”变量? 我遇到了类似的问题,我的 ClientWebSocket 开始连接,然后半秒后关闭,没有任何消息或错误或任何东西。你有什么见解吗?

以上是关于ClientWebSocket.ConnectAsync 崩溃,没有任何错误信息的主要内容,如果未能解决你的问题,请参考以下文章