How to connect to binance WS api - c#

I'm trying to implement the binance specification for their API using C#.
After building the foundation, I tried to reach wss://stream.binance.com:9443/ws/. But each time I use the code below to connect, the application stops abruptly whith no exception.
using CancellationTokenSource tcs = new CancellationTokenSource(TimeSpan.FromSeconds(10));
await _socket.ConnectAsync(BaseUri, tcs.Token).ConfigureAwait(false);
Of course, with BaseUri = wss://stream.binance.com:9443/ws/ and ClientWebSocket _socket . I've seen people talking about a handshake message, but could not find anything on binance doc. I'm i doing something wrong?
UPDATE :
How can i at least debug this ? The connect method doesn't return any data...

Refer to this link for the solution. I now get a 400 bad request instead which helps a lot !
ClientWebSocket.ConnectAsync crashes with out any error info

Related

RestSharp Response error: "Only one usage of each socket address (protocol/network address/port) is normally permitted"

I'm using RestSharp to communicate with a .Net Core Web API. Both Client and Server are written by me.
I have a suite of Services all inheriting a Base class which contains an async method to perform the request via a RestClient. Here is the method within the base class that creates the RestClient.
private async Task<ServiceResponse> RequestAsync(ServiceRequest request)
{
try
{
var result = await new RestClient(_digiCore.Config.GetApiBaseUrl()).ExecuteTaskAsync(request.Request, request.CancellationTokenSource.Token);
switch (result.StatusCode)
{
case HttpStatusCode.OK:
case HttpStatusCode.Created:
case HttpStatusCode.NoContent:
return new ServiceResponse
{
Code = ServiceResponseCode.Success,
Content = result.Content
};
// User wasn't authenticated for this one - better luck next time!
case HttpStatusCode.Unauthorized:
Logger.LogError($"Unauthorized {request.Method.ToString()}/{request.Path}");
default:
Logger.LogError($"An error occurred {request.Method.ToString()}/{request.Path}");
}
}
catch (Exception e)
{
Logger.LogError($"A Rest Client error occurred {request.Method.ToString()}/{request.Path}");
}
}
My understanding is that the RestClient (unlike HttpClient) is thread safe and OK to create a new instance each time.
When Load testing my application, one I reach a certain point, I find that I occasionally receive the following response back from the API. Refreshing the page might bring back the correct result, or I might get another error. When the Load Test has finished everything goes back to normal. The numbers of the load test are nothing crazy, so its started to get me worried about real-life performance...
Only one usage of each socket address (protocol/network address/port) is normally permitted
I believe this is down to port exhaustion. Both API and Client are running in Azure as App services.
I have tried making the RestClient part of a singleton service, and checked that it is only created once - but this did not alleviate the issue.
I have also looked into setting the DefaultConnectionLimit in the Startup function of my startup class from the default (2) to 12, but I did not see any improvements here either.
I'm really struggling to see how I can improve this...
Found out the reason for this...
It seems there is currently an issue with RestSharp whereby socket connections are not closed down immediately and instead are left in TIME_WAIT state.
This issue is currently logged with the RestSharp guys here ->
https://github.com/restsharp/RestSharp/issues/1322
I have chosen to switch over to using HttpClient - and running the exact same load test I had zero problems.
Here is an screenshot taken from Azure showing the difference between the two load tests.
Was with my app using RestSharp
Was with my app using Http Client
Hope this helps somebody. It's a shame I had to ditch RestSharp as it was a nice little library - unfortunately with an issue like this it's just too risky to run in a Production environment.

how to set httpclient connect timeout?

