WebSocketSharp with BinanceAPI - websocket

I have a connection with binanceApi and I have a disconnect problem,
the API disconnects and I don't know the reason, I wanna keep the connection alive until I have the orders in position. I will post my code, maybe someone can help me.
I already have created another two projects with websocketsharp on localhost to test and all disconnects fire normally.
https://pastebin.com/edit/2Mbh1X4p
public class WSMonitorada
{
public WebSocket ws;
public Usuario User;
public Timer timerKeepAlive = new Timer();
public WSMonitorada(Usuario user, string key)
{
timerKeepAlive.Interval = TimeSpan.FromMinutes(15).TotalMilliseconds;
timerKeepAlive.Elapsed += (object source, ElapsedEventArgs e) =>
{
BinanceUserDataStream.KeepAlive(User.BinanceAPIKey, user.BinanceAPISecret);
};
timerKeepAlive.Start();
ws = new WebSocket("wss://stream.binance.com:9443/ws/" + key);
ws.WaitTime = TimeSpan.FromSeconds(5);
ws.Log.Level = LogLevel.Trace;
ws.Log.File = "C:\\LogConexao\\" + user.nome + ".txt";
//log file never show close event
ws.OnOpen += (sender, e) =>
{
//logic here wors perfect
};
ws.EmitOnPing = true;
ws.OnMessage += (sender, e) =>
{
if (e.IsPing)
{
ws.Ping();
return;
}
//logic here wors perfect
}
ws.OnClose += (sender, e) =>
{
// i have a logic here to analyse if i have a opened order and reconnect again but event never fire
ws.Connect();
};
ws.Connect();
}
}

I think your Ping is not correct. The server waits for 'pong' message
UPD
According to binance docs =)

Related

cancel taskcompletionsource which calls a void method from an API with timeout xamarin forms

