我编写了一个需要传输大文件的WCF服务,所以我使用流媒体,但另一方面我需要进行用户名特定的初始化。
问题是每次获取用户名并执行初始化都非常昂贵。如果我可以打开会话,我可以将初始化数据保存在服务实例中的本地变量中。
有没有办法在netTcpBinding中打开流媒体和会话?
答案 0 :(得分:4)
大文件传输确实是wcf中的一个问题,并且流选项无法解决任何问题(您甚至需要更多服务器上的内存)。
如果您不想使用套接字可以解决实现您自己的“协议”的问题,以便在块中拆分文件并仅传输单独的块。我使用了reliableSessions和TransportWithMessageCredential。
服务器(或客户端)界面如下所示:
[ServiceContract(CallbackContract = typeof(IClient), SessionMode = SessionMode.Required)]
public interface IServer
{
[OperationContract]
FilePart GetFileChunk(string identifier, int number, int blockSize);
}
作为DataContract,您可以使用以下内容:
[DataContract]
public class FilePart
{
[DataMember] public int Part;
[DataMember] public byte[] Data;
[DataMember] public int BlockSize;
}
要找到“正确”的块大小,你必须玩一点,我建议大约64-512 kb。当它们太小时你会有很多请求,当它们变大时它会变慢并且你在服务器端有更多的负载。
maxReceivedMessageSize,maxBufferSize和超时足够高(在绑定配置中)和阅读器配额也很重要。对于测试,我建议对所有字段使用最大值,当它工作时使用更适合的值。
如果使用双面绑定,可以使用ref传递对象。通过这种方式,您可以传递回调对象,这样您就能更好地查看传输的进度等等......
[OperationContract IsOneWay=true]
FilePart GetFileChunk(string identifier, int number, int blockSize, ref TransferState callback);
我认为这些都是我可以提供的技巧和提示。我希望它有所帮助。
答案 1 :(得分:1)
我认为WCF不适合传输大文件 - 请尝试使用System.Net.Sockets,尽管WCF基于它们。