views:

434

answers:

5

Hi,

I hope someone can guide me as I'm stuck... I need to write an emergency broadcast system that notifies workstations of an emergency and pops up a little message at the bottom of the user's screen. This seems simple enough but there are about 4000 workstations over multiple subnets. The system needs to be almost realtime, lightweight and easy to deploy as a windows service.

The problem started when I discovered that the routers do not forward UDP broadcast packets x.x.x.255. Later I made a simple test hook in VB6 to catch net send messages but even those didn't pass the routers. I also wrote a simple packet sniffer to filter packets only to find that the network packets never reached the intended destination.

Then I took a look and explored using MSMQ over HTTP, but this required IIS to be installed on the target workstation. Since there are so many workstations it would be a major security concern.

Right now I've finished a web service with asynchronous callback that sends an event to subscribers. It works perfectly on a small scale but once there are more than 15 subscribers performance degrades considerably. Polling a server isn't really an option because of the load it will generate on the server (plus I've tried it too)

I need your help to guide me as to what technology to use. has anyone used the comet way with so many clients or should I look at WCF?

I'm using Visual C# 2005. Please help me out of this predicament.

Thanks

A: 

This problem i think is best solved with socket.

Open a connection to the server, and keep it open.

AndreasN
Opening a connection to the server works. Having 4000 sockets open might work, but I'm afraid it won't scale too well.
Piskvor
A: 

Could you have a slave server in each subnet that was responsible for distributing the messages to all the clients in the subnet?

Then you could have just the slaves attached to the central server where the messages are initiated.

Martin
You are right but i dont think i can get the hardware. there are around 50 subnets which means one server with 50 tcp connections each to many udp clients. So i'll need the client to be able to "nominate" itself for the slave, in case a workstation is restarted/etc. Would u recommend WCF for this?
Tyler
it may become a configuration nightmare
Ihar Voitka
I'd recommend having a few slaves in each subnet, in case one of the slaves goes down before it has time to notify the master. (Getting notified of the same event multiple times is better than not at all - you can ignore subsequent identical notices on the clients)
Piskvor
+3  A: 

Consider using WCF callbacks mechanism and events. There is good introduction by Juval Lowy.

Another pattern is to implement blocking web-service calls. This is how GMail chat works, for example. However, you will have to deal with sessions and timeouts here. It works when clients are behind NATs and Firewalls and not reachable directly. But it may be too complicated for simple alert within intranet.

Ihar Voitka
A: 

I think some of you are vastly overthinking this. There is already a service built into every version of Windows that provides this exact functionality! It is called the Messenger service. All you have to do is ensure that this service is enabled and running on all clients.

(Although you didn't specify in the question, I'm assuming from your choices of technology that the client population of this network is all Windows).

You can send messages using this facility from the command line using something like this:

NET SEND computername "This is a test message"

The NET SEND command also has options to send by Windows domain, or to specific users by name regardless of where they are logged in, or to every system that is connected to a particular Windows server. Those options should let you easily avoid the subnet issue, particularly if you use domain-based security on your network. (You may need the "Alerter" service enabled on certain servers if you are sending messages through the server and not directly to the clients).

The programmatic version of this is an API called NetMessageBufferSend() which is pretty straightforward. A quick scan of P/Invoke.net finds a page for this API that supplies not only the definitions you need to call out to the API, but also a C# sample program!

You shouldn't need to write any client-side code at all. Probably the most involved thing will be figuring out the best set of calls to this API that will get complete coverage of the network in your configuration.

ETA: I just noticed that the Messenger service and this API are completely gone in Windows Vista. Very odd of Microsoft to completely remove functionality like this. It appears that this vendor has a compatible replacement for Vista.

Tim Farley
Thanks Tim, I don't think vista will be a problem as we'll probably be skipping that version ;) I did try out this option but the problem was that I was not able to capture the packet at the client end to prevent the default message box. Should I use packet capture to trap it at the client side?
Tyler
Why do you want to trap it, your question specifies a pop-up message? Well, you could build your own service that does the same thing Messenger does. It's basically using the NETBIOS API to listen for these incoming messages, then firing up a MessageBox.
Tim Farley
The messenger service uses netbios which in turn uses broadcast packets which do not traverse routers...
Kalmi
+3  A: 

This is exactly what Multicast was designed for.

A normal network broadcast (by definition) stays on the local subnet, and will not be forwarded through routers.

Multicast transmissions on the other hand can have various scopes, ranging from subnet local, through site local, even to global. All you need is for the various routers connecting your subnets together to be multicast aware.

Alnitak