Send Stream in WCF Callback

One07k-4914 101 Reputation points
2023-02-01T15:52:13.6866667+00:00

Hi All,

I wanted to implement a Stream data transfer over wcf callback.Is there any way is to achieve this?

My contract is something looks below.

Thanks in advance.

   [ServiceContract(CallbackContract = typeof(IDataTansferCallback), SessionMode = SessionMode.Required)]
    public interface IDataTransfer
    {
        [OperationContract]
        Stream Download();

        [OperationContract]
        bool Upload(Stream stream);

        [OperationContract]
        bool DownLoadAsync(string id);
    }

    [ServiceContract]
    public interface IDataTansferCallback
    {

        [OperationContract]
        void Send(Stream data);
    }
.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,183 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
9,972 questions
{count} votes

2 answers

Sort by: Most helpful
  1. QiYou-MSFT 4,306 Reputation points Microsoft Vendor
    2023-02-03T05:55:35.4266667+00:00

    Hi @la07k-4914

    First of all, I will give you the code:

    Server port service class:

    namespace Test
    {
       [ServiceContract(CallbackContract=typeof(ICallback))] 
          public interface ICalculator
          {
              [OperationContract]
            void ReceiveStream(Stream a);
        }
         public interface ICallback
         {
        [OperationContract(IsOneWay = true)]
            
            void Display(string Str);
        }
         public class CalculatorService : ICalculator
         {
            public void ReceiveStream(Stream a)
             {
                StreamReader s = new StreamReader(a);
                string str = s.ReadLine();          
                s.Close();
                ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
                 callback.Display(str);            
             }
    }
    }
    

    Since my client doesn't need to get anything from the server, I set "Isoneway=true".

    This is the callback method

    ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>()

    callback.Display(str);

    This is my server startup class "Nettcpbinding":

    class main
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
                {
                    TcpTransportBindingElement transport = new TcpTransportBindingElement();
                    host.Open();
                        Console.WriteLine("work");
                    
                    Console.ReadKey();
                }
            }
        }
    

    This is my app.config(Basic ABC protocol):

    <configuration>
    	<system.serviceModel>
    		<behaviors>
    			<serviceBehaviors>
    				<behavior>
    					<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/Metadata"/>
    				</behavior>
    			</serviceBehaviors>
    		</behaviors>
    		<services>
    			<service name="Test.CalculatorService">
    				<endpoint address="net.tcp://localhost:9003/CalculatorService" binding="netTcpBinding" contract="Test.ICalculator"/>
    			</service>
    		</services>
    	</system.serviceModel>
    </configuration>
    

    This is my client callback class:

    [ServiceContract( CallbackContract=typeof(ICallback))] 
          public interface ICalculator
          {
              [OperationContract]
            void ReceiveStream(Stream a);
        }
         public interface ICallback
         {
        [OperationContract(IsOneWay = true)]
            
            void Display(string Str);
        }
         public class CalculatorService : ICalculator
         {
            public void ReceiveStream(Stream a)
             {
                StreamReader s = new StreamReader(a);
                string str = s.ReadLine();          
                s.Close();
                ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
                 callback.Display(str);            
             }
    }
    

    This is my client startup class

    class Program
          {
             static void Main(string[] args)
              {
                  InstanceContext instanceContex = new InstanceContext(new CallbackWCFService());
                CalculatorClient proxy = new CalculatorClient(instanceContex);
                FileStream f = new FileStream("C:\\Users\\Administrator\\Desktop\\a.txt", FileMode.OpenOrCreate);
                proxy.ReceiveStream(f);
                f.Close();
                Console.Read();
             }
         }
    

    These are the basic WCF client invocation patterns above:

    Here are my test results:

    Test1

    I've implemented callback streaming for both the server and the client. Since you didn't give me your method, I wrote the method myself.If you have any questions, you can leave a message below.

    Best Regards

    Qi You


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. QiYou-MSFT 4,306 Reputation points Microsoft Vendor
    2023-02-15T07:39:29.18+00:00

    Hi @One07k-4914

    I'll build you an example from scratch to demonstrate:

    1.I set up a txt file myself and saved the content as an mp4 file.

    2.Create a server.Most of my code is the same as you gave, and I modified your web.config file.

    <serviceBehaviors>
    <behavior>
    <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/Metadata"/>
    <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
    

    3.Build the client. I modified your main function code and callback code for testing.

     public void SendStream(Stream stream)
            {
                byte[] buffer = new byte[16 * 1024];
                using (MemoryStream ms = new MemoryStream())
                {
                    int read;
                    while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms.Write(buffer, 0, read);
                    }
                    byte[] result = ms.ToArray();
                    string str= System.Text.Encoding.Default.GetString(result);
                    File.WriteAllBytes("C:\\Users\\Administrator\\Desktop\\WriteDocument.txt", result);
                    Console.WriteLine(str);
                }
            }
    
    static void Main(string[] args)
            {
                var inst = new InstanceContext(new StreamServiceCallback());
                StreamServiceClient proxy= new StreamServiceClient(inst);
                var sss = proxy.Execute();
                Console.WriteLine(sss);
                Console.ReadLine();
            }
    

    Here are my test results:

    Test2_15

    Best Regards

    Qi You


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments