说明

对点之间传输文件,操作基本完全一致,仅当两个TouchRpcClient相互传输文件时,需要多增加一个ID参数而已,所以下列示例仅演示由TcpTouchRpcClientTcpTouchRpcService(实际上是TcpTouchRpcSocketClient)的操作。

对点之间可以任意pull(拉取)、push(推送)文件。接收对点可以订阅FileTransferingFileTransfered事件,来获取相关信息,发起对点直接通过传输控制器或返回值获取传输信息。

值得注意的是,FileTransfered事件的触发并不意味着完成传输,具体结果还要通过Result属性值进行判断。

Pull文件

由TouchClient向TouchService发起Pull请求时,相当于由客户端从服务器下载文件。

响应流程:

  1. 发起Pull请求。
  2. 接收对点触发FileTransfering事件。
  3. 返回文件信息,然后检验是否续传等,然后开始接收。
  4. 接收完成或异常。
  5. 接收对点触发FileTransfered事件。
  6. 发起对点函数返回,控制器状态改变。

具体请求:

请求参数 参数属性 请求参数属性描述
FileRequest 参数描述 FileRequest是请求信息类,主要向请求方描述请求详情。
Path Path属性为请求文件在接收对点的路径,当该值为相对路径时,会与接收对点的RootPath组合路径。当为绝对路径时,则会直接访问路径文件(此时如果不在对点设置条件,则有可能会有文件安全隐患,设置详情链接
SavePath SavePath属性是发起对点本地的保存路径。
Flags 可通过叠加位域的形式,尝试断点续传。
FileOperator 参数描述 FileOperator是本次传输的请求操作器,主要用于获取传输进度、速度、状态以及取消传输等操作。接收方的控制器从BeforeFileTransfer事件的参数e中获得。
CompletedLength 已完成流长度。
Speed 函数 从上次获取到此次获得的速度。一般请每秒钟调用一次获取速度值。
PackageSize 流分包尺寸。
Progress 传输进度,范围0-1。
Result 获取传输状态以及状态信息。当ResultCode为Default时,意味着传输正在进行。
Token CancellationToken类型的可取消令箭。
Metadata 参数描述 string类型的键值对,用于和接收方交互数据。

示例代码:

【服务器】

  1. static void Main(string[] args)
  2. {
  3. TcpTouchRpcService service = GetService();
  4. service.Logger.Message("服务器成功启动");
  5. Console.ReadKey();
  6. }
  7. static TcpTouchRpcService GetService()
  8. {
  9. var service = new RRQMConfig()//配置
  10. .SetListenIPHosts(new IPHost[] { new IPHost(7789) })
  11. .SetMaxCount(10000)
  12. .SetThreadCount(100)
  13. .SetSingletonLogger(new LoggerGroup(new ConsoleLogger(), new FileLogger()))
  14. .SetVerifyToken("File")//连接验证口令。
  15. .BuildWithTcpTouchRpcService();//此处build相当于new TcpTouchRpcService,然后Setup,然后Start。
  16. service.Handshaked += (client, e) =>
  17. {
  18. client.Logger.Message($"有客户端成功验证,ID={client.ID}");
  19. };
  20. service.Disconnected += (client, e) =>
  21. {
  22. client.Logger.Message($"有客户端断开,ID={client.ID}");
  23. };
  24. service.FileTransfering += (client, e) =>
  25. {
  26. //有可能是上传,也有可能是下载
  27. client.Logger.Message($"有客户端请求传输文件,ID={client.ID},请求类型={e.TransferType},请求文件名={e.FileRequest.Path}");
  28. };
  29. service.FileTransfered += (client, e) =>
  30. {
  31. //传输结束,但是不一定成功,需要从e.Result判断状态。
  32. client.Logger.Message($"客户端传输文件结束,ID={client.ID},请求类型={e.TransferType},文件名={e.FileRequest.Path},请求状态={e.Result}");
  33. };
  34. return service;
  35. }

【客户端】

  1. static void Main(string[] args)
  2. {
  3. TcpTouchRpcClient client = new RRQMConfig()
  4. .SetRemoteIPHost("127.0.0.1:7789")
  5. .SetVerifyToken("File")
  6. .BuildWithTcpTouchRpcClient();
  7. client.FileTransfering += (client, e) =>
  8. {
  9. //有可能是上传,也有可能是下载
  10. client.Logger.Message($"服务器请求传输文件,ID={client.ID},请求类型={e.TransferType},文件名={e.FileInfo.FileName}");
  11. };
  12. client.FileTransfered += (client, e) =>
  13. {
  14. //传输结束,但是不一定成功,需要从e.Result判断状态。
  15. client.Logger.Message($"服务器传输文件结束,ID={client.ID},请求类型={e.TransferType},文件名={e.FileInfo.FileName},请求状态={e.Result}");
  16. };
  17. client.Logger.Message("连接成功");
  18. //第一个参数是请求路径,第二个是保存路径。
  19. FileRequest fileRequest = new FileRequest(@"D:\System\Windows.iso", $@"Windows.iso");
  20. fileRequest.Flags = TransferFlags.BreakpointResume;//尝试断点续传,使用断点续传时,会验证MD5值
  21. FileOperator fileOperator = new FileOperator();//实例化本次传输的控制器,用于获取传输进度、速度、状态等。
  22. fileOperator.Timeout = 60 * 1000;//当传输大文件,且启用断点续传时,服务器可能会先计算MD5,而延时响应,所以需要设置超时时间。
  23. //此处的作用相当于Timer,定时每秒输出当前的传输进度和速度。
  24. LoopAction loopAction = LoopAction.CreateLoopAction(-1, 1000, (loop) =>
  25. {
  26. if (fileOperator.Result.ResultCode != ResultCode.Default)
  27. {
  28. loop.Dispose();
  29. }
  30. client.Logger.Message($"进度:{fileOperator.Progress},速度:{fileOperator.Speed()}");
  31. });
  32. loopAction.RunAsync();
  33. Metadata metadata = new Metadata();//传递到服务器的元数据
  34. metadata.Add("1", "1");
  35. metadata.Add("2", "2");
  36. //此方法会阻塞,直到传输结束,也可以使用PullFileAsync
  37. IResult result = client.PullFile(fileRequest, fileOperator, metadata);
  38. client.Logger.Message(result.ToString());
  39. Console.ReadKey();
  40. }

Push文件

Push和Pull操作一致,仅需要在最后调用PushFile即可。