I have this non-async Task> which just requests:
TaskCompletionSource<ObservableCollection<ItemDto>> tcs = new TaskCompletionSource<ObservableCollection<ItemDto>>();
ObservableCollection<ItemDto> results = new ObservableCollection<ItemDto>();
try
{
BasicHttpBinding binding = new BasicHttpBinding();
binding.OpenTimeout = new TimeSpan(0, 0, 30);
binding.CloseTimeout = new TimeSpan(0, 0, 30);
binding.SendTimeout = new TimeSpan(0, 0, 30);
binding.ReceiveTimeout = new TimeSpan(0, 0, 30);
MobileClient clientMobile = new MobileClient(binding, new EndpointAddress(_endpointUrl));
clientMobile.FindItemsCompleted += (object sender, FindItemsCompletedEventArgs e) =>
{
if (e.Error != null)
{
_error = e.Error.Message;
tcs.TrySetException(e.Error);
}
else if (e.Cancelled)
{
_error = "Cancelled";
tcs.TrySetCanceled();
}
if (string.IsNullOrWhiteSpace(_error) && e.Result.Count() > 0)
{
results = SetItemList(e.Result);
tcs.TrySetResult(results);
}
clientMobile.CloseAsync();
};
clientMobile.FindItemsAsync(SetSearchParam(searchString, 100));
}
catch (Exception)
{
results = new ObservableCollection<ItemDto>();
tcs.TrySetResult(results);
}
return tcs.Task;
Yes, I know, nothing special, it's just that this
clientMobile.FindItemsAsync(SetSearchParam(searchString, 100))
is a call to a void method, which in turn calls another void method which sets a few params in order to then call an async method which itself calls an async method which performs an async operation to return the list of Items.
Problem is, I have no control whatsoever of anything beyond the scope of this Task above, because everything I just explained is part of an API, in which I'm not allowed to touch, and of which I can make no comment, regarding the way it works, as the policy is for me to adapt my work to it... -_-
So, in order to do that, I must kill this call to the FindItemsAsync, as soon as a total of 1 minute has passed... I tried setting the above timespans to a minute each (first worked, now some changes have been made and no go), I tried reducing to half the time, and no go...
Here's the code which is calling this Task:
public void LoadItemList(string searchString)
{
_itemList = new ObservableCollection<ItemDto>();
// Calls the Task LoadList.
var result = LoadList(searchString).Result;
if (result != null && result != new ObservableCollection<ItemDto>())
{
_itemList = result;
}
else
{
_isTaskCompleted = false;
}
_isListEmpty = (_itemList != new ObservableCollection<ItemDto>()) ? false : true;
}
and below is the code which calls the caller of this task... (what a mess -_-):
void Init(string searchString = "")
{
Device.BeginInvokeOnMainThread(async () =>
{
if (!LoadingStackLayout.IsVisible && !LoadingActivityIndicator.IsRunning)
{
ToggleDisplayLoadingListView(true);
}
await Task.Run(() => _listVM.LoadItemList(searchString));
ToggleDisplayLoadingListView();
if (!string.IsNullOrWhiteSpace(_listVM.Error))
{
await DisplayAlert("Error", _listVM.Error, "OK");
}
else if (_listVM.AdList != null && !_listVM.IsListEmpty)
{
ItemListView.IsVisible = true;
ItemListView.ItemsSource = _listVM.ItemList;
}
else if (!_listVM.IsTaskCompleted || _listVM.IsListEmpty)
{
await DisplayAlert("", "At the moment it is not possible to show results for your search.", "OK");
}
else if (_listVM.ItemList.Count == 0)
{
await DisplayAlert("", "At the moment there are no results for your search.", "OK");
}
});
}
At the moment I'm trying to implement the MVVM arch...
Really, thank you so much for your help on this matter, it's been great, and I really apologize for all this inconvenience...
EDIT
Sorry because I didn't explain my objective clearly; it is: I need to fetch a list of Items accessing an API that just communicates with me via a void method FindItemsAsync. I have 60 seconds to fetch all those items. If something goes wrong, or if timeout, I have to cancel the process and inform the user something went wrong.
That doesn't happen. It never cancels. Either gets me the Items, or stays loading forever, dispite my hardest tries... I'm new to tasks and most of this stuff, hence my constant issues...
You can call CloseAsync when your cancellation token expires.
//Creates an object which cancels itself after 5000 ms
var cancel = new CancellationTokenSource(5000);
//Give "cancel.Token" as a submethod parameter
public void SomeMethod(CancellationToken cancelToken)
{
...
//Then use the CancellationToken to force close the connection once you created it
cancelToken.Register(()=> clientMobile.CloseAsync());
}
It will cut down the connection.

Code to execute if a navigation fails

Hello I have no idea where I should start looking. I add few prop (before that my code run fine), then I get
System.Diagnostics.Debugger.Break();
so then I comment that changes, but that didn't help.
Could you suggest me where I should start looking for solution?
MyCode:
namespace SkydriveContent
{
public partial class MainPage : PhoneApplicationPage
{
private LiveConnectClient client;
FilesManager fileManager = new FilesManager();
// Constructor
public MainPage()
{
InitializeComponent();
}
private void signInButton1_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
{
if (e.Status == LiveConnectSessionStatus.Connected)
{
client = new LiveConnectClient(e.Session);
infoTextBlock.Text = "Signed in.";
client.GetCompleted +=
new EventHandler<LiveOperationCompletedEventArgs>(OnGetCompleted);
client.GetAsync("/me/skydrive/files/");
fileManager.CurrentFolderId = "/me/skydrive/files/";
}
else
{
infoTextBlock.Text = "Not signed in.";
client = null;
}
}
void OnGetCompleted(object sender, LiveOperationCompletedEventArgs e)
{
//Gdy uda nam się podłaczyc do konta skydrive
if (e.Error == null)
{
signInButton1.Visibility = System.Windows.Visibility.Collapsed;
infoTextBlock.Text = "Hello, signed-in user!";
List<object> data = (List<object>)e.Result["data"];
fileManager.FilesNames.Clear();
filemanager.filesnames.add("..");
foreach (IDictionary<string,object> item in data)
{
File file = new File();
file.fName = item["name"].ToString();
file.Type = item["type"].ToString();
file.Url = item["link"].ToString();
file.ParentId = item["parent_id"].ToString();
file.Id = item["id"].ToString();
fileManager.Files.Add(file);
fileManager.FilesNames.Add(file.fName);
}
FileList.ItemsSource = fileManager.FilesNames;
}
else
{
infoTextBlock.Text = "Error calling API: " +
e.Error.ToString();
}
}
private void FileList_Tap(object sender, GestureEventArgs e)
{
foreach (File item in fileManager.Files)
{
if (item.fName == FileList.SelectedItem.ToString() )
{
switch (item.Type)
{
case "file":
MessageBox.Show("Still in progress");
break;
case "folder":
fileManager.CurrentFolderId = item.ParentId.ToString();
client.GetAsync(item.Id.ToString() + "/files");
break;
default:
MessageBox.Show("Coś nie działa");
break;
}
}
else if (FileList.SelectedItem.ToString() == "..")
{
client.GetAsync(fileManager.CurrentFolderId + "/files");
}
}
}
}
}
Running stop at that line.
// Code to execute if a navigation fails
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// A navigation has failed; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
You should check all of the URLs you have both in the XAML and code. When you get to the NavigationFailed function, it means that the phone tried to navigate to some page that did not existed. We would be able to help more if you could tell what were you doing when the app threw the exception.
System.Diagnostics.Debugger.Break();
usually happens because of an Uncaught Exception.
Either post the code which started giving problems, or the stack trace when you encounter this problem.
No one can tell anything without actually seeing what you are doing.

