Search code examples
c#websocket.net-corepredix

.Net Core ClientWebSocket: Unable to connect to server


I'm building a web application that connects to a Predix Timeseries instance to ingest data through a websocket. When I attempt to create the socket, I get this exception:

System.Net.WebSockets.WebSocketException: 'Unable to connect to the remote server'

I'm using this code to create my websocket, with my error being thrown on the ConnectAsync call:

public async Task openWebSocket()
    {
        _socket = new ClientWebSocket();

        _socket.Options.SetRequestHeader(headerName: "predix-zone-id", headerValue: PREDIX_ZONE_ID_HERE);
        _socket.Options.SetRequestHeader(headerName: "authorization", headerValue: "Bearer " + AUTH_TOKEN_HERE);
        _socket.Options.SetRequestHeader(headerName: "content-type", headerValue: "application/json");
        CancellationToken token = new CancellationToken();

        var uri = new Uri(uriString: "wss://gateway-predix-data-services.run.aws-usw02-pr.ice.predix.io/v1/stream/messages");
        await _socket.ConnectAsync(uri: uri, cancellationToken: token);

    }

and here is my exception's stack trace:

System.Net.WebSockets.WebSocketException occurred
  HResult=0x80004005
  Message=Unable to connect to the remote server
  Source=<Cannot evaluate the exception source>
  StackTrace:
   at System.Net.WebSockets.WebSocketHandle.<ConnectAsyncCore>d__20.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.ClientWebSocket.<ConnectAsyncCore>d__16.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at PROJECTNAME.Services.TimeseriesService.<openWebSocket>d__6.MoveNext() in %PROJECTLOCATION%\Services\%SERVICENAME%.cs:line 34
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at PROJECTNAME.Services.TimeseriesService.<Initialize>d__5.MoveNext() in %PROJECTLOCATION%\Services\%SERVICENAME%.cs:line 21
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at PROJECTNAME.Program.<Initialize>d__1.MoveNext() in %PROJECTLOCATION%\Program.cs:line 52

Inner Exception 1:
WebSocketException: Unable to connect to the remote server

The inner exception stack track has little more information, but noting the ThrowOnInvalidConnectState() that might be useful:

    at System.Net.WebSockets.WinHttpWebSocket.ThrowOnInvalidConnectState()
   at System.Net.WebSockets.WinHttpWebSocket.<ConnectAsync>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.WebSocketHandle.<ConnectAsyncCore>d__20.MoveNext()

I'm not sure what else to try - lots of other posts on SO at least have some useful information in the inner exception.

I've also attempted to use Fiddler. I can see message for other services, including my auth token retrieval from UAA, but nothing from this service.

Am I missing some configuration steps somewhere? Any help or guidance would be appreciated.


Solution

  • I figured out the issue. The three required headers for the Predix Timeseries are:

    • Predix-Zone-Id: zone_id_here
    • Authorization: Bearer auth_token_here
    • Origin: "https:// hostname_here

    My problem is that I tried the Origin header, but the Predix VCAP_APPLCIATION environmental variable for the application_uris doesn't include the "https://". Once I added it manually ("https://" + uri) it worked fine.