pull/1/head
a.bozhenov 6 years ago
parent 58c08dc4ab
commit 8f6e333540

@ -33,7 +33,7 @@ namespace ZeroLevel.Services.Network.FileTransfer
{ {
var fragment = new FileFrame var fragment = new FileFrame
{ {
UploadTaskId = _startInfo.FileUploadTaskId, UploadFileTaskId = _startInfo.UploadFileTaskId,
Offset = offset * CHUNK_SIZE, Offset = offset * CHUNK_SIZE,
Payload = new byte[bytesRead] Payload = new byte[bytesRead]
}; };
@ -47,7 +47,7 @@ namespace ZeroLevel.Services.Network.FileTransfer
public FileEndFrame GetCompleteInfo() public FileEndFrame GetCompleteInfo()
{ {
return new FileEndFrame { FileUploadTaskId = _startInfo.FileUploadTaskId }; return new FileEndFrame { UploadFileTaskId = _startInfo.UploadFileTaskId };
} }
} }
} }

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using ZeroLevel.Models;
using ZeroLevel.Services.Network.FileTransfer.Model; using ZeroLevel.Services.Network.FileTransfer.Model;
namespace ZeroLevel.Services.Network.FileTransfer namespace ZeroLevel.Services.Network.FileTransfer
@ -40,10 +41,12 @@ namespace ZeroLevel.Services.Network.FileTransfer
private string _basePath; private string _basePath;
private string _disk_prefix; private string _disk_prefix;
private readonly Dictionary<int, FileWriter> _incoming = new Dictionary<int, FileWriter>(); private readonly Dictionary<long, FileWriter> _incoming = new Dictionary<long, FileWriter>();
private readonly object _locker = new object(); private readonly object _locker = new object();
private long _cleanErrorsTaskId; private long _cleanErrorsTaskId;
private readonly Dictionary<long, object> _incomingLocks = new Dictionary<long, object>();
public FileReceiver(string path, string disk_prefix = "DRIVE_") public FileReceiver(string path, string disk_prefix = "DRIVE_")
{ {
_disk_prefix = disk_prefix; _disk_prefix = disk_prefix;
@ -68,37 +71,65 @@ namespace ZeroLevel.Services.Network.FileTransfer
public void Incoming(FileStartFrame info, string clientFolderName) public void Incoming(FileStartFrame info, string clientFolderName)
{ {
if (false == _incoming.ContainsKey(info.FileUploadTaskId)) try
{ {
lock (_locker) if (false == _incoming.ContainsKey(info.UploadFileTaskId))
{ {
if (false == _incoming.ContainsKey(info.FileUploadTaskId)) lock (_locker)
{ {
string path = BuildFilePath(clientFolderName, info.FilePath); if (false == _incoming.ContainsKey(info.UploadFileTaskId))
_incoming.Add(info.FileUploadTaskId, new FileWriter(path)); {
_incomingLocks.Add(info.UploadFileTaskId, new object());
lock (_incomingLocks[info.UploadFileTaskId])
{
string path = BuildFilePath(clientFolderName, info.FilePath);
_incoming.Add(info.UploadFileTaskId, new FileWriter(path));
}
}
} }
} }
} }
catch (Exception ex)
{
Log.Error("[FileReceiver]", ex);
}
} }
public void Incoming(FileFrame chunk) public void Incoming(FileFrame chunk)
{ {
FileWriter stream; try
if (_incoming.TryGetValue(chunk.UploadTaskId, out stream))
{ {
stream.Write(chunk.Offset, chunk.Payload); FileWriter stream;
if (_incoming.TryGetValue(chunk.UploadFileTaskId, out stream))
{
lock (_incomingLocks[chunk.UploadFileTaskId])
{
stream.Write(chunk.Offset, chunk.Payload);
}
}
}
catch (Exception ex)
{
Log.Error("[FileReceiver]", ex);
} }
} }
public void Incoming(FileEndFrame info) public void Incoming(FileEndFrame info)
{ {
lock (_locker) try
{
lock (_locker)
{
Remove(info.UploadFileTaskId);
}
}
catch (Exception ex)
{ {
Remove(info.FileUploadTaskId); Log.Error("[FileReceiver]", ex);
} }
} }
private void Remove(int uploadTaskId) private void Remove(long uploadTaskId)
{ {
FileWriter stream; FileWriter stream;
if (_incoming.TryGetValue(uploadTaskId, out stream)) if (_incoming.TryGetValue(uploadTaskId, out stream))

@ -1,5 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using ZeroLevel.Models;
using ZeroLevel.Network; using ZeroLevel.Network;
using ZeroLevel.Services.Network.FileTransfer.Model; using ZeroLevel.Services.Network.FileTransfer.Model;

@ -3,18 +3,19 @@
namespace ZeroLevel.Services.Network.FileTransfer.Model namespace ZeroLevel.Services.Network.FileTransfer.Model
{ {
public sealed class FileEndFrame public sealed class FileEndFrame
: IBinarySerializable : IBinarySerializable, IFileTransferInfo
{ {
public int FileUploadTaskId; public FileTransferInfoType TransferInfoType => FileTransferInfoType.End;
public long UploadFileTaskId { get; set; }
public void Serialize(IBinaryWriter writer) public void Serialize(IBinaryWriter writer)
{ {
writer.WriteInt32(this.FileUploadTaskId); writer.WriteLong(this.UploadFileTaskId);
} }
public void Deserialize(IBinaryReader reader) public void Deserialize(IBinaryReader reader)
{ {
this.FileUploadTaskId = reader.ReadInt32(); this.UploadFileTaskId = reader.ReadLong();
} }
} }
} }

@ -3,22 +3,24 @@
namespace ZeroLevel.Services.Network.FileTransfer.Model namespace ZeroLevel.Services.Network.FileTransfer.Model
{ {
public sealed class FileFrame : public sealed class FileFrame :
IBinarySerializable IBinarySerializable, IFileTransferInfo
{ {
public int UploadTaskId { get; set; } public FileTransferInfoType TransferInfoType => FileTransferInfoType.Frame;
public long UploadFileTaskId { get; set; }
public long Offset { get; set; } public long Offset { get; set; }
public byte[] Payload { get; set; } public byte[] Payload { get; set; }
public void Serialize(IBinaryWriter writer) public void Serialize(IBinaryWriter writer)
{ {
writer.WriteInt32(this.UploadTaskId); writer.WriteLong(this.UploadFileTaskId);
writer.WriteLong(this.Offset); writer.WriteLong(this.Offset);
writer.WriteBytes(this.Payload); writer.WriteBytes(this.Payload);
} }
public void Deserialize(IBinaryReader reader) public void Deserialize(IBinaryReader reader)
{ {
this.UploadTaskId = reader.ReadInt32(); this.UploadFileTaskId = reader.ReadLong();
this.Offset = reader.ReadLong(); this.Offset = reader.ReadLong();
this.Payload = reader.ReadBytes(); this.Payload = reader.ReadBytes();
} }

@ -4,24 +4,26 @@ using ZeroLevel.Services.Serialization;
namespace ZeroLevel.Services.Network.FileTransfer.Model namespace ZeroLevel.Services.Network.FileTransfer.Model
{ {
public sealed class FileStartFrame public sealed class FileStartFrame
: IBinarySerializable : IBinarySerializable, IFileTransferInfo
{ {
private static int _uploadTaskIdCounter = 0; private static long _uploadTaskIdCounter = 0;
public int FileUploadTaskId; public FileTransferInfoType TransferInfoType => FileTransferInfoType.Start;
public long UploadFileTaskId { get; set; }
public string FilePath; public string FilePath;
public long Size; public long Size;
public void Serialize(IBinaryWriter writer) public void Serialize(IBinaryWriter writer)
{ {
writer.WriteInt32(this.FileUploadTaskId); writer.WriteLong(this.UploadFileTaskId);
writer.WriteString(this.FilePath); writer.WriteString(this.FilePath);
writer.WriteLong(this.Size); writer.WriteLong(this.Size);
} }
public void Deserialize(IBinaryReader reader) public void Deserialize(IBinaryReader reader)
{ {
this.FileUploadTaskId = reader.ReadInt32(); this.UploadFileTaskId = reader.ReadLong();
this.FilePath = reader.ReadString(); this.FilePath = reader.ReadString();
this.Size = reader.ReadLong(); this.Size = reader.ReadLong();
} }
@ -32,7 +34,7 @@ namespace ZeroLevel.Services.Network.FileTransfer.Model
return new FileStartFrame return new FileStartFrame
{ {
FilePath = fi.FullName, FilePath = fi.FullName,
FileUploadTaskId = Interlocked.Increment(ref _uploadTaskIdCounter), UploadFileTaskId = Interlocked.Increment(ref _uploadTaskIdCounter),
Size = fi.Length Size = fi.Length
}; };
} }

@ -0,0 +1,15 @@
namespace ZeroLevel.Services.Network.FileTransfer.Model
{
public enum FileTransferInfoType
{
Start,
Frame,
End
}
public interface IFileTransferInfo
{
long UploadFileTaskId { get; }
FileTransferInfoType TransferInfoType { get; }
}
}
Loading…
Cancel
Save

Powered by TurnKey Linux.