I'm struggling with setting connect timeout with c# HttpClient or its siblings (HttpClientHandler,WebRequestHandler,...) . There's a timeout property in HttpClient, but it seems to be a timeout from the beginning of the request until receiving the response. I want to have a method which specify that for example if you don't received ACK from the net socket within 10 seconds for example , then break up and do the next.
I saw that there may be something similar in WinHttpHandler class, but it seems to be deleted or not available in recent version. compare the first link vs second :
1.WinHttpHandler MSDN
2.WinHttpHandler Microsoft Docs
I really need this, because I must differentiate asap between IP's which have a working web servers (maybe slow) vs which don't have a web server at all.
I use HttpWebRequest.Timeout in my project to verdict the connection time before establish tcp connection. And use HttpWebRequest.ReadOrWriteTimeout to verdict whole response timeout.
Ps: The HttpClient seems cut off some useful properties.

Adjust HttpRequst Timeout Before Creating any HttpWebRequest

In C# 5 and winform, I used a library created by Telegram Company. In this library there is a function SendDocument(UserId,DocumentStream). I know in this function, they used some HttpWebRequest, and the Timeout property of that is not handled. because sometimes it can't send large documents and after exact 100 seconds(default timeout in DotNet), the function throws an exception The task was canceled.
From the document of Telegram Company, we can send 50 MB files and my example files is about 15 MB.
Ok, Now I want to adjust the timeout of all HttpWebRequest of my server but I don't have any feature for this.
Can I adjust all HttpWebRequest.Timeout property in my server??
This is not directly related to your question, but may help ease your mind.
My advice is, don't bother adjusting the timeout. It is not likely to help. Here is what I have gone through:
I have tried to upload a 20M mp4 video file using Telegram Bot API. From a Raspberry Pi, it took 5 minutes, then returned a 504 Gateway-Timeout error. From a hosted server, it took 1 minute, then returned a 504 Gateway-Timeout error. In both cases, however, the video did eventually reach the recipient 5 minutes later. So, the upload seemed somewhat successful, yet not quite successful.
I tried to fix the problem by streaming the upload. Same problem persisted.
I tried to adjust the HTTP timeout parameter. Same problem persisted.
I tried to use cURL to make the request (instead of using telepot, a Python library I author). Same problem persisted.
I suspect the problem lies with the Telegram servers, so I talked to Bot Support. They got back to me once, saying they have made some improvements and asked if I still have the same problem. But same problem still persists.
So, it seems the problem does lie with the Telegram servers. It's not your code.
I know it's a pretty old question but may be my answer will help somebody. When I tried to send cosiderably large files via my bot I received Telegram.Bot.Exceptions.ApiRequestException: Request timed out and the only solution I found was this issue. Which wasn't really helpfull because if you check source code then you'll see that passing cancellation token does nothing with request timeout. But then I saw that you can pass HttpClient to your bot client instance and make it something like this:
_httpClient = new HttpClient();
_httpClient.Timeout = new TimeSpan(0, 5, 0); // 5 min
_client = new TelegramBotClient(botConfig.Token, _httpClient);
Hope this will help

Feed subscription of a Page

