1

I am using WCF with duplex netTcpBinding and I want to send a message to all users connected currently to my service. I thought I could just create a callback contract and it would send a message to all the clients but it seems I am mistaken, and there isn't a single server/service, each client gets its own service?

I have service with the name 'Server'. Here is how I access the server from the client -

ServerClient client = new ServerClient();
string result = client.SendMessage(messageTextBox.Text);
client.Close();

I thought the 'Server' was a single object that handled all calls by my clients but then I've started a thread in the Server constructor and I found out that multiple threads get started because every time a client calls the Server, a new Server object is created.

So it seems each client has it's own service/server.

  1. With that in mind how do I send a message to all my clients from the server?
  2. I thought the standard practise for accessing the server from the client was to get a proxy object, call the service functions, and then Close the proxy object like in the code above...but if I close the proxy object doesn't it mean I have closed the connection between client and server and now the server won't be able to make duplex callbacks to the client?
Venki
  • 1,419
  • 5
  • 28
  • 38
Jim_CS
  • 4,082
  • 13
  • 44
  • 80

2 Answers2

3

1) If you want all clients to share the same server, you need to make your service a singleton. Add this attribute to the class implementing your service (not the interface):

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 

That said, I suspect that what you really want is a synchronized, static (thread-shared) instance of a List<ServerClient>. Then you would iterate over that to send a message to each client. With that design, you wouldn't need a singleton server (just some good thread safety around the list).

2) If the clients close their server proxies, the server will not be able to send them any messages. You need to keep the proxy open and stash them somewhere in the client. This design will of course significantly limit scalability.

Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • You said - "This design will of course significantly limit scalability." So then I should avoid going down the singleton service route? I need to be able to show users a list of all users currenlty online, and send status messages to them periodicaly, so that is why I need the server to callback all clients. If the singleton idea is not good practise what is the standard way of implementng this? You mention a static instance of List in the other paragraph but would that not suffer the same problem of keeping proxies open? Can you advise me the standard way of doing what I need? – Jim_CS Dec 19 '11 at 20:31
  • 1
    The problem with this design (and using any form of stateful client callback proxies) is that the server will spend a lot of resources (memory, network ports, etc) keeping track of all of the clients that it has to service. A common way to get around this is to have the clients poll the server at periodic intervals, and have the server reply with any messages that have come in for that client since they last polled. If the clients are sending messages to each other, you might want to look into peer-to-peer solutions rather than a central brokered service. – Chris Shain Dec 19 '11 at 20:40
  • 1
    Keep in mind that the warnings about scalability only really apply at web-scale. If you are only ever going to have 100 people using this thing at any given time, then this is a perfectly acceptable solution, but if you are planning on building the next Twitter, this is not the way to do it. – Chris Shain Dec 19 '11 at 20:41
1

By default each client will get its own instance of the service. You can however make your service a singleton (which will than process requests from all client).

You may also want to skim through this Instance management article

Maxim Zabolotskikh
  • 3,091
  • 20
  • 21