Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Investigating solutions for notifying WPF clients from server

I have a project coming up with the requirement to notify WPF desktop clients when something happens on the server. Additionally, the notification to the WPF clients will not be broadcasted (sent to every client), it should be sent to specific clients.

I want to stay away from old fashioned server polling. This needs to be as close to real time as possible.

I've never had this requirement before and I'm investigating solutions. My first thought was to use SignalR with the .NET client. I haven't worked with SignalR yet, but it seems like it could be a solution. I am aware that this is an abstraction over long-polling, Server-Sent Events, and WebSockets, depending on what is available.

I've read briefly about WCF with Callbacks and service buses, but know nothing about them yet or whether those technologies apply here. I could use some feedback and suggestions from the people who have tackled this before. How would you do it?

like image 762
Ronnie Overby Avatar asked Dec 15 '11 14:12

Ronnie Overby


Video Answer


2 Answers

This can be done quite easily with WCF and duplex contracts. You can define operations that the client can perform on the server (like any web service) and in addition you can define operations that the server can perform on the client (i.e. a reverse web-service). Code wise, they're both just simple method calls. The client has methods that call operations on the server and it also must supply an object that implements the callback contract, which is an interface the server can call and the client must provide an implementation for. All serialization/deserialization of data and messages and all low level network operations are handled by WCF, so you won’t have to worry about it.

WCF supports duplex contracts using two bindings (or 'protocols'):

  1. WSDualHttpBinding - This entails two SOAP-based HTTP listeners, one on the server and one on the client. When the client wants to contact the server, it performs an HTTP request to server. When the server wants to contact the client, it performs a HTTP request to the client. The advantage of this approach is that any network connection is fleeting, and is not kept open (as with most HTTP connections), and so it can support a large number or concurrent clients. The main disadvantage is that it probably won't work with most client computers over the internet since they are usually behind NAT (a non-issue for server-to-server communications over the internet or any sort of communication inside an intranet or LAN). For more details, see my other answer.

  2. NetTcpBinding - This basically opens a socket from the client to the server and keeps it open for the duration of the session. This allows two way communications even over NAT, but since connections must be kept open it is somewhat more of a burden on the server and therefore will be able to support less concurrent users (but probably still more than enough in most cases). This is my preferred way of doing duplex contracts on WCF since it’s easier to get working and is more reliable.

The advantage of WCF is that you can switch between the two bindings without changing your code. All that is required is changing the configuration (.config file).

Whichever way you choose, you'll be able to perform near-instantaneous communication in both directions (network latency permitting, of course). I don't see the need for SignalR when you have such a rich, powerful and easy to user framework such as WCF at your disposal. If you were constrained by running in a browser, then SignalR would make sense. Since you're running in .NET, it would just introduce unnecessary friction.

like image 156
Allon Guralnek Avatar answered Sep 24 '22 05:09

Allon Guralnek


The point of technologies like SignalR are to meet the demand for realtime communication between servers and web clients. They take advantage of WebSockets and fallback to older/hackier communication mechanisms for older web browsers.

If your environment is going to be a LAN and your client a .NET app then you could use a TCPServer and multiple TCPClients. When your web server has an update/message to send tell your TCPServer (maybe by putting a message on a message bus which it's listening to) which can inform the connected client(s). Realtime web technologies are a great way of doing this but it really depends what your current requirements are and what your plans for the future are:

  • Do you want to try out SignalR - If yes, then it'll work and you'll probably have a lot of fun. It might also be useful for future projects and be a good string in your bow. If no, a TCPClient and TCPServer approach might be super-simple and faster to do.
  • Do you have a requirement for other types of web client to be able to receive the notifications in future? - yes, SignalR or another more mature self hosted realtime web technology might be a better solution. No - TCPServer/Client
  • Do you plan to distribute the data outside of your LAN? Yes - a self hosted option or event a hosted solution with .NET libraries may be the way to go as they remove the maintenance overhead (Disclaimer: I work for Pusher who offer a service like this). No - self hosted or TCPServer/Client.
  • How much does speed matter? If it really matters then a TCP connection with absolutely no overhead will be the fastest option. The second best options will be WebSockets, then HTTP Streaming followed by HTTP Long-Polling.

Note: Although I'm saying TCPServer/Client might be the simplest approach I'd like to emphasise that it also might not be. WebSockets are a really exciting technology and are in many ways more accessible than TCPClient technology so could become the dominant technology for bi-direction communication between any server and client*

I can't comment on Duplex Contracts but my understanding was that the connection they establish were not persisted so they are actually a polling solution - I could be wrong.

like image 34
leggetter Avatar answered Sep 22 '22 05:09

leggetter