I want to get notifications when a new feed has landed on a designated page (by page id). After what I understand, the Realtime-update og Graph API should be able to do this trick according to https://developers.facebook.com/docs/graph-api/real-time-updates/v2.4.
So I want to add a new subscription, which I try to do with the following code:
dynamic result = client.Post(urlPath, new
{
#object = "page",
callback_url = callbackUrl,
fields = "feed",
verify_token = "654321",
access_token = accessToken
});
return result;
But when I try to run this, I'm getting the following error code:
(OAuthException - #2200) (#2200) callback verification failed: Received HTTP code 502 from proxy after CONNECT"
What do I miss?
The callback url is https://127.0.0.1:8989/ and I have a TcpListener running on the port, which does not seem to get any response/request incoming...
The application is a C# console application, so no fancy asp.net stuff or something. I'm using the Facebook .net SDK.
Should I FacebookClient.VerifyPostSubscription() or anything else that I missed out?? Maybe the SDK wraps a handle?
So the answer I'm looking for is:
- How do I create/add a subscription for feeds of a facebook page, using the .net SDK on a windows console project??
UPDATE:
I changed the loopback with a domain name, that I the NAT to my target machine, and now I actually get some encrypted data on my TcpListener!
So, the question now is, how do I respond correctly to this received respons, only by using a Tcp Client??
How you have to respond is exactly outlined in the docs you linked:
https://developers.facebook.com/docs/graph-api/real-time-updates/v2.4#setupget
It's not really clear what you mean with "TCP listener". You need to have some logic why can send HTTP responses to the Facebook servers, otherwise your service will be disregarded after some time, meaning no updates will be send.
Typically, this is implemented as a script/application in a web/application server.
Please note: The "C# SDK" is a third-party SDK and not officially supported by FB.

How to build TCP IP listner to read incoming messages using chilkat socket class c#

I am using chilkat socket class. The problem is I want to keep my socket open, lets say I executed my form and the very first time which opened the port on a specific IP to listen the messages.I am able to receive the messages first time only successfully, now after this message I want to keep my application to keep listening and receive when ever a new message comes.
We have several clients who will connect and send some text messages on the same port and ip.
But I am unable to achieve this. I need to build a Listener, which will keep on listening and as soon as I will get any message I need to process it. Any body who has used chilkat class or having experience in this kind of application kindly suggest me how can I achieve this functionality as I could't find good example for this kind of application on CHILKAT website or may be I am inexperienced don't know how to exactly code this type of functionality.
Edit 1: Jermy,
yes we have developed REST WCF services and they are working perfect, but the problem is in the response of REST WCF Service big response headers are appearing, which we don't want because in our enterprise application Windows Phone 7 mobiles will also communicate and send text messages and only for the sake of mobiles we are trying to reduce the data we need to pass back and by using sockets we can avoid extra response headers and SMS is not an option for us because of cost. If you have any suggestions towards Webservices to minimize the data kindly share it.
Have you considered a Web Service? They can be consumed by pretty much any language that can send Http requests. If you have control of the client applications then a Web Service is definitely the correct route.
http://sarangasl.blogspot.com/2010/09/create-simple-web-service-in-visual.html
Edit:
Have you considered simple http upload of bytes, with a http response code. Ie Http Ok, Http Failure. You can customize the status codes to anything that suits your project.
Edit 2:
Perhaps an RPC styled method with ONLY http status codes as the response could be suitable. Checks this question for hints. json call with C#
Basically you are just sending some string to a url, then receiving the status code back. That is quite minimal.
Edit 3:
Here is something I pulled out of some old code with Reflector. This is just for the general gist of the procedure. Obviously there should be a using statement on the first request.
public void SMS(Uri address, string data)
{
// Perhaps string data is JSON, or perhaps its something delimited who knows.
// Json seems to be the pretty lean.
try
{
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(address);
request.Method = "POST";
// If we don't setup proxy information then IE has to resolve its current settings
// and adds 500+ms to the request time.
request.Proxy = new WebProxy();
request.Proxy.IsBypassed(address);
request.ContentType = "application/json;charset=utf-8";
// If your only sending two bits of data why not add custom headers?
// If you only send headers, no need for the StreamWriter.
// request.Headers.Add("SMS-Sender","234234223");
// request.Headers.Add("SMS-Body","Hey mom I'm keen for dinner tonight :D");
request.Headers.Add("X-Requested-With", "XMLHttpRequest");
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.WriteLine(data);
writer.Close();
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
// Either read the stream or get the status code and description.
// Perhaps you won't even bother reading the response stream or the code
// and assume success if no HTTP error status causes an exception.
}
}
}
catch (WebException exception)
{
if (exception.Status == WebExceptionStatus.ProtocolError)
{
// Something,perhaps a HTTP error is used for a failed SMS?
}
}
}
Remember to respond only with Http status codes and descriptions. And ensure that the request's proxy is setup to bypass the requesting Url to save time resolving the IE proxy.

Categories

Resources