private void DoWork() { while (!_shutdown) { DateTime _lastSave = DateTime.MinValue; while (_conn.isPaused == false && Global.PauseAll == false) { if (_que.Count == 0) { SaveQueue(); break; } if (_que.Count > 0 && ClientCommands.isConnected(_conn.MachineName)) { SyncFile file = null; DownloadAsZipFile(); try { _que.TryDequeue(out file); if (file != null) { ProcessFile(file); } } catch (Exception ex) { _log.Error(ex); if (file != null) { _ErrorQue.Enqueue(file); } } if (FastDateTime.Now.Subtract(_lastSave).TotalMinutes > Global.SaveQueueEvery_X_Minute) { SaveQueue(); _lastSave = FastDateTime.Now; } } else { Thread.Sleep(3000); } } Thread.Sleep(1000); } }
private void timer_elapsed(object sender, ElapsedEventArgs e) { if (ClientCommands.isConnected(_conn.MachineName)) { if (_que.Count == 0 && _conn.isClient && _downloading == false) { NewSync(); } } else { // clear cache if connection lost _log.Info("Clearing cache for : " + _conn.Name); _conn.CurrentState = new State(); _conn.isChanged = true; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); } }
public TorpedoSyncServer() { BJSON.Parameters.UseUTCDateTime = true; NetworkClient.Config.KillConnectionSeconds = 1; Directory.CreateDirectory("Computers"); ReadConfigFiles(); _tcpport = Global.TCPPort; _udpport = Global.UDPPort; _webport = Global.WebPort; PrintHeaderConsoleMessages(); _log.Debug("Starting Server..."); _log.Debug("UDP server on port = " + _udpport); Task.Factory.StartNew(() => UDP.StartUDPServer(_udpport)); _log.Debug("TCP server on port = " + _tcpport); _tcpserver.Start(_tcpport, handler); _log.Debug("WEB server on port = " + _webport); ClientCommands.FillServerList(); _webserver = new TorpedoWeb( _webport, Global.LocalOnlyWeb, Global.UseEmbeddedWebResources, StartQue, RemoveQue, GetConnInfo, System.Net.AuthenticationSchemes.Anonymous, "api"); StartQueueProcessors(); _timer.AutoReset = true; _timer.Elapsed += timer_elapsed; _timer.Start(); }
private void DownloadAsZipFile() { SyncFile file = null; if (Global.BatchZip) { int size = 0; int mb = Global.BatchZipFilesUnderMB * Global.MB; List <SyncFile> ziplist = new List <SyncFile>(); while (_que.Count > 10) { if (_que.TryPeek(out file)) { if (file.S + size < mb && file.S < Global.SmallFileSize) // small files { _que.TryDequeue(out file); ziplist.Add(file); } else { break; } } } if (ziplist.Count > 0) { try { _downloading = true; var sf = ClientCommands.CreateZip(_conn, ziplist); if (sf != null) { string path = _conn.Path + ".ts" + _S + "Temp" + _S; LongDirectory.CreateDirectory(path); if (downloadfile(sf, path + sf.F, ClientCommands.DownloadZip)) { string zfn = path + sf.F; string fn = sf.F; if (TorpedoSync.Global.isWindows == false) { zfn = zfn.Replace("\\", "/"); } var zf = ZipStorer.Open(zfn, FileAccess.Read); foreach (var z in zf.ReadCentralDir()) { if (TorpedoSync.Global.isWindows) { fn = z.FilenameInZip.Replace("/", "\\"); } else { fn = z.FilenameInZip; } MoveExistingFileToArchive(fn); LongDirectory.CreateDirectory(LongDirectory.GetDirectoryName(_conn.Path + fn)); try { _log.Info("unzip : " + fn); //_log.Debug("unzip : " + fn); using (var fs = new FileStream(_conn.Path + fn, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { _connInfo.LastFileNameDownloaded = fn; zf.ExtractFile(z, fs); fs.Close(); } var dt = z.ModifyTime; if (z.Comment != "") { //_log.Info($"date {z.Comment}"); if (DateTime.TryParse(z.Comment, out dt) == false) { dt = z.ModifyTime; } } var dtt = dt; if (TorpedoSync.Global.isWindows) { dtt = dt.ToUniversalTime(); } LongFile.SetLastWriteTime(_conn.Path + fn, dtt); } catch (Exception ex) { _log.Error(ex); } } zf.Close(); ClientCommands.DeleteZip(_conn, sf); _log.Info("Decompress zip done : " + sf.F); LongFile.Delete(zfn); } } _downloading = false; } catch (Exception ex) { _log.Error(ex); } } } }
private void NewSync() { lock (_lock) { if (ClientCommands.isConnected(_conn.MachineName) == false) { return; } if (_conn.isConfirmed == false) { _conn.isConfirmed = ClientCommands.isConfirmed(_conn); _conn.isPaused = false; ServerCommands.SaveConnection(_conn); } if (_que.Count > 0) { return; } if (_conn.ReadyForSync()) { if (_conn.ReadOnly) { if (ClientCommands.isChanged(_conn) || _conn.isChanged) { _log.Info("syncing readonly : " + _conn.Name); var state = DeltaProcessor.GetCurrentState(_conn.Path, _conn); _connInfo.TotalFileCount = state.Files.Count; var d = ClientCommands.SyncMeReadonly(state, _conn); if (d != null) { QueueDelta(d); _conn.isChanged = false; } } } else { if (ClientCommands.isChanged(_conn) || _conn.isChanged) { _log.Info("syncing read write : " + _conn.Name); var laststate = DeltaProcessor.GetLastState(_conn); // sync read write var state = DeltaProcessor.GetCurrentState(_conn.Path, _conn); _connInfo.TotalFileCount = state.Files.Count; var delta = DeltaProcessor.ComputeDelta(state, laststate); if (laststate.Files.Count > 0 || laststate.Folders.Count > 0) { delta.FilesChanged = new List <SyncFile>(); delta.FilesAdded = new List <SyncFile>(); } var d = ClientCommands.SyncMeReadWrite(state, delta, _conn); if (d != null) { QueueDelta(d); _conn.isChanged = false; DeltaProcessor.SaveState(_conn, state); } } } } SaveQueue(); } }
public override void InitializeCommandHandler(Dictionary <string, Handler> handler, Dictionary <string, string> apihelp) { var jp = new JSONParameters { UseExtensions = false, UseFastGuid = false, EnableAnonymousTypes = true }; handler.Add("createshare", ctx => // ? sharename & path { OutPutContentType(ctx, "*.json"); string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); var s = str.Split('&'); var sh = s[0]; var path = s[1]; if (path.EndsWith("" + Path.DirectorySeparatorChar) == false) { path += Path.DirectorySeparatorChar; } var f = Global.Shares.Find(x => x.Name.ToLower() == sh.ToLower()); if (f == null) { Share ns = new Share(); ns.Name = sh; ns.Path = path; Global.Shares.Add(ns); ServerCommands.SaveConfig(); WriteResponse(ctx, 200, "true"); return; } WriteResponse(ctx, 200, "false"); }); handler.Add("connect", ctx => // ? token & path { OutPutContentType(ctx, "*.json"); string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); var ss = str.Split('&'); var c = ClientCommands.CanConnect(ss[0].Trim()); if (c != null) { var cc = ClientCommands.Connect(c.MachineName, c.Name, c.Token); if (cc != "") { c.Path = ss[1].Trim(); if (c.Path.EndsWith("" + Path.DirectorySeparatorChar) == false) { c.Path += Path.DirectorySeparatorChar; } if (ServerCommands.Connect(c) != "") { StartQue(c); WriteResponse(ctx, 200, "true"); return; } } } WriteResponse(ctx, 200, "false"); }); handler.Add("connection.confirm", ctx => // ? machinename & share & bool { OutPutContentType(ctx, "*.json"); string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); var s = str.Split('&'); var mn = s[0]; var sh = s[1]; var t = s[2]; var f = Global.ConnectionList.Find(x => x.MachineName == mn && x.Name == sh); if (f != null) { f.isConfirmed = t.ToLower() == "true" || t.ToLower() == "t"; ServerCommands.SaveConnectionList(); WriteResponse(ctx, 200, "true"); return; } WriteResponse(ctx, 200, "false"); }); handler.Add("connection.remove", ctx => // ? machinename & share { OutPutContentType(ctx, "*.json"); string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); var s = str.Split('&'); var mn = s[0]; var sh = s[1]; var f = Global.ConnectionList.Find(x => x.MachineName == mn && x.Name == sh); if (f != null) { RemoveQue(f); WriteResponse(ctx, 200, "true"); return; } WriteResponse(ctx, 200, "false"); }); handler.Add("connection.getinfo", ctx => // ? machine & share { OutPutContentType(ctx, "*.json"); string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); var s = str.Split('&'); var mn = s[0]; var sh = s[1]; var f = Global.ConnectionList.Find(x => x.MachineName == mn && x.Name == sh); if (f != null) { var o = GetConnInfo(f); var j = JSON.ToJSON(o, jp); WriteResponse(ctx, 200, j); return; } WriteResponse(ctx, 200, "{}"); }); handler.Add("connection.pauseresume", ctx => // ? machinename & share & true { OutPutContentType(ctx, "*.json"); string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); var ss = str.Split('&'); var cs = Global.ConnectionList.Find(x => x.MachineName == ss[0].Trim() && x.Name == ss[1].Trim()); if (cs != null) { cs.isPaused = ss[2].Trim() == "true" ? true : false; ServerCommands.SaveConnectionList(); WriteResponse(ctx, 200, "true"); return; } WriteResponse(ctx, 200, "false"); }); handler.Add("share.pauseresume", ctx => // ? share & true { OutPutContentType(ctx, "*.json"); string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); var ss = str.Split('&'); var s = Global.Shares.Find(x => x.Name == ss[0].Trim()); if (s != null) { foreach (var cs in Global.ConnectionList.FindAll(x => x.Name == ss[0].Trim())) { cs.isPaused = ss[1].Trim() == "true" ? true : false; } ServerCommands.SaveConnectionList(); WriteResponse(ctx, 200, "true"); return; } WriteResponse(ctx, 200, "false"); }); handler.Add("share.add", ctx => { OutPutContentType(ctx, "*.json"); string text = null; using (var reader = new StreamReader(ctx.Request.InputStream, Encoding.UTF8)) { text = reader.ReadToEnd(); } var o = JSON.ToObject <Share>(text); var s = Global.Shares.Find(x => x.Name == o.Name); if (s == null) { if (o.Path.EndsWith("" + Path.DirectorySeparatorChar) == false) { o.Path += Path.DirectorySeparatorChar; } Global.Shares.Add(o); ServerCommands.SaveConfig(); WriteResponse(ctx, 200, "true"); return; } WriteResponse(ctx, 200, "false"); }); handler.Add("share.remove", ctx => // ? sharename { OutPutContentType(ctx, "*.json"); string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); var sh = Global.Shares.Find(x => x.Name == str.Trim()); if (sh != null) { Global.Shares.Remove(sh); // remove connections also foreach (var c in Global.ConnectionList.FindAll(x => x.Name == str.Trim())) { RemoveQue(c); } ServerCommands.SaveConfig(); WriteResponse(ctx, 200, "true"); return; } WriteResponse(ctx, 200, "false"); }); handler.Add("getshares", ctx => { OutPutContentType(ctx, "*.json"); WriteResponse(ctx, 200, fastJSON.JSON.ToJSON(Global.Shares, jp)); }); handler.Add("getconnections", ctx => { OutPutContentType(ctx, "*.json"); WriteResponse(ctx, 200, fastJSON.JSON.ToJSON(Global.ConnectionList, jp)); }); handler.Add("pausets", ctx => // ? 0 or 1 { string str = ctx.Request.Url.GetComponents(UriComponents.Query, UriFormat.Unescaped); if (str == "1") { Global.PauseAll = true; } else { Global.PauseAll = false; } OutPutContentType(ctx, ".json"); WriteResponse(ctx, 200, "true"); }); handler.Add("getlogs", ctx => { OutPutContentType(ctx, ".json"); WriteResponse(ctx, 200, JSON.ToJSON(LogManager.GetLastLogs(), jp)); }); handler.Add("getconfigs", ctx => { var o = new { Version = FileVersionInfo.GetVersionInfo(this.GetType().Assembly.Location).FileVersion, Globals = new Global(), Global.FreeMemoryTimerMin, Global.SaveQueueEvery_X_Minute, Global.PauseAll }; OutPutContentType(ctx, ".json"); WriteResponse(ctx, 200, JSON.ToJSON(o, jp)); }); }