delegatevoid Posted November 19, 2013 Report Share Posted November 19, 2013 Hi, For those who are interested, I just published a C# implementation of the API on Bitbucket.It's an early draft and the tests need some restructuring, will do that asap. If anybody is interesting in helping, you know what to do. The repository can be found here:https://bitbucket.org/timothyp/arendee-btsynclib Quote Link to comment Share on other sites More sharing options...
marc321 Posted August 11, 2014 Report Share Posted August 11, 2014 Thank you very much, sir! Is there any c++ implementation to this date? Regards Quote Link to comment Share on other sites More sharing options...
delegatevoid Posted August 13, 2014 Author Report Share Posted August 13, 2014 Hi, I'm not aware of C++ implementations except for the first result on google: https://github.com/boxdot/btsync-cppPerhaps that one can get you started. Quote Link to comment Share on other sites More sharing options...
marc321 Posted August 16, 2014 Report Share Posted August 16, 2014 I don't know how I couldn't find that. Thank you! Quote Link to comment Share on other sites More sharing options...
marc321 Posted September 4, 2014 Report Share Posted September 4, 2014 Dear Delegatevoid, as I'm new to OOP programming, and since your (excellent) implementation relies heavily on it's concepts, I'd like to clarify an issue I'm having. I have developed an application which:1 - starts an instance of Btsync.exe with the supplied config file using Process.Start()2 - creates a folder C:\test3 - makes use of the AddFolder method to have that folder synced (a read-only key is provided with my application)4 - closes itself (btsync will remain running) The problem is, my program won't accomplish step 3 unless I give it some time before the program closes (either using Console.Read() or Thread.Sleep() ). I do believe this is caused by the method being asynchronous. Is it correct? What can I do about this, other than pausing the execution for a little while before the program exits? Anyone else please feel free to help me on this as well. Thanks! Answer I was usingstatic async void AddFolderToSync()and calling that method under the Main method of my console app. Now I've switched tostatic async Task AddFolderToSync()and it's called like thisAddFolderToSync().Wait()and my problem is solved. Reference: http://stackoverflow.com/questions/3840795/console-app-terminating-before-async-call-completion Quote Link to comment Share on other sites More sharing options...
delegatevoid Posted September 5, 2014 Author Report Share Posted September 5, 2014 Hi, You are correct to say that the methods in the library are all asynchronous.By default this means fire and forget. You start a Task which gets executed somewhere elseand your applications imply continues to execute whatever line of code follows. I'm sure you are using a console application so here's what's happeningYour application starts at the entry point public static void Main() It executes the code in that method, starting with whatever logic you use to start BTSync It then creates the folder (be careful where you create it, your application may not have access to that location) Then you start a new task by calling client.AddFolder but that method is asynchronous, so it (to put it simply) gets executed somewhere else and your main thread does not wait for it, instead it continues to execute the next line in your main method. If there is nothing there, your application will close and the task along with it.While your answer, posted above, would work, it is not the correct way of using the code.Instead you should use the async/await pattern in C# (http://msdn.microsoft.com/en-us/library/hh191443.aspx) Consider the following (a little over simplified example):using Arendee.BTSyncLib;using System;using System.IO;using System.Threading;using System.Threading.Tasks;namespace BTSyncExample{ class Program { private bool exitApplication; private string server; private string username; private string password; private string deviceName; private int port; static void Main(string[] args) { new Program(); } new Program() { //Replace the values here to fit your setup Run("localhost", 8888, "spongebob", "squarepants", "HelloBTSync"); while (!exitApplication) { Thread.Sleep(500); } } public async void Run(string server, int port, string username = "", string password = "", string deviceName = "YourAppName") { this.server = server; this.port = port; this.username = username; this.password = password; this.deviceName = deviceName; StartBTSync(); await AddBTSyncFolder("c:\\test", "yoursecrethere"); Console.Write("Press any key to continue..."); Console.ReadKey(); exitApplication = true; } private async Task AddBTSyncFolder(string path, string secret) { try { if (!Directory.Exists(path)) { Console.WriteLine("Creating directory: '{0}'", path); Directory.CreateDirectory(path); } Console.WriteLine("Adding the folder to BTSync"); var client = new BTSyncClient(server, port, username, password, deviceName); await client.AddFolder(path, secret); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Add folder failed: {0}", ex.Message); Console.ForegroundColor = ConsoleColor.White; } } private void StartBTSync() { //Do whatever you need to to start btsync } }}Start by looking at the AddBTSyncFolder method. It's signature includes the async keyword and returns a Task.Simply put, a Task is something that will get executed somewhere else and you can wait for it to complete.After creating the folder it creates an instance of BTSyncClient and calls AddFolder. await client.AddFolder(path, secret);Note the await keyword. This means the method execution will stop at this line, the AddFolder task will be started,and when it has been completed, method execution will resume as if nothing happened. (Note that the AddBTSyncFolder function is not a clean function, it does two things, creating a folder and adding it to BTSync, normally a function should do one thing and one thing only, but for the purpose of this example it should be fine) The Run method is also defined as async but it does not return a Task. An async method that does not return a taskis truly fire and forget. It is started and there is no way to wait for it. It has to be like this because, otherwise any methodcalling Run would have to be asynchronous as well. The main entry point for your application and the constructor of theProgram class cannot be asynchronous, so Run does not return a Task. (For more info on this check out articles referringto async/await being contagious). So finally there is the constructor of the Program class which calls Run.It will start executing the code in Run but it will not wait and if you do nothing after that line,your application will, once again, simply exit. So I've included a while loop which will put the main thread to sleep until exitApplication is set to true. It may seem a little counter-intuitive, but that's because async/await does not really lend itself for usein a console application. That doesn't mean it shouldn't be used in console applications, it just means thatthere's a little extra work to be done to make it behave properly. A desktop application for example, does notexit until all windows have been closed so there is no need for a wait loop. The async/await pattern is particularlyuseful in desktop application as a way to perform long running tasks without freezing the UI thread.(Remember the infamous 'Application xxx is not responding') Once you get the hang of async/await you'll wonder how you ever got things done without it,so if you can, invest some time in learning more about it, you will not regret it. I hope this helps,and if you have any more questions, just ask. Quote Link to comment Share on other sites More sharing options...
marc321 Posted September 5, 2014 Report Share Posted September 5, 2014 Thank you for elucidating, mate. Do you see any reason I should not do the following?public async Task Run()Run("localhost", 8888, "spongebob", "squarepants", "HelloBTSync").Wait;This eliminates the need of using Thread.Sleep() and seems to be a better approach. Also, shouldn't I instantiate BTSyncClient before the beginning of the try clause? Quote Link to comment Share on other sites More sharing options...
delegatevoid Posted September 6, 2014 Author Report Share Posted September 6, 2014 In this particular case, if your application doesn't do anything else at the same time, you can get away with using .WaitWhen you build bigger applications or desktop applications .Wait() will not be suitable. As for the BTSyncClient instance, there's no need to do that before the try.In fact, if you have a try/catch in a method you should always try and make it so that the try isthe very first thing in the method. Quote Link to comment Share on other sites More sharing options...
marc321 Posted September 6, 2014 Report Share Posted September 6, 2014 Alright! Quote Link to comment Share on other sites More sharing options...
marc321 Posted September 6, 2014 Report Share Posted September 6, 2014 Btw, I think I should define the constructor aspublic Program() {definition} instead ofnew Program() {definition} or simply asProgram() {definition} right? Sorry, this is indeed a newbie question. Quote Link to comment Share on other sites More sharing options...
delegatevoid Posted September 7, 2014 Author Report Share Posted September 7, 2014 You are correct, should be public Program() { ... }I wrote that on my Surface using notepad,as I just received it and hadn't installed Visual Studio yet.A typo, my bad, sorry Quote Link to comment Share on other sites More sharing options...
marc321 Posted September 7, 2014 Report Share Posted September 7, 2014 Excellent! No problem. ty Quote Link to comment Share on other sites More sharing options...
marc321 Posted September 9, 2014 Report Share Posted September 9, 2014 Man, I'd like to let you know about an issue with the new version of BTSync (v1.4). Have a look at this snippet:var btSyncClient = new BTSyncClient(SYNC_SERVER, SYNC_PORT, SYNC_USERNAME, SYNC_PASSWORD, syncName);Console.WriteLine("New API instance created");// applies transfer control, if defined by bool variableif (transferSpeedLimit){ var btSyncPrefs = new Arendee.BTSyncLib.Model.SyncPreferences(); btSyncPrefs.UploadLimit = uploadSpeedLimit; await btSyncClient.SetPreferences(btSyncPrefs);}This will throw an exception: -> Could not convert string to integer: *5. Path 'recv_buf_size', line 1, position 1389 <- I'll not look into this myself because I had to decide against using BTSync. Quote Link to comment Share on other sites More sharing options...
lg0 Posted September 9, 2014 Report Share Posted September 9, 2014 Do you have an open source project setup for the development of this on github? Last I checked the requirement was .net 4.5+ do you have a version avalible for 4? Quote Link to comment Share on other sites More sharing options...
delegatevoid Posted September 12, 2014 Author Report Share Posted September 12, 2014 @marck321 You are correct, thank you for pointing it out. Apparently the response to this API request has changed, I will have to check what is going on. @lg0The open source repository for this projects can be found on BitBucket (I am not a fan of GIT)https://bitbucket.org/timothyp/arendee-btsynclib Feel free to post bug/feature requests there. As for 4.0 support, I'm afraid not, since the library relies heavily on async/await.That being said, you could backport it to use .NET 4.0 and the Async CTP for .NET 4.0,however I wouldn't suggest it. Today Windows XP is the only version of Windows not supported by .NET 4.5and nobody should be running that anymore anyway. If you do want to backport it, perhaps you can fork the repository in GitHub, create a new branch for .net 4.0 and if it's good I'll pull it back into the main repoAnd of course I'd be more than willing to help out if need be.@mark321 I looked into it some more, it's actually a bug in the new version of BTSync The values marked with a * should actually just be integer values,and since the latest version they are not. Will post this as a bug Update: I've posted it here: http://forum.bittorrent.com/topic/31616-bug-preference-values-in-btsync-14x-contain/ Quote Link to comment Share on other sites More sharing options...
Wearon Posted March 23, 2015 Report Share Posted March 23, 2015 Hi,thank you for sharing this implementation with us. I have a problem with the SetPreferences() method. Whenever I try to set the variables some of them are not saved.Here is an example:SyncPreferences pref = new SyncPreferences();pref.DeviceName = tb_deviceName.Text;pref.UseUPNP = cb_useUpnp.Checked;pref.ListeningPort = Int32.Parse(tb_listeningPort.Text);var response = await client.SetPreferences(pref);If I go into the Debugger I can see that UseUPNP is set to true. The Request that is build also contains this parameter. But if I look at the response (which should be a list of the new set preferences) the useupnp parameter is now false (or 0 in the response context). I think it only affects values of the type Boolean because for example "deviceName" is saved correctly.I don't know what exactly could be the cause of this. Do you have the same problem? Could this have something to do with the Json converter? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.