2

I am trying to connect to a WebSocket API from a C# console app.

My code crashes on ConnectAsync method and it wont fall in catch block or give any error.

Here is my code

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

Application crashed at await clientWebSocket.ConnectAsync(serverUri, cancellationTokenSource.Token); doesn't even fall in catch block

I changed connectAsync line to as below

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

Now it falling catch block with following exception

The request was aborted: Could not create SSL/TLS secure channel.

Stack Trace

   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()

Then I added the following line before the method start

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

New Exception

Unable to connect to the remote server The remote server returned an error: (400) Bad Request.

Stack Trace:

   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()
HaBo
  • 13,999
  • 36
  • 114
  • 206

1 Answers1

1

This is how I got this worked.

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;
        }
HaBo
  • 13,999
  • 36
  • 114
  • 206
  • what is "_securityService.SetClientToken().Wait();", more specifically, "_secrityService" variable? – gcadmes Aug 24 '18 at 20:05
  • I've run into a similar issue where my ClientWebSocket starts connecting then after half a second just closes without any message or error or anything. do you have any insight? – Reahreic Feb 25 '21 at 18:46