Windows Phone 7 - wait for Webclient to complete

I'm developing an app and have run into a problem with asynchronous calls... Here's what i'm trying to do.
The app consumes a JSON API, and, when run, fills the ListBox within a panorama item with the necessary values (i.e. a single news article). When a user selects a ListBox item, the SelectionChanged event is fired - it picks up the articleID from the selected item, and passes it to an Update method to download the JSON response for the article, deserialize it with JSON.NET, and taking the user to the WebBrowser control which renders a html page from the response received.
The problem with this is that I have to wait for the response before I start the NavigationService, but I'm not sure how to do that properly. This way, the code runs "too fast" and I don't get my response in time to render the page.
The event code:
private void lstNews_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lstNews.SelectedIndex == -1)
{
return;
}
ShowArticle _article = new ShowArticle();
ListBox lb = (ListBox)sender;
GetArticles item = (GetArticles)lb.SelectedItem;
string passId = ApiRepository.ApiEndpoints.GetArticleResponseByID(item.Id);
App.Current.JsonModel.JsonUri = passId;
App.Current.JsonModel.Update();
lstNews.SelectedIndex = -1;
NavigationService.Navigate(new Uri("/View.xaml?id=" + item.Id, UriKind.Relative));
}
OnNavigatedTo method in the View:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
long sentString = long.Parse(NavigationContext.QueryString["id"]);
string articleUri = ApiRepository.ApiEndpoints.GetArticleResponseByID(Convert.ToInt32(sentString));
//this throws an error, runs "too fast"
_article = App.Current.JsonModel.ArticleItems[0];
}
The update method:
public void Update()
{
ShowArticle article = new ShowArticle();
try
{
webClient.DownloadStringCompleted += (p, q) =>
{
if (q.Error == null)
{
var deserialized = JsonConvert.DeserializeObject<ShowArticle>(q.Result);
_articleItems.Clear();
_articleItems.Add(deserialized);
}
};
}
catch (Exception ex)
{
//ignore this
}
webClient.DownloadStringAsync(new Uri(jsonUri));
}
async callback pattern:
public void Update(Action callback, Action<Exception> error)
{
webClient.DownloadStringCompleted += (p, q) =>
{
if (q.Error == null)
{
// do something
callback();
}
else
{
error(q.Error);
}
};
webClient.DownloadStringAsync(new Uri(jsonUri));
}
call:
App.Current.JsonModel.Update(() =>
{
// executes after async completion
NavigationService.Navigate(new Uri("/View.xaml?id=" + item.Id, UriKind.Relative));
},
(error) =>
{
// error handling
});
// executes just after async call above

Asking about webClient in Windowsphone 7

