bchavez / Coinbase.Pro

:chart_with_upwards_trend: A .NET/C# implementation of the Coinbase Pro API.
https://docs.pro.coinbase.com/
Other
66 stars 27 forks source link

support question : how do trap socket exceptions #18

Closed bwjunkie closed 4 years ago

bwjunkie commented 4 years ago

Just curious if there is a way to trap socket exceptions. My normal try catch in the ticker_Handlers doesn't seem to stop my program from crashing when I get the following while running in debug:

CoinbasePro.Exceptions.CoinbaseProWebSocketException: 'WebSocket Feed Error: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. Please check https://status.pro.coinbase.com/ for more details as there may be an outage

Version Information

Software Version(s)
NuGet Package v3.0.5
.NET Core? no
.NET Full Framework? yes
Windows OS? 10
Linux OS? no
Visual Studio? yes 2019 preview

What's the problem?

cant figureout how to handle socket exceptions which cause my application to crash completely

What possible solutions have you considered?

try catch in the ticker and match handlers

Do you have sample code to show what you're trying to do?

Private Sub Websocket_MatchReceived(sender As Object, e As WebSocket.Models.Response.WebfeedEventArgs(Of WebSocket.Models.Response.Match)) Try catch

(Please be complete. Include any class models necessary to run your code.)

What is the HTTP request JSON and response JSON?

(Use Fiddler to help capture this information)

bchavez commented 4 years ago

Hi Josh,

I added some error handling to the Examples project here: https://github.com/bchavez/Coinbase.Pro/tree/master/Source/Examples

https://github.com/bchavez/Coinbase.Pro/blob/5db11a21bbe00fabf3c1ab7c6f4b7f75a2f21608/Source/Examples/Program.cs#L90-L91

It seems to catch disconnects and connection closures: image

If you have any other issues, comments, questions or feedback, let me know. Feel free to continue the discussion after we close the issue.

Thanks, Brian

bwjunkie commented 4 years ago

Thanks Brian, yes I did send a donation and I’ll send more now that I know the project is still alive and well!

yes I did see that sample code you linked, previously I was really confused because I’m not using .SubscribeAsync nor am I using any SuperSocket, nor do I have any RawSocket code. I guess I can try to redo my code to use these object models?

My code looks like this: (sorry VB.NET)

        Dim channelsToSub As New List(Of WebSocket.Types.ChannelType)
        channelsToSub.Add(WebSocket.Types.ChannelType.Matches)
        channelsToSub.Add(WebSocket.Types.ChannelType.Ticker)
        Dim productsToTrade As New List(Of ProductType)
        productsToTrade.Add(productToTrade)
        Dim socket = coinClient.WebSocket

        socket.Start(productsToTrade, channelsToSub)
        AddHandler socket.OnErrorReceived, AddressOf Websocket_ErrReceived

Private Sub Websocket_ErrReceived(sender As Object, e As WebSocket.Models.Response.WebfeedEventArgs(Of WebSocket.Models.Response.[Error]))
    listResults.Add("Error in Websocket_ErrReceived " & Now.ToShortTimeString)
End Sub
Private Sub Websocket_TickerReceived(sender As Object, e As WebSocket.Models.Response.WebfeedEventArgs(Of WebSocket.Models.Response.Ticker))
    Try

