2010-01-15 13 views
5

Büyük dosyaları aktarması gereken bir WCF Hizmeti yazıyorum, bu yüzden akışı kullanıyorum, ancak diğer taraftan kullanıcı adı özel başlatmalarını yapmalıyım.NetTcpBinding'de hem oturumu hem de akışı etkinleştirmenin bir yolu var mı?

Sorun, kullanıcı adının alınması ve başlatmanın her zaman çok pahalı yapılmasıdır. Oturumu açabilirsem, hizmet örneğinde yerel değişkenlerde başlatılmış verileri kaydedebilirdim.

NetTcpBinding'de hem akış hem de oturum açmanın bir yolu var mı?

cevap

4

Büyük dosya aktarımları gerçekten wcf'de bir problemdir ve akış seçeneği hiçbir şeyi çözmez (hatta sunucuda daha fazla belleğe ihtiyacınız vardır).

Soketler kullanmak istemiyorsanız, sorunu bloklara ayırmak ve yalnızca ayrı blokları aktarmak için kendi "protokol" ünü uygulayarak sorunu çözebilirsiniz. GüvenilirSessions ve TransportWithMessageCredential'ı kullandım.

[ServiceContract(CallbackContract = typeof(IClient), SessionMode = SessionMode.Required)] 
public interface IServer 
{ 
    [OperationContract] 
    FilePart GetFileChunk(string identifier, int number, int blockSize); 
} 

DataContract olarak böyle bir şey kullanabilirsiniz::

[DataContract] 
public class FilePart 
{ 
    [DataMember] public int Part; 
    [DataMember] public byte[] Data; 
    [DataMember] public int BlockSize; 
} 

Mecbur "doğru" blok boyutunu bulmak için

Sunucusu (veya istemci) arayüzü şuna benzer Biraz oyna, 64-512 kb hakkında bir şey tavsiye ederim. Çok küçük olduklarında çok fazla istek var, büyük olduklarında yavaşlar ve sunucu tarafında daha fazla yük var.

Ayrıca maxReceivedMessageSize, maxBufferSize ve zaman aşımlarının yeterince yüksek (bağlama yapılandırmasında) ve okuyucu kotaları önemlidir. Test için, tüm alanların maksimum kullanılmasını tavsiye ederim, işe yaradığında daha iyi uyan değerler kullanın.

Önlü arkalı bağlantılarla çalışıyorsanız, nesnelerini ref olarak geçirebilirsiniz. Eğer transferi ve benzeri ilerlemesini görüntülemek için daha iyi edebiliyoruz bu yolla ile

[OperationContract IsOneWay=true] 
FilePart GetFileChunk(string identifier, int number, int blockSize, ref TransferState callback); 

Bu verebileceğim bütün hile ve ipuçları olduğunu düşünüyorum ..., geri arama nesneleri geçebilir. Umut ediyorum bu yardım eder.

+1

Hangi boyutta "büyük" olarak düşünürdünüz? – flayn

+0

Oluşturmak istediğiniz şeye bağlıdır ... doğru yapılandırmayla, dosyayı bölmeden 50MB'nin üstüne dosyaları aktarabilirsiniz, ancak wcf akış seçeneğini etkinleştirmelisiniz. Aktarım seçeneği ile sunucudaki bellek tüketimi aktarım mesajı tabanlı dosya yığınlarından daha yüksektir, bu nedenle yüksek bir yükü işlemek zorunda kalırsanız, bölme işlemi daha iyi bir yol olabilir. – CaptainPlanet

1

WCF'nin büyük dosyaları aktarmak için uygun olduğunu düşünmüyorum - WCF bunlara dayanıyor olsa da, bunun yerine System.Net.Sockets kullanmayı deneyin.

İlgili konular