开发者

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

开发者 https://www.devze.com 2023-04-03 19:30 出处:网络
I\'m tring to implement my first WCF call-back server. This is my code: [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ILogCallback))]

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.


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);
  }
}


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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号