通过WCF传输文件

时间:2012-03-17 15:44:52

标签: wcf file-transfer

我是WCF的新手,所以如果你能尽可能详细地回答我真的很感激:)我有一个WCF服务库和一个WPF应用程序(谁是客户端)。想要的结果是一个应用程序,它将在连接的客户端之间实现文件共享。我使用一种方法构建一个真正基本WCF服务库:

[ServiceContract]
public interface IFileService
{
    [OperationContract]
    byte[] GetFile(string fullPath);
}

并实现了这样的方法:

public class FileService : IFileService
{
    public byte[] GetFile(string fullPath)
    {
        return System.IO.File.ReadAllBytes(fullPath);
    }
}

这是WPF客户端项目中的App.config文件:

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IFileService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Message">
                    <transport clientCredentialType="Windows" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:9355/TankusFileTransferService/Service/"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IFileService"
            contract="TankusFileService.IFileService" name="WSHttpBinding_IFileService">
            <identity>
                <userPrincipalName value="GIL-LAPTOP\Gil" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

这是主窗口WPF应用程序中的代码:

public partial class MainWindow : Window
{

    ServiceHost sh;
    TankusFileService.FileServiceClient fsc;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void btn_Connect_Click(object sender, RoutedEventArgs e)
    {
        Uri uri = new Uri("http://127.0.0.1:1234/");
        sh = new ServiceHost(typeof(TankusFileTransferService.FileService), uri);
        sh.Open();
        lbl_Listener.Content = sh.Description.Endpoints[0].Address.ToString();
    }

    private void btn_Disconnect_Click(object sender, RoutedEventArgs e)
    {
        sh.Close();
        lbl_Listener.Content = string.Empty;
    }

    private void btn_GetFile_Click(object sender, RoutedEventArgs e)
    {
        fsc = new TankusFileService.FileServiceClient();
        fsc.Endpoint.Address = new EndpointAddress("http://127.0.0.1:1234/");
        fsc.Endpoint.Binding = new BasicHttpBinding();
        byte[] bytes = fsc.GetFile(@"D:\mika.txt");
        System.IO.File.WriteAllBytes(@"D:\mika_new.txt", bytes);
    }
}

按下连接按钮并初始化ServiceHost对象以便它可以开始收听我按下getFile按钮。当调用GetFile()函数时,它会抛出TimeoutException。为什么是这样?我是否正在以正确的方式完成我想要的申请?谢谢:)

2 个答案:

答案 0 :(得分:2)

您可能会收到 TimeoutException ,因为发送文件的时间比服务允许的时间长。

在服务器和客户端的配置文件中,请确保增加 receiveTimeout sendTimeout

您可能还会遇到大小限制,因为WCF会配置最大邮件大小,并且该文件将被视为邮件的一部分。查看 maxBufferPoolSize maxReceivedMessageSize 以及下面的成员

<readerQuotas 
     maxDepth="32" maxStringContentLength="8192" 
     maxArrayLength="16384" maxBytesPerRead="4096" 
     maxNameTableCharCount="16384" />

答案 1 :(得分:0)

同步Web服务请求不是传输文件的最佳方式。即使它有效,如果您需要扩展端点以处理并发请求,您将很快遇到麻烦。通过将文件上载到服务端点,您可能会损害端点的可用性。

更好的解决方案 - WPF应用程序将文件流写入磁盘(或数据库,ftp服务器或队列),然后向服务器发送快速单向命令消息,然后进入并抓取文件。

这样可扩展性更高,并且可用性类型异常少得多。

<强>更新

根据我的经验,当您将大型文件上传到Web服务端点时,您可能会遇到可用性问题,尤其是在存在任何重大并发性的情况下。如果你知道你的上限是什么(文件大小,并发连接等),你可以计划这些东西,你可以将其形式化为服务水平协议,但是你想要做的事情的性质(对等 - 根据定义,这是一个不稳定的环境,这样的规划很困难。

然而,那就是说,你的要求是P2P的事实意味着理想情况下不应该是一个集中的环境来实现我建议的存储和检索消息模式的类型。

Windows Azure blob存储是如何实现这一目标的一个示例。