2

I am currently developing a C# Windows Form Application that I intend to let it interact with a server. The server will receive posting from a mobile application that I have developed and whenever a posting is received, my Windows Form Application should be notified and give me a notification. In order to do this, I intend to use WCF duplex service for it.

E.g. My mobile application sends an posting over to my server. Once my server reads and receives the new posting, the service should send a message over to my winform app to alert me that a posting is received. And the UI of the winform app should update accordingly to what I want to updated. (e.g. adding new panels)

This is basically how I wish for it to work They way this would work is

  1. WCF Service in running on my server
  2. Windows Form connects to my server's WCF service using Duplex Contract
  3. Mobile app posts to a webpage
  4. Once the webpage receives the posting, the asp.net will invoke the WCF service
  5. WCF duplex service receives the posting and sends the information to the winform app
  6. My winform Application aka WCF Client updates UI with this new message received

My question is, how does step 4 proceed to step 5? To be specific, how does the service sends the information over to the winform app upon receiving the posting.

To be even more specific, once the posting is received from the webpage, the service contract is invoked and the information is sent and received by the service, how does the service make use of the call back channel to send the information over to the winform app and update the UI accordingly?

Thomas
  • 1,126
  • 6
  • 21
  • 39

2 Answers2

3

The answer to this question depends on how your WCF service is hosted and how "big" the service will eventually be (in terms of number of simultaneous clients).

  • The simplest scenario is a self-hosted WCF service (meaning hosted in a Windows Service or as a desktop application--not in IIS). In this case, you can use InstancePerSession mode and make your service use sessions. In this case, you'll have a 1:1 correspondence between clients and instances of your service class. When a client connects, retrieve the callback reference and store it in a static list outside of the service class. When you need to send a message to one or more clients, simply iterate over (or find the desired client in) your list and call the appropriate function on the callback contract
  • If you need to host your service in IIS, then the situation is trickier because you have the possibility of multiple processes hosting your service, so your list can potentially get fragmented (or blown away in the event of an app pool recycle). In this case, you'll have to use something external to your service (MSMQ, perhaps) to notify other application pool processes that a message needs to be sent.
Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
  • Hi, thank you for your reply again. regarding the part where you say, "when a client connects, retrieve the callback reference and store it in a static list outside of service class" how do I go about doing this? – Thomas Nov 16 '11 at 13:49
  • i am still quite unsure about the part whereby what happens after my service receives the posting from my server. how does the service automatically send the posting to my winform after receiving the posting? – Thomas Nov 16 '11 at 14:22
  • edit : or rather, how do I straight away call the callback channel straight after the posting method is being called by the server. (adding in the callback code at the last line of the post method?) – Thomas Nov 16 '11 at 15:50
1

In terms of a duplex connection, you are really just able to communicate two way over that one connection, not with all connections of the service without doing some tricky thread stuff and shutting the door on any scalability (or using something outside the service to handle to pub/sub).

One solution though that may work a lot more along the lines of what you want to do would be SignalR. It allows a single client to make a request and then you can broadcast data from that request to other clients (or target it). Take a look at its info, its sole purpose is real time communication in .NET with multiple clients.

Also another note, is that you will want to use some sort of BackgroundWorker or something for your listening thread in WinForms so that the UI is not locked while the background operations are running.

Paul Tyng
  • 7,924
  • 1
  • 33
  • 57
  • I'm curious what you mean by "tricky threading stuff". Depending on how the service is hosted (self hosted vs. iis), this could be as simple as a `static` list of callback contract connections, or it would require external synchronization. Either way, I'm not sure what specific threading operations would come into play. – Adam Robinson Nov 16 '11 at 13:22
  • In WAS you can designate your hosting to be as a "web garden" (ie. multiple worker processes) or if your service needed to scale to multiple servers ("web farm") a static variable obviously will not work. Instead of using a `static` you can actually mark your service class as single instance and just use instance data. But the threading stuff I'm referring to is that the callback channel of the operation context is maintained on the current request thread, not in some like global dictionary. So you would have to implement this dictionary and then use it to find specific clients. – Paul Tyng Nov 16 '11 at 14:29
  • Also note that the `WSHTTPDualBinding` requests 2 connections, so it potentially needs ports opened, which may not work for you mobile device or other things depending on their firewall setup, here is more info: http://stackoverflow.com/questions/5165858/is-wcf-duplex-a-good-choice I have successfully used the duplex bindings for intranet apps but I think over the internet it may be a bad idea when there are other libraries better suited for your needs. If you are looking for something to implement yourself you can also check in to HTML 5 WebSockets. – Paul Tyng Nov 16 '11 at 14:30
  • "tricky threading stuff" i mean synchronized access to the client list and locks around some of the communication since WCF is multi threaded. – Paul Tyng Nov 16 '11 at 14:33
  • Right, which means that the method of message delivery back to the clients is dependent upon the activation/hosting mechanism (self hosted vs. WAS). I agree with you that `WSHTTPDualBinding` is almost always a bad choice because of firewall issues. My assumption was that this user's application was an intranet application, so something more appropriate like `NetTcpBinding` could be used. Note that he wants a duplex connection between his desktop application and the service, not between the mobile device and the service. – Adam Robinson Nov 16 '11 at 14:37
  • As for the threading stuff, I guess we just have different definitions of "tricky" ;) Locks and such are pretty standard fare when it comes to concurrency control, so I wouldn't have classified them that way; I thought you might be referring to something else that I hadn't thought of. – Adam Robinson Nov 16 '11 at 14:38
  • Nah, I just mostly was trying to point out that I don't think with the WCF hammer this should be seen as a nail because of many of the issues we both point out. – Paul Tyng Nov 16 '11 at 14:40