stav alfi

stav alfi

  • NA
  • 2
  • 1.6k

WCF Streaming - Limiting speed

May 26 2012 4:48 PM

This is a severe problem in my application for some months with out finding any good solution. I noticed that C# manage the way Stream class is streaming in WCF, without considering my configuration.

Firstly, I have a class that inherit from FileStream so I can watch how much was read until now from the client side at anytime:

public class FileStreamWatching : FileStream
   
{
       
/// <summary>        
       
/// how much was read until now        
       
/// </summary>        
       
public long _ReadUntilNow { get; private set; }
       
public FileStreamWatching(string Path, FileMode FileMode, FileAccess FileAccess)
           
: base(Path, FileMode, FileAccess)
       
{
           
this._ReadUntilNow = 0;
       
}
       
public override int Read(byte[] array, int offset, int count)
       
{
           
int ReturnV = base.Read(array, offset, count);
           
//int ReturnV = base.Read(array, offset, count);
           
if (ReturnV > 0)
           
{
                _ReadUntilNow
+= ReturnV;
               
Console.WriteLine("Arr Lenght: " + array.Length);
               
Console.WriteLine("Read: " + ReturnV);
               
Console.WriteLine("****************************");
           
}
           
return ReturnV;
       
}
   
}

Secondly, below is my service method of reading the client's stream that contain the file. My main problem is that FileStreamWatching.Read does not start for each time I summon it from this method below, instead FileStreamWatching.Read start one time for each X times I call it.. Strange.

*Look at the out put later

    public void Get_File_From_Client(Stream MyStream)
   
{
        using
(FileStream fs = new FileStream(@"C:\Upload\" + "Chat.rar", FileMode.Create))
       
{
           
byte[] buffer = new byte[1000];
           
int bytes = 0;
           
while ((bytes = MyStream.Read(buffer, 0, buffer.Length)) > 0)
           
{
                fs
.Write(buffer, 0, bytes);
                fs
.Flush();
           
}
       
}
   
}

This is the output at the client side for each time FileStreamWatching.Read is activated:(Remmber the buffer lenght is only 1000!)

Arr Lenght: 256, Read: 256


Arr Lenght: 4096, Read: 4096


Arr Lenght: 65536, Read: 65536


Arr Lenght: 65536, Read: 65536


Arr Lenght: 65536, Read: 65536


Arr Lenght: 65536, Read: 65536


....Until the file transfare is complete.

Problems:

  1. The Lenght of the buffer I brought to the read method isnt 256/4096/65536. It is 1000.
  2. The Read from the FileStreamWatching class does not start each time I call it from the service.

My goals:

  1. Controling on how much I reacive from the client for each read.

  2. The FileStreamWatching.Read will start each time I call it from the service.

My Client configuration:

<configuration>
   
<system.serviceModel>
       
<bindings>
           
<basicHttpBinding>
               
<binding name="BasicHttpBinding_IJob" transferMode="Streamed"/>
           
</basicHttpBinding>
       
</bindings>
       
<client>
           
<endpoint address="http://localhost:8080/Request2" binding="basicHttpBinding"
                bindingConfiguration
="BasicHttpBinding_IJob" contract="ServiceReference1.IJob"
                name
="BasicHttpBinding_IJob" />
       
</client>
   
</system.serviceModel>
</configuration>

My service configuration (There is no configuration file here):

        BasicHttpBinding BasicHttpBinding1 = new BasicHttpBinding();
       
BasicHttpBinding1.TransferMode = TransferMode.Streamed;
       
//
       
BasicHttpBinding1.MaxReceivedMessageSize = int.MaxValue;
       
BasicHttpBinding1.ReaderQuotas.MaxArrayLength = 1000;
       
BasicHttpBinding1.ReaderQuotas.MaxBytesPerRead = 1000;
       
BasicHttpBinding1.MaxBufferSize = 1000;
       
//
       
ServiceHost host = new ServiceHost(typeof(JobImplement), new Uri("http://localhost:8080"));
       
//
       
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
        behavior
.HttpGetEnabled = true;
       
//
        host
.Description.Behaviors.Add(behavior);
       
ServiceThrottlingBehavior throttle = new ServiceThrottlingBehavior();
        throttle
.MaxConcurrentCalls = 1;
        host
.Description.Behaviors.Add(throttle);
       
//
       
//
        host
.AddServiceEndpoint(typeof(IJob), BasicHttpBinding1, "Request2");
        host
.Open();