简体   繁体   中英

my first WCF Server - why OperationContext.Current is null?

I'm tring to implement my first WCF call-back server. This is my code:

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ILogCallback))]
public interface ILog
{
}

public interface ILogCallback
{
    [OperationContract(IsOneWay = true)]
    void Push(string callbackValue);
}

public class MyLog : ILog
{

}

class Log
{


    public static void initialize()
    {
        using (ServiceHost host = new ServiceHost(
            typeof (MyLog),
            new Uri[]
                {
                    new Uri("net.pipe://localhost")
                }))
        {

            host.AddServiceEndpoint(typeof (ILog),
                                    new NetNamedPipeBinding(),
                                    "PipeReverse");

            host.Open();
            // TODO: host.Close();
        }
    }

    public static void Push(string s)
    {
        ILogCallback callbacks = OperationContext.Current.GetCallbackChannel<ILogCallback>();
        callbacks.Push(s);
    }
}

then I try to use my server using this code:

        Log.initialize();

        while (true)
        {
            Log.Push("Hello");
            System.Threading.Thread.Sleep(1000);
        }

But I got NPE, because OperationContext.Current is null. Why, what's wrong and how to fix that?

Because you are NOT in the context of an operation.

You're simply calling a static method of the Log class.

For you to be in an Operation Context your call MUST have been come from a client that is being serviced by your WCF server.

You are missing the subscriber's subscription. The way you do this is to create a [oneway] operation in your MyLog WCF server called something like: " void SendMeLogs() ". This will open the client callback channel. You Then have to implement SendMeLogs() in lines of something like:

void SendMeLogs()
{
  while(CheckLogsForNewData())
 {
   PushOnTheClient();
 }
}

Since the SendMeLogs() function is oneway, the client will not block, but will start the subscription to your log server. (you can search the net for sample code for duplex calculator in wcf for a good example of this architecture). The key however is that you must have a nice unsubscribe method like " StopSendingMeLogs " to break the loop, and also make the PushOnTheClient function fail safe, in case the client terminates or the specific client connection goes down. The " CheckLogsForNewData " function should ideally be a shared (static) implementation in your case

OperationContext.Current is a thread-static property that is initialized when request arrives to the server. Here's what you do to call the callback

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ILogCallback))]
public interface ILog
{
  void PushOnTheClient();
}

public class MyLog : ILog
{
  void PushOnTheClient()
  {
        ILogCallback callbacks = OperationContext.Current.GetCallbackChannel<ILogCallback>();
        callbacks.Push(s);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM