说明
对点之间传输文件,操作基本完全一致,仅当两个TouchRpcClient相互传输文件时,需要多增加一个ID参数而已,所以下列示例仅演示由TcpTouchRpcClient到TcpTouchRpcService(实际上是TcpTouchRpcSocketClient)的操作。
对点之间可以任意pull(拉取)、push(推送)文件。接收对点可以订阅FileTransfering和FileTransfered事件,来获取相关信息,发起对点直接通过传输控制器或返回值获取传输信息。
值得注意的是,FileTransfered事件的触发并不意味着完成传输,具体结果还要通过Result属性值进行判断。
Pull文件
由TouchClient向TouchService发起Pull请求时,相当于由客户端从服务器下载文件。
响应流程:
- 发起Pull请求。
 - 接收对点触发FileTransfering事件。
 - 返回文件信息,然后检验是否续传等,然后开始接收。
 - 接收完成或异常。
 - 接收对点触发FileTransfered事件。
 - 发起对点函数返回,控制器状态改变。
 
具体请求:
| 请求参数 | 参数属性 | 请求参数属性描述 | 
|---|---|---|
| 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类型的键值对,用于和接收方交互数据。 | 
示例代码:
【服务器】
static void Main(string[] args){TcpTouchRpcService service = GetService();service.Logger.Message("服务器成功启动");Console.ReadKey();}static TcpTouchRpcService GetService(){var service = new RRQMConfig()//配置.SetListenIPHosts(new IPHost[] { new IPHost(7789) }).SetMaxCount(10000).SetThreadCount(100).SetSingletonLogger(new LoggerGroup(new ConsoleLogger(), new FileLogger())).SetVerifyToken("File")//连接验证口令。.BuildWithTcpTouchRpcService();//此处build相当于new TcpTouchRpcService,然后Setup,然后Start。service.Handshaked += (client, e) =>{client.Logger.Message($"有客户端成功验证,ID={client.ID}");};service.Disconnected += (client, e) =>{client.Logger.Message($"有客户端断开,ID={client.ID}");};service.FileTransfering += (client, e) =>{//有可能是上传,也有可能是下载client.Logger.Message($"有客户端请求传输文件,ID={client.ID},请求类型={e.TransferType},请求文件名={e.FileRequest.Path}");};service.FileTransfered += (client, e) =>{//传输结束,但是不一定成功,需要从e.Result判断状态。client.Logger.Message($"客户端传输文件结束,ID={client.ID},请求类型={e.TransferType},文件名={e.FileRequest.Path},请求状态={e.Result}");};return service;}
【客户端】
static void Main(string[] args){TcpTouchRpcClient client = new RRQMConfig().SetRemoteIPHost("127.0.0.1:7789").SetVerifyToken("File").BuildWithTcpTouchRpcClient();client.FileTransfering += (client, e) =>{//有可能是上传,也有可能是下载client.Logger.Message($"服务器请求传输文件,ID={client.ID},请求类型={e.TransferType},文件名={e.FileInfo.FileName}");};client.FileTransfered += (client, e) =>{//传输结束,但是不一定成功,需要从e.Result判断状态。client.Logger.Message($"服务器传输文件结束,ID={client.ID},请求类型={e.TransferType},文件名={e.FileInfo.FileName},请求状态={e.Result}");};client.Logger.Message("连接成功");//第一个参数是请求路径,第二个是保存路径。FileRequest fileRequest = new FileRequest(@"D:\System\Windows.iso", $@"Windows.iso");fileRequest.Flags = TransferFlags.BreakpointResume;//尝试断点续传,使用断点续传时,会验证MD5值FileOperator fileOperator = new FileOperator();//实例化本次传输的控制器,用于获取传输进度、速度、状态等。fileOperator.Timeout = 60 * 1000;//当传输大文件,且启用断点续传时,服务器可能会先计算MD5,而延时响应,所以需要设置超时时间。//此处的作用相当于Timer,定时每秒输出当前的传输进度和速度。LoopAction loopAction = LoopAction.CreateLoopAction(-1, 1000, (loop) =>{if (fileOperator.Result.ResultCode != ResultCode.Default){loop.Dispose();}client.Logger.Message($"进度:{fileOperator.Progress},速度:{fileOperator.Speed()}");});loopAction.RunAsync();Metadata metadata = new Metadata();//传递到服务器的元数据metadata.Add("1", "1");metadata.Add("2", "2");//此方法会阻塞,直到传输结束,也可以使用PullFileAsyncIResult result = client.PullFile(fileRequest, fileOperator, metadata);client.Logger.Message(result.ToString());Console.ReadKey();}
Push文件
Push和Pull操作一致,仅需要在最后调用PushFile即可。