I'm trying to create a simple app for my phone that can get data from a website and save to the phone. After I looked for, I knew I have to use webClient for this app. When I code I have a problem that set value for a property in a class.
class data
{
public string temp = "";
public void getContent(string url)
{
var client = new WebClient();
client.DownloadStringCompleted += (s, e) => { /*my problem is right here*/};
client.DownloadStringAsync(new Uri(url));
}
}
For example: e.result = "this is a book" so how can I set "e.result" for "temp"?
just replace
client.DownloadStringCompleted += (s, e) => { /*my problem is right here*/};
with
client.DownloadStringCompleted += (s, e) => {
temp = e.Result;
};

UI not updating in async web request callback

I'm using this to make a web request and download some data:
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
var client = new WebClient();
client.DownloadStringCompleted += (s, e) => {
textBlock1.Text = e.Result;
};
client.DownloadStringAsync(new Uri("http://example.com"));
}
}
The text of textBlock1 never changes even though e.Result has the correct data. How do I update that from the callback?
Edit: If I add MessageBox.Show(e.Result); in the callback along with the textBlock1.Text assignment, both the messsage box and the text box show the correct data.
Edit Again: If I add a TextBox and set it's text right after the line textBlock1.Text line, they both show the correct text.
I think, it's a bug.
I also ran into some problems with updating the UI from different dispatchers. What I finally did was use the TextBlock's (or other UI Element) own dispatcher and that worked for me. I think the phone framework may be using different dispatchers between the app and UI Elements. Notice the change from dispatcher.BeginInvoke to textbox1.Dispatcher...
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var dispatcher = Deployment.Current.Dispatcher;
var client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
var result = e.Result;
textBlock1.Dispatcher.BeginInvoke(
()=> textBlock1.Text = result
);
};
client.DownloadStringAsync(new Uri("http://example.com"));
}
From browsing through the WP7 forums, a bunch of people were reporting that this was related to a video card driver issue. I've updated my ATI Radeon HD 3400 drivers to the latest version and it appears to work now.
client.DownloadStringAsync is expecting a Uri like this:
client.DownloadStringAsync(new Uri("http://example.com"));
also, shouldn't you update your TextBlock through a Dispatcher.BeginInvoke like this:
client.DownloadStringCompleted += (s, e) =>
{
if (null == e.Error)
Dispatcher.BeginInvoke(() => UpdateStatus(e.Result));
else
Dispatcher.BeginInvoke(() => UpdateStatus("Operation failed: " + e.Error.Message));
};
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var dispatcher = Deployment.Current.Dispatcher;
var client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
var result = e.Result;
dispatcher.BeginInvoke(
()=> textBlock1.Text = result
);
};
client.DownloadStringAsync(new Uri("http://example.com"));
}
}
I want to comment but can't yet. Yes, I have a very similar issue. In my case it's my viewmodel that is updating a DownloadStatus property, then when the download is completed I do some more work and continue updating this property.
The view stops updating once the ViewModel code hits the OpenReadCompleted method. I've stepped carefully through the code. PropertyChanged fires, and the view even comes back and retrieves the new property value, but never shows the change.
I was sure it was a bug, but then I created a brand new project to reproduce the issue, and it works fine!
Here's a snippet of my non-reproducing code. The UI textblock bound to "DownloadStatus" happily updates properly all the way through. But the same paradigm doesn't work in my main project. Infuriating!
public void BeginDownload(bool doWorkAfterDownload)
{
DownloadStatus = "Starting ...";
_doExtraWork = doWorkAfterDownload;
var webClient = new WebClient();
string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("test:password"));
webClient.Headers["Authorization"] = auth;
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(new Uri("http://www.ben.geek.nz/samsung1.jpg"));
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error != null)
{
DownloadStatus = e.Error.Message;
return;
}
DownloadStatus = "Completed. Idle.";
if(_doExtraWork)
{
Thread t = new Thread(DoWork);
t.Start(e.Result);
}
}
void DoWork(object param)
{
InvokeDownloadCompleted(new EventArgs());
// just do some updating
for (int i = 1; i <= 10; i++)
{
DownloadStatus = string.Format("Doing work {0}/10", i);
Thread.Sleep(500);
}
DownloadStatus = "Completed extra work. Idle.";
InvokeExtraWorkCompleted(new EventArgs());
}

Resources