2010-01-15 13 views
5

Scrivo un servizio WCF che richiede il trasferimento di file di grandi dimensioni, quindi utilizzo lo streaming, ma dall'altra ho bisogno di fare inizializzazioni specifiche del nome utente.C'è un modo per abilitare sia la sessione che lo streaming in netTcpBinding?

Il problema è che ottenere il nome utente ed eseguire l'inizializzazione ogni volta è molto costoso. Se potessi attivare la sessione, potrei semplicemente salvare i dati inizializzati in variabili locali nell'istanza del servizio.

C'è un modo per attivare sia lo streaming che la sessione in netTcpBinding?

risposta

4

I trasferimenti di file di grandi dimensioni sono davvero un problema in wcf e l'opzione di streaming non risolve nulla (è addirittura necessario più memoria sul server).

Se non si desidera utilizzare i socket, è possibile risolvere il problema con l'implementazione del proprio "protocollo" per suddividere il file in blocchi e trasferire solo blocchi separati. Ho usato affidabileSession e TransportWithMessageCredential.

server (o client) l'interfaccia simile a questa:

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

Come DataContract si può usare qualcosa di simile:

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

di trovare il "giusto" dimensione dei blocchi è necessario giocare un po ', mi raccomando qualcosa su 64-512 kb. Quando sono troppo piccoli hai molte richieste, quando sono troppo grandi diventa lento e hai più carico sul lato server.

È inoltre importante che maxReceivedMessageSize, maxBufferSize e timeout siano sufficientemente elevati (nella configurazione di binding) e le quote del lettore. Per i test consiglio di utilizzare il massimo per tutti i campi, quando funziona utilizzare valori che si adattano meglio.

Se si lavora con collegamenti duplex è possibile passare oggetti con riferimento. Con questo modo è possibile passare gli oggetti di richiamata, in modo che siano meglio in grado di visualizzare l'avanzamento del trasferimento e così via ...

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

Penso che questo sono tutti i trucchi e suggerimenti che posso dare. Spero possa essere d'aiuto.

+1

Che taglia consideri "grande"? – flayn

+0

Dipende da cosa vuoi costruire ... con la giusta configurazione puoi trasferire file sopra i 50MB senza dividere il file, ma devi attivare l'opzione di streaming wcf. Con l'opzione di streaming, il consumo di memoria sul server è maggiore rispetto ai file di trasferimento basati su file, quindi se si deve gestire un carico elevato, la suddivisione potrebbe essere il modo migliore ... – CaptainPlanet

1

Non penso che WCF sia appropriato per il trasferimento di file di grandi dimensioni - prova invece a utilizzare System.Net.Sockets, anche se WCF è basato su di essi.

Problemi correlati