2010-04-08 3 views

Répondre

0

Avez-vous décoré l'interface pour ICalculatorDuplex

avec

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required, 
       CallbackContract=typeof(ICalculatorDuplexCallback))] 

Lorsqu'un service reçoit un message, il se penche sur un élément replyTo dans le message pour déterminer où répondre, je suppose que si Si votre attribut de contrat de rappel est manquant, vous obtiendrez une exception NullReferenceException, car il ne sait pas où répondre.

+0

Oui, j'ai, c'est pas. – Yaroslav

0

Je viens de courir rapidement à travers l'exemple.

Le code pour mon service est:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.ServiceModel; 
using System.Text; 

namespace DuplexExample 
{ 
    // Define a duplex service contract. 
// A duplex contract consists of two interfaces. 
// The primary interface is used to send messages from client to service. 
// The callback interface is used to send messages from service back to client. 
// ICalculatorDuplex allows one to perform multiple operations on a running result. 
// The result is sent back after each operation on the ICalculatorCallback interface. 
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required, 
       CallbackContract=typeof(ICalculatorDuplexCallback))] 
public interface ICalculatorDuplex 
{ 
    [OperationContract(IsOneWay=true)] 
    void Clear(); 
    [OperationContract(IsOneWay = true)] 
    void AddTo(double n); 
    [OperationContract(IsOneWay = true)] 
    void SubtractFrom(double n); 
    [OperationContract(IsOneWay = true)] 
    void MultiplyBy(double n); 
    [OperationContract(IsOneWay = true)] 
    void DivideBy(double n); 
} 

// The callback interface is used to send messages from service back to client. 
// The Equals operation will return the current result after each operation. 
// The Equation opertion will return the complete equation after Clear() is called. 
public interface ICalculatorDuplexCallback 
{ 
    [OperationContract(IsOneWay = true)] 
    void Equals(double result); 
    [OperationContract(IsOneWay = true)] 
    void Equation(string eqn); 
} 
// Service class which implements a duplex service contract. 
// Use an InstanceContextMode of PerSession to store the result 
// An instance of the service will be bound to each duplex session 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
public class CalculatorService : ICalculatorDuplex 
{ 
    double result; 
    string equation; 
    ICalculatorDuplexCallback callback = null; 

    public CalculatorService() 
    { 
     result = 0.0D; 
     equation = result.ToString(); 
     callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>(); 
    } 

    public void Clear() 
    { 
     callback.Equation(equation + " = " + result); 
     result = 0.0D; 
     equation = result.ToString(); 
    } 

    public void AddTo(double n) 
    { 
     result += n; 
     equation += " + " + n; 
     callback.Equals(result); 
    } 

    public void SubtractFrom(double n) 
    { 
     result -= n; 
     equation += " - " + n; 
     callback.Equals(result); 
    } 

    public void MultiplyBy(double n) 
    { 
     result *= n; 
     equation += " * " + n; 
     callback.Equals(result); 
    } 

    public void DivideBy(double n) 
    { 
     result /= n; 
     equation += "/" + n; 
     callback.Equals(result); 
    } 

} 
class Program 
{ 
    static void Main() 
    { 
     var host = new ServiceHost(typeof(CalculatorService)); 

     host.Open(); 
     Console.WriteLine("Service is open"); 
     Console.ReadLine(); 

    } 
} 

}

Ma config d'application ressemble à:

<?xml version="1.0" encoding="utf-8" ?> 

<services> 
     <service behaviorConfiguration="NewBehavior" name="DuplexExample.CalculatorService"> 
      <endpoint address="dual" binding="wsDualHttpBinding" bindingConfiguration="" 
       contract="DuplexExample.ICalculatorDuplex" /> 
      <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" 
       contract="IMetadataExchange" /> 
      <host> 
       <baseAddresses> 
        <add baseAddress="http://localhost:8081/duplex" /> 
       </baseAddresses> 
      </host> 
     </service> 
    </services> 
</system.serviceModel> 

J'ai ensuite utilisé l'adresse hôte dans le fichier de configuration pour créer une référence de service nommé CalculatorService.

donc mon client ressemble à:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.ServiceModel; 
using System.Text; 
using Client.CalculatorService; 


namespace Client 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var context = new InstanceContext(new CallbackHandler()); 

      var client = new CalculatorDuplexClient(context); 

      Console.WriteLine("Press <ENTER> to terminate client once the output is displayed."); 
      Console.WriteLine(); 


      // Call the AddTo service operation. 
      var value = 100.00D; 
      client.AddTo(value); 

      // Call the SubtractFrom service operation. 
      value = 50.00D; 
      client.SubtractFrom(value); 

      // Call the MultiplyBy service operation. 
      value = 17.65D; 
      client.MultiplyBy(value); 

      // Call the DivideBy service operation. 
      value = 2.00D; 
      client.DivideBy(value); 

      // Complete equation 
      client.Clear(); 

      Console.ReadLine(); 

      //Closing the client gracefully closes the connection and cleans up resources 
      client.Close(); 
     } 
    } 


    // Define class which implements callback interface of duplex contract 
    public class CallbackHandler : ICalculatorDuplexCallback 
    { 
     public void Result(double result) 
     { 
      Console.WriteLine("Result({0})", result); 
     } 

     public void Equation(string eqn) 
     { 
      Console.WriteLine("Equation({0})", eqn); 
     } 


     #region ICalculatorDuplexCallback Members 

     public void Equals(double result) 
     { 
      Console.WriteLine("Equals{0} ",result); 
     } 

     #endregion 
    } 
} 
+0

Oui, tout cela a l'air sympa, mais vous n'appelez aucune méthode client du serveur, et c'est exactement là que le problème se situe. J'ai besoin d'un canal de rappel et je définis une instance nulle d'une interface de rappel, en utilisant ce qui dans un autre code provoque des problèmes. – Yaroslav

+0

Vous avez écrit CalculatorDuplexCallback callback = null; callback = OperationContext.Current.GetCallbackChannel(); Ne devriez-vous pas passer le callbackcontract dans cette méthode? – Miker169

Questions connexes