2

I have a windows service that continuously read data from a serial port, from this service I'd like to be able to notify a WPF application with the updated data using WCF; I thought about using callbacks.

The windows service would call a WCF service's method which in turn would call the WPF application callback:

[ServiceContract(CallbackContract = typeof(IUpdateCallback))]
public interface IMyService
{
     [OperationContract]
     void Update(UpdatedData data);
}

public interface IUpdateCallback
{
    void OnUpdate(UpdatedData data);
}

This is how I'm planning to implement the service:

public class MyService : IMyService
{
    public void Update(UpdatedData data)
    {
        var callback =  OperationContext.Current.GetCallbackChannel<IUpdateCallback>();

        callback.OnUpdate(data);
    }
}

And then from the client App's side:

public class UpdateCallback : IUpdateCallback
{
    public void OnUpdate(UpdatedData data)
    {
        // Update data logic...
    }
}

Am I on the right track, or is there a better way to do this?

mainvoid
  • 347
  • 1
  • 4
  • 17

2 Answers2

2

So using callbacks is certainly one way of doing this. However, the callback channel can timeout and so you'll need a way of automatically reconnecting. If you want to continue down this route then you're looking good understanding-wise.

In my opinion, a simpler (and therefore superior) solution is to use netMsmqBinding, host the service in the WPF app, and then have the windows service consume it. This has the benefit that it's more reliable than duplex communication as it relies on one way calls, and easier to implement.

Additionally the windows service will still be able to send notifications to the WPF app even if the WPF is unavailable - messages will simply queue up until the WPF comes back online. (This may or may not be desirable.)

You would need to have msmq enabled on both machines, and for maximum reliability use transactional queues with DTC.

if I wanted to be able to send data from the client app to the serial port (the Windows service would still handle the IO), would I have to implement another WCF service

In this instance yes you would have to configure a service on the windows service which exposed an operation for the WPF to call into. This would need to be defined separately to the one used for notifications, and could just use http/tcp as a transport rather than message queues, as this sounds like a synchronous operation.

Should I define the WCF service inside the WPF project and not as a stand alone DLL?

The WPF project is the host process for the WCF service. From this perspective it makes no difference if you define the service as a standalone assembly or within the WPF app, you should be able to spin up a ServiceHost instance within your WPF app which will expose the service.

Despite it making little difference where you define your service code to the runtime hosting of the service, as best-practice I would always try to define your actual service implementation as a separate assembly, to keep things which are logically different in a different place.

how am I supposed to consume the data from the WPF application: the Windows service will call the WCF service and send the data, from here I would need to retrieve that data that is hold somewhere

So my understanding was that your original plan was to host the WCF service in the windows service which reads data from a serial port.

The WPF service would then call the WCF service and the WCF service would store the callback delegate for the WPF service, effectively like a subscription.

When data arrived at the serial port the WCF service would then invoke the callback channel and feed data back to the WPF service.

My suggestion was to replace this with a queue-based approach, where you would host the service in the WPF app, and have the windows service simply call the WCF service when data arrived on the serial port.

Then you asked about also having the WPF app call the windows service to pass data across, and I said that you should host a separate service in the windows service in order to expose an endpoint for the WPF app to call. When the WPF app made a call and passed data into the WCF service, this data could then be made available to the windows application which talks to the serial port.

Are you now asking how to allow data passed in on the call from the WPF app to the windows service-hosted WCF app to be available to the windows service? If so then please read my post here, which details how to pass data from an instance of a WCF service to the app domain which is running the ServiceHost instance.

Community
  • 1
  • 1
tom redfern
  • 30,562
  • 14
  • 91
  • 126
  • Thanks, I'll check it out. Also I was wondering, if I wanted to be able to send data from the client app to the serial port (the Windows service would still handle the IO), would I have to implement another WCF service (hence another callback) that handles the communication the other way around? – mainvoid Mar 09 '15 at 15:55
  • One thing I'm still having trouble figuring out is how am I supposed to consume the recieved data in the client App? Should I define the WCF service inside the WPF project and not as a stand alone DLL? – mainvoid Mar 11 '15 at 09:22
  • @mainvoid see my edit to my answer. I am uncertain what you are asking but I am assuming you have coded your service interface and implementation as a separate assembly and now you're unsure how to host it within WPF. Is this the case? – tom redfern Mar 11 '15 at 09:41
  • I do know how to host the service, what I wanted to know is how am I supposed to consume the data from the WPF application: the Windows service will call the WCF service and send the data, from here I would need to retrieve that data that is hold somewhere. I need something or somewhere in order to share the data between the WCF service and the WPF application itself, am I right? – mainvoid Mar 11 '15 at 15:49
  • I have this requirement like i want to continuosly watch a serial port thorugh my windows service and when data will come on this port then i want to push that data in to my database.can you please guide me little bit?? – I Love Stackoverflow Apr 20 '16 at 06:28
  • 1
    @Learning if you post your comment as a question, outlining exactly what you want to acheive, along with any thoughts you have for a solution, and then paste the link as a comment here, I will take a look. – tom redfern Apr 20 '16 at 07:58
  • Can you help me with this question:http://stackoverflow.com/questions/36738596/how-to-store-data-through-web-service-when-data-coming-to-my-serial-port-will-be – I Love Stackoverflow Apr 20 '16 at 08:55
  • 1
    @Learning This is a complex requirement - outside my current area of knowledge. I have formatted the question so it's easier to understand. I hope you get some good responses! Good luck with your solution – tom redfern Apr 20 '16 at 10:37
  • No problem.Thank you so much sir – I Love Stackoverflow Apr 20 '16 at 10:45
  • Sir can you tell me something about like I have 1 event which will fire whenever my data will arrive on serial port.so when this data will come I will have 1 web api method which will insert data in database.so I want this database insert operation independent of my data receive event.my data receive event will continuosly receive data from serial port – I Love Stackoverflow Apr 20 '16 at 15:15
  • @Learning - sounds like you need to ask another question... let me know when you have done so – tom redfern Apr 20 '16 at 15:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/109745/discussion-between-learning-and-tom-redfern). – I Love Stackoverflow Apr 21 '16 at 03:39
0

MSMQ is a good way of handling this. If your technology stack permits, I would check out ActiveMQ or RabbitMQ, as you can do true pub/sub broadcasting of your data to other applications that would be interested in receiving those events.