16

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?

Ronnie Overby
  • 41,852
  • 68
  • 257
  • 338

6 Answers6

7

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.

Community
  • 1
  • 1
Allon Guralnek
  • 15,101
  • 5
  • 51
  • 92
  • 1
    I will look more into this area of WCF, but the reason I was considering SignalR is because my experience is that WCF introduces unnecessary friction. – Ronnie Overby Dec 15 '11 at 23:49
4

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.

leggetter
  • 14,640
  • 1
  • 50
  • 58
  • Duplex Contracts do not use polling, at least with any of the bindings supplied with the framework (i.e. you could write your own custom binding that does all sorts of crazy things). – Allon Guralnek Dec 20 '11 at 12:27
  • What do they use? HTTP Streaming? – leggetter Dec 20 '11 at 13:33
  • Ah, TCP - for the TCP binding - obviously. For HTTP the client actually needs to act as a server, well, have an IP address so that an HTTP request can be made to it from the server. – leggetter Dec 21 '11 at 15:06
3

I was also evaluating a light weight yet easy way to communicate events to WPF clients using a pub/sub service. I did not require guaranteed message delivery so solutions like MassTransit or NServiceBus seemed too heavy as they require queues to be available (MSMQ or otherwise). I also had the requirement that the solution be available as .NET 4.0 Client Profile.

One solution built on WCF that seems to work is nvents. I'm not sure if that project is still active. It is easy to use and the underlying implementation (WCF) is well abstracted. No nasty configuration required.

Another solution I came across on Per Brage's Blog uses SignalR with Reactive Extensions. I haven't tried his implementation and am not sure if it requires a full profile but is a good read!

Mike Rowley
  • 898
  • 7
  • 19
3

You should look into WebSync from Frozen Mountain. I've used it in the past with great results. It does all you require. They even offer a hosted service 'WebSync on Demand'. They offer a free product as well (but up to 10 concurrent users). It is a comercial product. If you don't want to do all the plumbing, WebSync offers you ready to use api's you can just start using and get going fast. I've heard/read about SignalR, have not used it yet, but SignalR seems to be in alpha/beta, whereas WebSync is very mature.

santiagoIT
  • 9,185
  • 6
  • 40
  • 54
0

This question is interesting.

We are currently developing an application that interacts with multiple Web Services. One of the requirements is that each client must be kept aware of the actions done by the other clients.

In order to achieve this, we're thinking of creating a Web Service whose purpose is only to build a list of clients to notify, and to handle the logic behind who is notified, when, and the content of the notification. The clients would register with that Service when they are launched. The notifications themselves would be done using callbacks as you mentioned.

The reason behind using a completely separate Web Service was due to the fact that all our existing ones required connections to be established and dropped on every call. With the notification Web Service, connections have to be maintained as long as the clients run.

I'm sorry I could not be of much more help, as we're in the process of developing such a system ourselves. I'm also interested in obtaining feedback on this subject.

Hussein Khalil
  • 1,495
  • 2
  • 23
  • 46
0

You can create a wcf service where wpf clients register themselve to on startup. Then each wpf could communicate with a msmq or rabbitmq server where they will poll their own queue created based on the client name/unique id. On the server side, you can have a service that will push data to the queues as data are available based on conditions set for each clients.

rpgmaker
  • 780
  • 1
  • 4
  • 7
  • You can always have a queue on each machine that run the WPF app and read from the queue. As long as you are using WPF you will need to poll something to get data except you use wcf callbacks which is not as reliable as using queue where you have persist your data – rpgmaker Dec 16 '11 at 02:15
  • Elaborate on why it's not as reliable. – Ronnie Overby Dec 16 '11 at 12:21
  • 1
    It is not reliable because you cannot fully control clients that are connected to your service. You will have to write a lot code to manage detecting disconnect and connect of client, such as checking whether a client connection is faulted. In a situation where the client lose connection, they will loose data that was sent while they were disconnected. It is only good if you don't mind loosing data, but if you want to make sure that all client is always notified then you need a way to persist the data some how. – rpgmaker Dec 16 '11 at 19:29