WCF send info from service to client when event happens in service - c#

I'm trying to build basic prototypes from a project that will take form a little later down the road.
For this prototype I currently have a console application hosting WCF services and another console application consuming the WCF services.
I have read of the three different message patterns for WCF and from what I understand I can either :
1)Call the WCF service and wait for the answer, locking the consumer while its waiting for the answer.
2)Call the WCF service asynchronously, which doesn't lock the consumer while its waiting for the answer. An answer event will eventually happen.
3)Call the WCF service without expecting and answer at all.
What I would like to know is if it is possible to use WCF to send a message to the client when an event is triggered on the service side. For example if a variable changes on the application hosting my services, a message would be sent to a client.
The only way I can imagine this would be to have my client also host WCF services and send a one way message from my initial host as the client.
This seems like a somewhat odd way of doing things for some reason and I would love to know if anybody has another idea on how this could be done.
Thanks a lot!
Note: Just in case anybody gets stuck on that, I am not looking for a way to trigger events when a variable changes. Also, there is no code in the question because it is mostly an architectural question. If you can point me towards the right tools to achieve what I'm looking for I'm sure i'll find plenty of code examples on how to use them!

Related

Communication from WCF Service to UWP Application

I am currently building a WCF Service to make use of some DLL's that are not UWP compatible at the moment. I've gotten my service running, included, and accessible from my UWP app but because I'm very new to WCF I'm not sure the best way to go about reporting the status of certain activities of the WCF Service. Specifically, I have a function that I call from my service that does some things, reaches a certain point, and then does some more things. I would like the notify the UWP app that this certain point has been reached. How would I go about doing this?
I've looked into callbacks but I haven't found a clear resource on them and am hoping there is a simpler way to accomplish what I'm looking for.
Edit: After doing some reading on the various forms of communication in WCF(mainly duplex and subpub) I think my solution will be more along the lines of subpub although it seems like overkill. From what I've seen I would be unable to make 2 callback calls from within one service function call and that would be ideal.
Edit: So apparently I am able to make 2 callback calls from a service function by modifying my ServiceContract to something like:
[ServiceContract(SessionMode = SessionMode.Required,
CallbackContract = typeof(IRecordServiceCallback_duplex),
CallbackContract = typeof(IRecordServiceCallback_duplex))]
So now I know that's what I'm trying to accomplish.
Update:
My problem now, I've looked through various examples and none of them seem to implement a duplex wcf service without some other complications which make understanding what's going on a bit difficult. Or they are missing the config file. Ideally I think I'd like to have a Duplex WCF Service hosted in IIS that communicates to a Windows Universal App, I'm currently hung up on how to call my duplex wcf service from within a UWP app. I've called a basic WCF Service before so I'm sure it can be done.

Notification fromClient1 to Client2 through WCF

I'm new at WCF and I've got one problem, and I don't have an idea how to solve it.
I've got Windows Service app listening to COM ports, and GUI WPF app for configuring Windows Service app. Among that my idea is to send notification to WPF app every time when something comes to COM port and maybe send that data to WPF.
For communicaton between those two clients I use WCF, and for sending data from WCF service to WPF app I got to use callbacks.
I got to use two different ServiceContracts because of two different clients. One of ServiceContacts supports callback method, and one of them not so there are two different bindings.
Is there any way to invoke callback method implemented on WPF app when WS gets data from COM port. On WS I invoke proxy method defined in ServiceContract for WS, and get data in WCF service but when I invoke callback its always null. I know that there is problem with OperationContext and I know what problem is but I dont know how to solve it, or is there any way to solve it.
Please help me and thank you.
I think duplex WCF (i.e. contract with Callback) is one way to go if your WFP client is normally calling the "service" via WCF anyway. You will obtain the callback context in the "service" contract class (its constructor usually) and then use it to forward anything to the WPF client at any time. Google "Duplex WCF".
However this is a situation for which in enterprise scale you will use a middleware solution, i.e. a separate "message queue/bus" infrastructure to which the WPF clients subscribe and get their updates. If no one is subscribed, messages are sent to /dev/null. The "service" publishes everything to the bus at any case.

how to use netMsmqbinding - with server connected scenario

