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("通道写入结束");
|
||
}
|
||
}
|
||
}
|
||
}
|