189 lines
6.8 KiB
C#
189 lines
6.8 KiB
C#
|
using Cysharp.Threading.Tasks;
|
|||
|
using System.ComponentModel;
|
|||
|
using System.ComponentModel.Design;
|
|||
|
using System.Text;
|
|||
|
using System.Text.Json;
|
|||
|
using TouchSocket.Core;
|
|||
|
using TouchSocket.Dmtp;
|
|||
|
using TouchSocket.Dmtp.FileTransfer;
|
|||
|
using TouchSocket.Dmtp.Rpc;
|
|||
|
using TouchSocket.Rpc;
|
|||
|
using TouchSocket.Sockets;
|
|||
|
|
|||
|
namespace FileSend
|
|||
|
{
|
|||
|
public class ZClient
|
|||
|
{
|
|||
|
public TcpDmtpClient client;
|
|||
|
public const string rootCPath = "E:\\zRoot\\C";
|
|||
|
public const string rootSPath = "E:\\zRoot\\S";
|
|||
|
public ZClient()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public async UniTask StartAsync(short port = 7708)
|
|||
|
{
|
|||
|
// 0
|
|||
|
var a = new TcpClient();
|
|||
|
|
|||
|
|
|||
|
// 1
|
|||
|
client = await new TouchSocketConfig()
|
|||
|
.SetRemoteIPHost("127.0.0.1:7789")
|
|||
|
.SetListenIPHosts(port)
|
|||
|
.SetDmtpOption(new DmtpOption()
|
|||
|
{
|
|||
|
VerifyToken = "Channel"
|
|||
|
})
|
|||
|
.SetSendTimeout(0)
|
|||
|
.ConfigureContainer(a =>
|
|||
|
{
|
|||
|
a.AddConsoleLogger();
|
|||
|
})
|
|||
|
.ConfigurePlugins(a =>
|
|||
|
{
|
|||
|
a.UseDmtpFileTransfer()//必须添加文件传输插件
|
|||
|
.SetRootPath(rootCPath)//设置RootPath
|
|||
|
.SetMaxSmallFileLength(1024 * 1024);//设置小文件的最大限制长度
|
|||
|
a.Add<MyPlugin>();
|
|||
|
a.Add<ConnectAndMsgPlugin>();
|
|||
|
})
|
|||
|
.BuildClientAsync<TcpDmtpClient>();//相当于创建客户端并配置,连接
|
|||
|
|
|||
|
client.Logger.Info("连接成功");
|
|||
|
|
|||
|
//string str = "{\"header\":\"your_header_value\",\"body\":\"your_body_content\"}";
|
|||
|
//byte[] bytes = Encoding.UTF8.GetBytes(str);
|
|||
|
//await client.SendAsync(1, bytes);
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public async UniTask CloseAsync()
|
|||
|
{
|
|||
|
|
|||
|
await client.CloseAsync();
|
|||
|
client.Dispose();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 客户端向服务器请求文件
|
|||
|
/// </summary>
|
|||
|
public void C2S_RequestFile()
|
|||
|
{
|
|||
|
var filePath = "ClientPullFileFromService.Test";
|
|||
|
var saveFilePath = "SaveClientPullFileFromService.Test";
|
|||
|
|
|||
|
var metadata = new Metadata();//传递到服务器的元数据
|
|||
|
metadata.Add("1", "1");
|
|||
|
metadata.Add("2", "2");
|
|||
|
|
|||
|
var fileOperator = new FileOperator()//实例化本次传输的控制器,用于获取传输进度、速度、状态等。
|
|||
|
{
|
|||
|
SavePath = saveFilePath,//客户端本地保存路径
|
|||
|
ResourcePath = filePath,//请求文件的资源路径
|
|||
|
Metadata = metadata,//传递到服务器的元数据
|
|||
|
Timeout = TimeSpan.FromSeconds(60),//传输超时时长
|
|||
|
TryCount = 10,//当遇到失败时,尝试次数
|
|||
|
FileSectionSize = 1024 * 512//分包大小,当网络较差时,应该适当减小该值
|
|||
|
};
|
|||
|
|
|||
|
fileOperator.MaxSpeed = 1024 * 1024 * 20;//设置最大限速为20Mb。
|
|||
|
|
|||
|
//此处的作用相当于Timer,定时每秒输出当前的传输进度和速度。
|
|||
|
var loopAction = LoopAction.CreateLoopAction(-1, 1000, (loop) =>
|
|||
|
{
|
|||
|
if (fileOperator.Result.ResultCode != ResultCode.Default)
|
|||
|
{
|
|||
|
loop.Dispose();
|
|||
|
}
|
|||
|
client.Logger.Info($"进度:{fileOperator.Progress},速度:{fileOperator.Speed()}");
|
|||
|
});
|
|||
|
|
|||
|
loopAction.RunAsync();
|
|||
|
|
|||
|
//此方法会阻塞,直到传输结束,也可以使用PullFileAsync
|
|||
|
IResult result = client.GetDmtpFileTransferActor().PullFile(fileOperator);
|
|||
|
}
|
|||
|
|
|||
|
public void C2S_ResposeFolder(string folderPath)
|
|||
|
{
|
|||
|
DirectoryInfo directoryInfo = new DirectoryInfo(rootCPath);
|
|||
|
FileInfo[] fileInfos = directoryInfo.GetFiles();
|
|||
|
foreach (FileInfo fileInfo in fileInfos)
|
|||
|
{
|
|||
|
C2S_ResposeFile(fileInfo);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 客户端向服务器推送文件
|
|||
|
/// </summary>
|
|||
|
public void C2S_ResposeFile(FileInfo fileInfo)//
|
|||
|
{
|
|||
|
var saveFilePath = $"{rootSPath}\\{fileInfo.Name}";
|
|||
|
|
|||
|
var metadata = new Metadata();//传递到服务器的元数据
|
|||
|
metadata.Add("1", "1");
|
|||
|
metadata.Add("2", "2");
|
|||
|
|
|||
|
var fileOperator = new FileOperator()//实例化本次传输的控制器,用于获取传输进度、速度、状态等。
|
|||
|
{
|
|||
|
SavePath = saveFilePath,//服务器本地保存路径
|
|||
|
ResourcePath = fileInfo.FullName,//客户端本地即将上传文件的资源路径
|
|||
|
Metadata = metadata,//传递到服务器的元数据
|
|||
|
Timeout = TimeSpan.FromSeconds(60),//传输超时时长
|
|||
|
TryCount = 10,//当遇到失败时,尝试次数
|
|||
|
FileSectionSize = 1024 * 512//分包大小,当网络较差时,应该适当减小该值
|
|||
|
};
|
|||
|
|
|||
|
fileOperator.MaxSpeed = 1024 * 1024 * 1024;//设置最大限速为1Gb。
|
|||
|
|
|||
|
//此处的作用相当于Timer,定时每秒输出当前的传输进度和速度。
|
|||
|
var loopAction = LoopAction.CreateLoopAction(-1, 1000, (loop) =>
|
|||
|
{
|
|||
|
if (fileOperator.Result.ResultCode != ResultCode.Default)
|
|||
|
{
|
|||
|
loop.Dispose();
|
|||
|
}
|
|||
|
client.Logger.Info($"进度:{fileOperator.Progress},速度:{fileOperator.Speed()}");
|
|||
|
});
|
|||
|
|
|||
|
loopAction.RunAsync();
|
|||
|
|
|||
|
//此方法会阻塞,直到传输结束,也可以使用PushFileAsync
|
|||
|
IResult result = client.GetDmtpFileTransferActor().PushFile(fileOperator);
|
|||
|
while (!fileOperator.IsEnd && !result.IsSuccess)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
client.Logger.Info($"{fileInfo.Name} 上传完成!");
|
|||
|
}
|
|||
|
|
|||
|
public async UniTask Send()
|
|||
|
{
|
|||
|
|
|||
|
var count = 1024 * 1;//测试1Gb数据
|
|||
|
|
|||
|
//1.创建通道,同时支持通道路由和元数据传递
|
|||
|
using (var channel = client.CreateChannel())
|
|||
|
{
|
|||
|
//设置限速
|
|||
|
//channel.MaxSpeed = 1024 * 1024;
|
|||
|
|
|||
|
ConsoleLogger.Default.Info($"通道创建成功,即将写入{count}Mb数据");
|
|||
|
var bytes = new byte[1024 * 1024];
|
|||
|
for (var i = 0; i < count; i++)
|
|||
|
{
|
|||
|
//2.持续写入数据
|
|||
|
await channel.WriteAsync(bytes);
|
|||
|
}
|
|||
|
|
|||
|
//3.在写入完成后调用终止指令。例如:Complete、Cancel、HoldOn、Dispose等
|
|||
|
await channel.CompleteAsync("我完成了");
|
|||
|
ConsoleLogger.Default.Info("通道写入结束");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|