This might look a question where you can read the answer on MSDN, but I still want to ask about the scenario, as I want to solve the business problem.
I have a service hosted on a server, and a client makes service calls. It currently uses netTCP binding. Everything works fine when the service is available, when the server is up and running. Now, I need to handle the server down scenario. I use the local cache file on the client to serve the client requests in case of server down scenario. Now I want to cache all the requests made while server down and want to make service calls once server is up and running.
I am thinking about using the netMsmqBinding, because all I've read suggests that it works well in the disconnected scenario.
Q.1 Can I use the netMsmq to handle this scenario?
Q.2 If not then what could be another approach with which I can follow to solve this problem?
Q.3 Can I use WS-Discovery in case of server down to find that the client calls won't be able to contact the service?
EDIT : The scenario is Client-Server. But i do need to give response on every call to the client. The client is also developed and maintained by me only so i am in a good position to implement the best suitable solution.
Please guide me as I'm not too good with WCF.
Yes, you can use netMsmqBinding for this purpose. We are doing that for services running over a satellite link that can be down often.
One important limitation you need to take into account is that all calls must be one way, being a queue-based transport. If you need to get the results of a request, you'll have to provide a separate response mechanism (it can be a similar queue in the opposite direction)
Ad question 1: using MSMQ is excellent for a scenario where the service may not always be up and running. Note that the server that hosts the message queue must be up and reachable to receive the messages. However, you haven't told us anything else about your scenario, particularly why you currently have NetTCP. The reason that's important, is because there are some things you can not do with MSMQ, for example duplex communication won't work out of the box.
Ad question 2: an alternative may be to implement logic in the client (it's unclear from the question if you're the owner of the client software) to have a local queue and retry messages later if a service is (temporarily) offline. I guess you may even have a proxy MSMQ service on the client, relaying the messages to the main service once it's up.
Ad question 3: yes, you can use Discovery for this. The service will have to announce to the clients when it goes online or offline. The simplest example is using the UdpAnnouncementEndpoint. In the clients you can use the AnnouncementService class to listen to the service coming online or offline, and keep a local list of available services. Alternatively (for example when UDP broadcasts aren't feasible) you can create a discovery proxy service at a well known location that listens to announcements, which the clients can access for instant-knowledge on whether the service they need is online

How to test the reactivity of a Windows Service?

I'm programming a monitoring application that needs to display the state of several windows services. In the current version, I can know whether a service is Running, Stopped, Suspended or in one of the pending states. That's good, but I'm wondering if there is a way to test if a service is actually responding? I guess it can be in a running state but not responding at all!
I am using the ServiceController class from System.ServiceProcess. Do you think that if a service is not responding, the ServiceController.Status would return an exception?
How would you approach the problem?
Thanks
EDIT
Seems that: ServiceController.Status can return 2 types of exceptions:
System.ComponentModel.Win32Exception: An error occurred when accessing a system API.
System.InvalidOperationException: The service does not exist as an installed service.
Nothing about reactivity.
This might be obvious, but have you tried talking to the service?
There's no common way to talk to a service, so there is no way Windows can interrogate whether the service is still responding as normal. It is perfectly normal for a service to go into a complete sleep waiting for external I/O to happen, and thus Windows would not get a response while the service is actually alive and functioning exactly as designed.
The only way is to actually send a request to it, and wait for the response, and for that you need some inter-process communication channel, like:
Network
Named pipes
Messages
Basically, if you need to determine if a service is able to respond, you need to check if it is responding.
The service controller types and APIs can only provide information on the basis of the service's response to those APIs.
E.g. you can create a service which responds to those APIs correctly, but provides no functionality on even numbered hours.
In the end you need to define "responsive" in terms of the services functionality (e.g. a batch processor is processing batches) and provide a mechanism (A2A API, WMI, Performance Counters) to surface this.

Communication between server and client for WinForms

I have 50+ kiosk style computers that I want to be able to get a status update, from a single computer, on demand as opposed to an interval. These computers are on a LAN in respect to the computer requesting the status.
I researched WCF however it looks like I'll need IIS installed and I would rather not install IIS on 50+ Windows XP boxes -- so I think that eliminates using a webservice unless it's possible to have a WinForm host a webservice?
I also researched using System.Net.Sockets and even got a barely functional prototype going however I feel I'm not skilled enough to make it a solid and reliable system. Given this path, I would need to learn more about socket programming and threading.
These boxes are running .NET 3.5 SP1, so I have complete flexibility in the .NET version however I'd like to stick to C#.
What is the best way to implement this? Should I just bite the bullet and learn Sockets more or does .NET have a better way of handling this?
edit:
I was going to go with a two way communication until I realized that all I needed was a one way communication.
edit 2:
I was avoiding the traditional server/client and going with an inverse because I wanted to avoid consuming too much bandwidth and wasn't sure what kind of overhead I was talking about. I was also hoping to have more control of the individual kiosks. After looking at it, I think I can still have that with WCF and connect by IP (which I wasn't aware I could connect by IP, I was thinking I would have to add 50 webservices or something).
WCF does not have to be hosted within IIS, it can be hosted within your Winform, as a console application or as windows service.
You can have each computer host its service within the winform, and write a program in your own computer to call each computer's service to get the status information.
Another way of doing it is to host one service in your own computer, and make the 50+ computers to call the service once their status were updated, you can use a database for the service to persist the status data of each node within the network. This option is easier to maintain and scalable.
P.S.
WCF aims to replace .net remoting, the alternatives can be net.tcp binding or net.pipe
Unless you have plans to scale this to several thousand clients I don't think WCF performance will even be a fringe issue. You can easily host WCF services from windows services or Winforms applications, and you'll find getting something working with WCF will be fairly simple once you get the key concepts.
I've deployed something similar with around 100-150 clients with great success.
There's plenty of resources out on the web to get you started - here's one to get you going:
http://msdn.microsoft.com/en-us/library/aa480190.aspx
Whether you use a web service or WCF on your central server, you only need to install and configure IIS on the server (and not on the 50+ clients).
What you're trying to do is a little unclear from the question, but if the clients need to call the server (to get a server status, for example), then they just call a method on the webservice running on the server.
If instead you need to have the server call the clients from time to time, then you'll need to have each client call a sign-in method on the server webservice each time the client starts up. The sign-in method would take a delegate method from the client as a parameter. The server would then call this delegate when it needed information from the client.
Setting up each client with its own web service would represent an inversion of the traditional (one server, multiple clients) client/server architecture, and as you've already noted this would be impractical.
Do not use remoting.
If you want robustness and scalability you end up ruling out everything but what are essentially stateless remote procedure calls. Since this is exactly the capability of web services, and web services are simpler and easier to build, remoting is an essentially pointless technology.
Callbacks with remote delegates are on the performance/reliability forbidden list, so if you were thinking of using remoting for that, think again.
Use web services.
I know you don't want to be polling, but I don't think you need to. Since you say all your units are on a single network segment then I suggest UDP for broadcast change notifications, essentially setting a dirty flag, and allowing the application to (re-)fetch on demand. It's still not reliable but it's easy and very fast because it's broadcast.
As others have said you don't need IIS, you can self-host. See ServiceHost class for details on how to do this.
I'd suggest using .NET Remoting. It's quite easy to implement and doesn't require anything else.
For me its is better to learn networking.. or the manual way of socket communication.. web services are mush slower because it contains metadata..
your clients and the servers can transform to multithreaded application. just imitate the request and response architecture. it is much easy to implement a network application like this..
If you just need a status update, you can use much simpler solution, such as simple tcp server/client messaging or like orrsella said, remoting. WCF is kinda overkill here.
One note though, if all your 50+ kiosk is connected via internet, then you might need use VPN or have an open port on each kiosk(which is a security risk) so that your server can retrieve status update from each kiosk.
We had a similiar situation, but the status is send to our server periodically, so we only have 1 port to protect/secure. The frequency of the update is configurable as to accomodate slower clients.
As someone who implemented something like this with over 500+ clients and growing:
Message Queing is the way to go.
We have gone from an internal developed TCP server and client to WCF polling and ended up with Message queing. It's the only guaranteed way to get data to and from clients and servers over the internet. As a bonus, many of these solutions have an extensive framework makeing it trivial to implement publish-subscribe, Send-one-way, point-to-point sending, Request-reply. Some of these are possible with WCF but it will involve crying, shouting, whimpering and long nights not to mention gallons of coffee.
A couple of important remarks:
Letting a process poll the clients instead of the other way around = Bad idea.. it is not scalable at all and you will soon be running in to trouble when the process is take too long to complete.. Not to mention having to handle all the ip addresses ( do you have access to all clients on the required ports ? What happpens when the ip changes etc..)
what we have done: The clients sends status updates to a central message queue on a regular interval ( you can easily implement live updates in the UI), it also listens on it's own queue for a GetStatusRequest message. if it receives this, it answers ( has a timeout).. this way, we can see overal status of all clients at all times and get a specific status of a specific client when needed.
Concerning bandwidth: kiosk usually show images/video etc.. 1Kb or less status messages will not be the big overhead.
I CANNOT stress enough that the current design you present will have a very intensive development cycle AND will not scale or extend well ( trust me, we have learned this lesson). Next to this, building a good client/server protocol for this type of stuff is a hard job that will be totally useless afterwards if you make a design error ( migrating a protocol is not easy)
We have built our solution ontop of ActiveMQ ( using NMS library c#) and are currently extending Simple Service Bus for our internal workings.
We only use WCF for the communication between our winforms app and the centralized service(s)

Categories