From: Brian Chavez notifications@github.com Sent: Tuesday, August 18, 2020 6:06 PM To: bchavez/Coinbase.Pro Coinbase.Pro@noreply.github.com Cc: Josh Miller josh@coolbluewater.org; Author author@noreply.github.com Subject: Re: [bchavez/Coinbase.Pro] support question : how do trap socket exceptions (#18)

Hi Josh,

I added some error handling to the Examples project here: https://github.com/bchavez/Coinbase.Pro/tree/master/Source/Examples

https://github.com/bchavez/Coinbase.Pro/blob/5db11a21bbe00fabf3c1ab7c6f4b7f75a2f21608/Source/Examples/Program.cs#L90-L91

It seems to catch disconnects and connection closures: [image]https://user-images.githubusercontent.com/478118/90576929-5a8f0600-e174-11ea-88dd-231b651c9714.png

If you have any other issues, comments, questions or feedback, let me know. Feel free to continue the discussion after we close the issue.

Thanks, Brian

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/bchavez/Coinbase.Pro/issues/18#issuecomment-675778004, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AALKA7TPSKCUGLZASVHQTDDSBMJPVANCNFSM4QCABPAA.

bchavez commented 4 years ago

Hi Josh,

Are you sure you are using my library?

From the VB.NET code you posted, I think you are using someone else's Coinbase Pro library found here: https://github.com/dougdellolio/coinbasepro-csharp

My Coinbase Pro API does not have a coinClient.WebSocket web socket property; however, the other .NET Coinbase Pro library does as shown here: https://github.com/dougdellolio/coinbasepro-csharp/blob/c67c22ce18494017abf06b85476cba1753977ab0/CoinbasePro/CoinbaseProClient.cs#L102

My websocket implementation is completely separate from the REST API implementation. In other words:

Also, the types you posted don't seem to match up to my API models. I think you might be using the other Coinbase Pro library.

Thanks, Brian

bwjunkie commented 4 years ago

I think I might be using both at the same time, and have fully confused myself, hehe! Whew…

From: Brian Chavez notifications@github.com Sent: Tuesday, August 18, 2020 7:06 PM To: bchavez/Coinbase.Pro Coinbase.Pro@noreply.github.com Cc: Josh Miller josh@coolbluewater.org; Author author@noreply.github.com Subject: Re: [bchavez/Coinbase.Pro] support question : how do trap socket exceptions (#18)

Hi Josh,

Are you sure you are using my library?

From the VB.NET code you posted, I think you are using someone else's Coinbase Pro library found here: https://github.com/dougdellolio/coinbasepro-csharp

My Coinbase Pro API does not have a coinClient.WebSocket web socket property; however, the other .NET Coinbase Pro library does as shown here: https://github.com/dougdellolio/coinbasepro-csharp/blob/c67c22ce18494017abf06b85476cba1753977ab0/CoinbasePro/CoinbaseProClient.cs#L102

My websocket implementation is completely separate from the REST API implementation. In other words:

Also, the types you posted don't seem to match up to my API models. I think you might be using the other Coinbase Pro library.

Thanks, Brian

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/bchavez/Coinbase.Pro/issues/18#issuecomment-675793297, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AALKA7RZOE6PK7ESKILSPADSBMQOVANCNFSM4QCABPAA.

bwjunkie commented 4 years ago

Hi Brian, thanks for all the replys.

I did get my ticker sockets converted over to your Coinbase.Pro API. And it’s working better than before since the socket_error doesn’t crash. I do have to re-start the socket after a socket_error handler, which is just fine.

Side note: I did notice Models.TickerEvent and Models.Ticker are identical objects with equivalent JsonProperty attributes, except that one inherits from event. I’m just using the tickerevent, and I don’t see when I would ever use the dup class, do you prefer to cast over the lighter weight Ticker object in the handler?

Josh

From: Brian Chavez notifications@github.com Sent: Tuesday, August 18, 2020 7:06 PM To: bchavez/Coinbase.Pro Coinbase.Pro@noreply.github.com Cc: Josh Miller josh@coolbluewater.org; Author author@noreply.github.com Subject: Re: [bchavez/Coinbase.Pro] support question : how do trap socket exceptions (#18)

Hi Josh,

Are you sure you are using my library?

From the VB.NET code you posted, I think you are using someone else's Coinbase Pro library found here: https://github.com/dougdellolio/coinbasepro-csharp

My Coinbase Pro API does not have a coinClient.WebSocket web socket property; however, the other .NET Coinbase Pro library does as shown here: https://github.com/dougdellolio/coinbasepro-csharp/blob/c67c22ce18494017abf06b85476cba1753977ab0/CoinbasePro/CoinbaseProClient.cs#L102

My websocket implementation is completely separate from the REST API implementation. In other words:

Also, the types you posted don't seem to match up to my API models. I think you might be using the other Coinbase Pro library.

Thanks, Brian

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/bchavez/Coinbase.Pro/issues/18#issuecomment-675793297, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AALKA7RZOE6PK7ESKILSPADSBMQOVANCNFSM4QCABPAA.

bchavez commented 4 years ago

Hi Josh, thank you again for the donation! I really appreciate it. And, thank you for supporting open source!

To answer your question, you should definitely use TickerEvent because it derives from Event. All websocket models derive from the Event parent class. That is, in C#, TickerEvent : Event.

Additionally, you'll want to use the WebSocketHelper.TryParse() method to turn the webhook json into an object for inspection. The following C# code demonstrates handling the HeartbeatEvent and TickerEvent from a websocket stream:

private static void Websocket_MessageReceived(object sender, WebSocket4Net.MessageReceivedEventArgs e)
{
   WriteLine("Message received.");
   if( WebSocketHelper.TryParse(e.Message, out var msg) )
   {
      if( msg is HeartbeatEvent hb )
      {
         WriteLine($"Sequence: {hb.Sequence}, Last Trade Id: {hb.LastTradeId}");
      }

      if( msg is TickerEvent te )
      {
         WriteLine($"Ticker: {te.Sequence}, {te.ProductId}, Ask: {te.BestAsk}, Bid: {te.BestBid}");
      }
   }
}

If you have any more questions, feel free to ask.

Thanks, Brian

bwjunkie commented 4 years ago

I Haven’t found a reliable way to recover from a broken/errored/closed socket. When I re-instance during the error_handler it sometimes works sometimes not, do you have a proven method?

Josh

From: Brian Chavez notifications@github.com Sent: Tuesday, August 18, 2020 7:06 PM To: bchavez/Coinbase.Pro Coinbase.Pro@noreply.github.com Cc: Josh Miller josh@coolbluewater.org; Author author@noreply.github.com Subject: Re: [bchavez/Coinbase.Pro] support question : how do trap socket exceptions (#18)

Hi Josh,

Are you sure you are using my library?

From the VB.NET code you posted, I think you are using someone else's Coinbase Pro library found here: https://github.com/dougdellolio/coinbasepro-csharp

My Coinbase Pro API does not have a coinClient.WebSocket web socket property; however, the other .NET Coinbase Pro library does as shown here: https://github.com/dougdellolio/coinbasepro-csharp/blob/c67c22ce18494017abf06b85476cba1753977ab0/CoinbasePro/CoinbaseProClient.cs#L102

My websocket implementation is completely separate from the REST API implementation. In other words:

Also, the types you posted don't seem to match up to my API models. I think you might be using the other Coinbase Pro library.

Thanks, Brian

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/bchavez/Coinbase.Pro/issues/18#issuecomment-675793297, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AALKA7RZOE6PK7ESKILSPADSBMQOVANCNFSM4QCABPAA.

bchavez commented 4 years ago

Hi Josh,

Here's an example that should recover from TCP disconnects:

https://github.com/bchavez/Coinbase.Pro/blob/master/Source/Examples/ResilientWebSocket.cs

Please be sure you're using the latest v3.2.0 version. I made a small modification to ConnectAsync that returns a ConnectResult for better connection semantics.

The ResilientWebSocket class should be able to recover and reconnect on its own. You'll generally want to follow the same code structure as outlined in the C# file.

Here is an example of output with intermittent connection failures and recoveries:

Coinbase Example
Subscribing to Websocket Events.
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
>> Connected.
>> Subscribing to events...
>> Subscribed.
Press enter to exit program.
Message received.
Message received.
Sequence: 190132839, Last Trade Id: 0
Message received.
Sequence: 190132849, Last Trade Id: 0
Message received.
Sequence: 190132856, Last Trade Id: 0
Message received.
Sequence: 190132866, Last Trade Id: 0
Message received.
Sequence: 190132869, Last Trade Id: 0
Message received.
Sequence: 190132871, Last Trade Id: 0
Message received.
Sequence: 190132878, Last Trade Id: 0
Message received.
Sequence: 190132884, Last Trade Id: 0
Message received.
Sequence: 190132893, Last Trade Id: 0
Message received.
Sequence: 190132898, Last Trade Id: 0
Message received.
Sequence: 190132903, Last Trade Id: 0
Message received.
Sequence: 190132911, Last Trade Id: 0
Message received.
Sequence: 190132923, Last Trade Id: 0
Message received.
Sequence: 190132929, Last Trade Id: 0
Message received.
Sequence: 190132937, Last Trade Id: 0
!! The websocket closed!
!! Reconnecting...
>> Connecting websocket...
>> Connected.
>> Subscribing to events...
>> Subscribed.
Message received.
Message received.
Sequence: 190132950, Last Trade Id: 0
Message received.
Sequence: 190132955, Last Trade Id: 0
Message received.
Sequence: 190132959, Last Trade Id: 0
Message received.
Sequence: 190132964, Last Trade Id: 0
!! The websocket closed!
!! Reconnecting...
>> Connecting websocket...
>> Connected.
>> Subscribing to events...
>> Subscribed.
Message received.
Message received.
Sequence: 190132970, Last Trade Id: 0
Message received.
Sequence: 190132970, Last Trade Id: 0
Message received.
Sequence: 190132972, Last Trade Id: 0
Message received.
Sequence: 190132979, Last Trade Id: 0
!! Websocket Error!
SuperSocket.ClientEngine.ErrorEventArgs
!! The websocket closed!
!! Reconnecting...
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
System.Exception: Connect failed.
   at Examples.ResilientWebSocket.Reconnect(Credentials creds, Subscription subscription) in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 77
   at Examples.ResilientWebSocket.SafeReconnect() in C:\Code\Projects\Public\Coinbase.Pro\Source\Examples\ResilientWebSocket.cs:line 136
>> Connecting websocket...
>> Connected.
>> Subscribing to events...
>> Subscribed.
Message received.
Message received.
Sequence: 190133017, Last Trade Id: 0
Message received.
Sequence: 190133020, Last Trade Id: 0
Message received.
Sequence: 190133025, Last Trade Id: 0
Message received.
Sequence: 190133027, Last Trade Id: 0
Message received.
Sequence: 190133029, Last Trade Id: 0
Message received.
Sequence: 190133031, Last Trade Id: 0
Message received.
Sequence: 190133038, Last Trade Id: 0
Message received.
Sequence: 190133040, Last Trade Id: 0
Message received.
Sequence: 190133045, Last Trade Id: 0
Message received.
Sequence: 190133052, Last Trade Id: 0

Hope that helps, Brian