public async Task SendFileAsync(LinkProfile profile, string filePath, FileSenderHandler handler) { if (profile == null || handler == null) { throw new ArgumentNullException(); } var fileInfo = new FileInfo(filePath); if (!fileInfo.Exists) { throw new FileNotFoundException("File not found!", filePath); } var length = fileInfo.Length; var packet = new { name = fileInfo.Name, length }; using (var tcp = await Network.ConnectAsync("link.share.file", packet, profile.GetTcpEndPoint(), CancellationToken)) { var stream = tcp.GetStream(); var result = await stream.ReadBlockWithHeaderAsync(Environment.TcpBufferLimits, CancellationToken); var data = Generator.AsToken(result); if (data["status"].As <string>() != "wait") { throw new LinkException(LinkError.InvalidData); } using (var sender = new FileSender(this, profile, stream, fileInfo.FullName, length)) { await UpdateUIAsync(() => handler.Invoke(sender)); await sender.LoopAsync(); } } }
private async Task UpdateImageAsync(LinkProfile profile) { var cache = client.Cache; var imageHash = profile.RemoteImageHash; try { if (cache.Exists(imageHash, out var fullpath) == false) { fullpath = await cache.RequestAsync(imageHash, profile.GetTcpEndPoint(), client.CancellationToken); } profile.ImageHash = imageHash; await client.UpdateUIAsync(() => profile.ImagePath = fullpath); } finally { Op.Lock(locker, () => pending.Remove(profile.Id)); } }
internal async Task SendAsync(LinkProfile profile, Message message, string path, object packetData) { message.Status = MessageStatus.Pending; profile.MessageCollection.Add(message); bool handled(Token token) { var status = token["status"].As <string>(); var flag = status == "ok" ? MessageStatus.Success : status == "refused" ? MessageStatus.Refused : default; if (flag == default) { return(false); } message.Status = flag; return(true); } for (var i = 0; i < 2; i++) { try { var result = await RequestAsync(path, packetData, profile.GetUdpEndPoint(), environment.UdpTimeout); if (handled(result.Data)) { return; } } catch (LinkException ex) when(ex.ErrorCode == LinkError.UdpPacketTooLarge) { break; } catch (TimeoutException) { continue; } } var tcp = default(TcpClient); var stream = default(NetworkStream); var cancel = new CancellationTokenSource(); try { tcp = await ConnectAsync(path, packetData, profile.GetTcpEndPoint(), cancel.Token); stream = tcp.GetStream(); var buffer = await stream.ReadBlockWithHeaderAsync(environment.TcpBufferLimits, cancel.Token).TimeoutAfter(environment.TcpTimeout); var token = generator.AsToken(buffer); if (handled(token)) { return; } } catch (Exception) { // ignore } finally { cancel.Cancel(); cancel.Dispose(); stream?.Dispose(); tcp?.Dispose(); } message.Status = MessageStatus.Aborted; }