Webservice for serial port devices - c#

I want to create a remote webservice for an application that is now avaliable only localy. This application controlls three devices (each is controlled separately) connected on serial port. The problem is that I don't know how to take care of passing back information that a device return requested data. For example - I send move command to the motion device (which is very slow and can take a minute or more). Can I just set a big timeout on the client side (and server side) and return for example a true/false if operation is completed or is this a bad idea? Is SOAP with big timeouts ok?
And the other question is if Mono on Linux (Ubuntu 9.10, Mono 2.4) is stable enought for making a web service or should I chose Java or some other language?
I'm open for recommendations.
Thanks for your help!

Using big timeouts is not a good idea. It wastes resources on both the server and the client and you will not be able to detect a "true" timeout condition, when the server is unavailable for example, before the allocated timeout expires.
You really have two options. The first is to use polling. Return immediately from the motion request command, acknowledging the reception of the command (and not the completion of it). Then send requests in regular intervals, asking whether the command is completed or not.
The other alternative requires the client to be able to register a callback endpoint, which the server will call when the motion completes. This makes the whole process asynchronous, but requires the client to be able to operate in server mode. This is very easy to do with WCF - I don't know however if this functionality is available in Mono.

Not directly related to your question..., but consider com0com and its friends hub4com and com2tcp.

Related

CF app two way communications with server

Users in field with PDA's will generate messages and send to the server; users at the server end will generate messages which need to be sent to the PDA.
Messages are between the app and server code; not 100% user entered data. Ie, we'll capture some data in a form, add GPS location, time date and such and send that to the server.
Server may send us messages like updates to database records used in the PDA app, messages for the user etc.
For messages from the PDA to server, that's easy. PDA initiates call to server and passes data. Presently using web services at the server end and "add new web reference" and associated code on the PDA.
I'm coming unstuck trying to get messages from the the server to the PDA in a timely fashion. In some instances receiving the message quickly is important.
If the server had a message for a particular PDA, it would be great for the PDA to receive that within a few seconds of it being available. So polling once a minute is out; polling once a second will generate a lot of traffic and, maybe draim the PDA battery some ?
This post is the same question as mine and suggests http long polling:
Windows Mobile 6.0/6.5 - Push Notification
I've looked into WCF callbacks and they appear to be exactly what I want however, unavailable for compact framework.
This next post isn't for CF but raises issues of service availability:
To poll or not to poll (in a web services context)
In my context i'll have 500-700 devices wanting to communicate with a small number of web services (between 2-5).
That's a lot of long poll requests to keep open.
Is sockets the way to go ? Again that's a lot of connections.
I've also read about methods using exchange or gmail; i'm really hesitant to go down those paths.
Most of the posts i've found here and in google are a few years old; something may have come up since then ?
What's the best way to handle 500-700 PDA CF devices wanting near-instant communication from a server, whilst maintaing battery life ? Tall request i'm sure.
Socket communication seems like the easiest approach. You say you're using webservices for client-server comms, and that is essentially done behind the scenes by the server (webservice) opening a socket and listening for packets arriving, then responding to those packets.
You want to take the same approach in reverse, so each client opens a socket on its machine and waits for traffic to arrive. The client will basically need to poll its own socket (which doesnt incur any network traffic). Client will also need to communicate its ip address and socket to the server so that when the server needs to communicate back to the client it has a means of reaching it. The server will then use socket based comms (as opposed to webservices) to send messages out as required. Server can just open a socket, send message, then close socket again. No need to have lots of permanently open sockets.
There are potential catches though if the client is roaming around and hopping between networks. If this is the case then its likely that the ip address will be changing (and client will need to open a new socket and pass the new ip address/socket info to the server). It also increases the chances that the server will fail to communicate with the client.
Sounds like an interesting project. Good luck!
Ages ago, the CF team built an application called the "Lunch Launcher" which was based on WCF store-and-forward messaging. David Kline did a nice series on it (here the last one, which has a TOC for all earlier articles).
There's an on-demand Webcast on MSDN given by Jim Wilson that gives an outline of store-and-forward and the code from that webcast is available here.
This might do what you want, though it got some dependencies (e.g. Exchange) and some inherent limitations (e.g. no built-in delivery confirmation).
Ok, further looking and I may be closer to what I want; which I think i a form of http long poll anyway.
This article here - http://www.codeproject.com/KB/IP/socketsincsharp.aspx - shows how to have a listener on a socket. So I do this on the server side.
Client side then opens a socket to the server at this port; sends it's device ID.
Server code first checks to see if there is a response for that device. If there is, it responds.
If not, it either polls itself or subscribes to some event; then returns when it's got data.
I could put in place time out code on the server side if needed.
Blocking on the client end i'm not worried about because it's a background thread and no data is the same as blocking at the app level; as to CPU & batter life, not sure.
I know what i've written is fairly broad, but is this a strategy worth exploring ?

Fast way to check if a server is accessible over the network in C#

I've got a project where I'm hitting a bunch of custom Windows Performance Counters on multiple servers and aggregating them into a database. If a server is down, I want to skip it, and just continue on with my day.
Currently I'm checking to see if a server is live by doing a DirectoryInfo on a share that I've got to look at later in the process anyways, then checking the .Exists property.This is my current code snippet for testing:
DirectoryInfo di = new DirectoryInfo(machine.Share_Path);
if (!di.Exists)
{
log.Warn("Could not access " + machine.Name + "! Maybe its down?");
continue; // Skips to the next server in my loop where this snippet exists.
}
This works, but its pretty slow. It takes about 68 seconds on average for the di.Exists bit to finish its work, and I ideally need to know within a second whether or not a server is accessible. Pinging also isn't an option since a server can be pingable but not "live" in our environment.
I'm still kind of fresh to the .NET world, so I'm open to any advice people can offer.
Thanks in advance.
-Weegee
Ping First, Ask Questions Later
Why not ping first, and then do the di.Exists if you get a response?
That would allow you to fail early in the case that is not reachable, and not waste the time for machines that are down hard.
I have, in fact, used this method successfully before.
MSDN Ping Documentation
Paralellize
Another option you have is to paralellize the checking, and action on the servers as they are known to be available.
You could use the Paralell.ForEach() method, and use a thread-safe queue along with a simple consumer thread to do the required action. Combined with the checking method above, this could alleviate almost all of your bottleneck on the up/down checking.
Knock on the Door
Yet another method would be to ckeck if the required remote service is running (either by hitting its port directly or by querying it with WMI).
Since WMI is almost always running when a machine is up, your connection should be very quick to either succeed or fail.
The only "quick" way I think to see if it's up without relying on ping would be to create a socket, and see if you can actually connect to the port of the service you're trying to reach.
This would be the equivalent of telnet servername 135 to see if it's up.
Specifically...
Create a .NET TCP socket client (System.Net.Sockets.TcpClient)
Call BeginConnect() as an asynchronous operation, to connect to the server in question on one of the RPC ports that your directory exists code would use anyway (TCP 135, 139, or 445).
If you don't hear back from it within X milliseconds, call Close() to cancel the connection.
Disclaimer: I have no idea what effect this would have on any threat/firewall protection that may see this type of Connect / Disconnect with no data sent activity as a threat.
Opening Socket to a specific port usually does the trick. If you really want it to be fast, be sure to set the NoDelay property on the new socket (Nagle algorithm) so there is no buffering.
Fast will largely depend on latency but this is probably the fastest way I know to connect to an endpoint. It's pretty simple to parallelize using the async methods. How fast you can check will largely depend on your network topology but in tests for 1000 servers (latency between 0-75ms) I've been able to get connectivity state in ~30 seconds. Not scientific data at all but should give you the idea.
Also, don't ever do this through UNC file shares because if the server no longer exists you will have a lot of dangling connections that take forever to timeout. So if you have a lot of servers with invalid DNS records and you try to poll them you will bring Windows down completely over time. Things like File.Exists and any file access will cause this.
The "Full-Blown" option would be to install a monitoring tool like SCOM (System Center Operations Manager), this has an SDK you can use to query SCOM for (performance) and maintenance information avout machines being monitored. Might be a bridge to far though....
Telnet is another option. Try telnetting to the target machine to see if it responds.
Create a small Windows Service that you install on your target machine, have the sys admin stop it when they perform maintenance on the target machine (just use batch file to net stop / net start the service)

Driving events across custom TCP Long-Polling server

I’m trying to write a custom TCP based long polling server that will serve as a go-between for other TCP connections that require more persistence than a mobile phone can provide.
The way I’m trying to do it is writing an asynchronous TCP server in C# and a matching TCP Client also written in C#.
The way that long polling works (as far as I understand it) is that you open a TCP connection to a server, and the server Halts before sending data back across the socket. You find a Heartbeat interval that works on a mobile phone network (I’ve heard that around 8 minutes works?) and you send an empty packet if there is no updated data.
This is where my trouble comes in. I can’t figure out how to “link” my client’s request for data with an event handler running on the server…
The flow should be something like this (“client” is on a phone):
User starts my application
Client sends a request to be notified if data has changed
Server “links” (registers) client’s socket object into an “Event handler” that is called by the server’s other TCP connections that I talked about!
Event
o If it is triggered (new data has arrived), Send the data to the client
o If it isn’t triggered (no new data), Send an “EmptyChanges” packet to client
Client receives data on the phone and processes it (calls an event handler based on what type of packet it received and passes the “data” it got from the server to it)
Client sends a request to be notified if data has changed
So, my problem is that I can’t think of a design that will accomplish what I want it to do. The problem is that I don’t know HOW to do #3. How do I “Link” one event handler from another? And these are almost guaranteed to be running on different threads!
So, my application would look something like this (all psuedocode):
Class AppClass
{
Main()
List<Client> clients;
List<DataServers> dataServers;
DataReceivedFromServer(Data stuff)
{
}
MessageReceivedFromPhone(PhoneMessage pm, object sender)
{
//Loop here until HeartBeat interval reached
Int totalTime = 0;
While(totalTime < HEARTBEAT_INTERVAL)
{
If( ) // If we have received data from the server, and the client WANTED that data, send it now
{
}
}
}
}
Kind of? I want it to be event driven, but I'm having the damndest time figuring out how to drive the application with a PUSH driven style vs. what I'm "used" to of Polling.
Please, be kind as I might be doing something overly complicated and stupid because this is my first real attempt at using Socket programming (never needed it) and it's especially hard due to the nature of Cell phones being on transient networks and my server needing to maintain the location of these phones with an OPEN TCP connection.
Server platform: Windows
Server language: C#
Test Client platform: Windows
Test Client language: C#
Target Client platform: Windows Mobile 6.5, iPhone, Android (clients will be written separately)
Target client language: C#, Obj-C or MonoTouch, Java
Just anyone wondering this, I trashed the idea of writing a custom TCP server to manage my connections. There was so much overhead in doing that, I'd basically be replicating writing my own HTTP server, so instead of doing that, I went with the Web Tornado framework in Python as my server and am writing the back end services to communicate through HTTP requests in Web Tornado.
Instead of using Long polling at all, I'm going to use SMS for push notifications. I believe all of the major phone platforms implement something similar to an SMS Interceptor that you write... if an SMS of a certain format comes through, it will run your custom code. This allows me to remove the requirements of using consistent open connections (other than for live chat, which will use a comet style Long poll, but the connection can only remain open if active for about 5 minutes.)
Basically, the Web Tornado framework is serving as an Enterprise bus in my architecture.

Whats the best way to send an event to all workstations

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
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.
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.
This problem i think is best solved with socket.
Open a connection to the server, and keep it open.
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.
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.

Asynchronous multi-direction server-client communication over the same open socket?

I have a client-server app where the client is on a Windows Mobile 6 device, written in C++ and the server is on full Windows and written in C#.
Originally, I only needed it to send messages from the client to the server, with the server only ever sending back an acknowledgement that it received the message. Now, I would like to update it so that the server can actually send a message to the client to request data. As I currently have it set up so the client is only in receive mode after it sends data to the server, this doesn't allow for the server to send a request at any time. I would have to wait for client data. My first thought would be to create another thread on the client with a separate open socket, listening for server requests...just like the server already has in respect the client. Is there a way, within the same thread and using the same socket, to all the server to send requests at any time?
Can you use something to the effect of WaitForMultipleObjects() and pass it a receive buffer and an event that tells it there is data to be sent?
When I needed to write an application with a client-server model where the clients could leave and enter whenever they want, (I assume that's also the case for your application as you use mobile devices) I made sure that the clients send an online message to the server, indicating they were connected and ready to do whatever they needed doing.
at that time the server could send messages back to the client trough the same open connection.
Also, but I don't know if that is applicable for you, I had some sort of heartbeat the clients sent to the server, letting it know it was still online. That way the server knows when a client was forcibly disconnected from the network and it could mark that client back as offline.
Using asynchronous communication is totally possible in single thread!
There is a common design pattern in network software development called the reactor pattern (look at this book). Some well known network library provides an implementation of this pattern (look at ACE).
Briefly, the reactor is an object, you register all your sockets inside, and you wait for something. If something happened (new data arrived, connection close...) the reactor will notify you. And of course, you can use only one socket to send and received data asynchronously.
I'm not clear on whether or not you're wanting to add the asynchronous bits to the server in C# or the client in C++.
If you're talking about doing this in C++, desktop Windows platforms can do socket I/O asynchronously through the API's that use overlapped I/O. For sockets, WSASend, WSARecv both allow async I/O (read the documentation on their LPOVERLAPPED parameters, which you can populate with events that get set when the I/O completes).
I don't know if Windows Mobile platforms support these functions, so you might have to do some additional digging.
Check out asio. It is a cross compatable c++ library for asyncronous IO. I am not sure if this would be useful for the server ( I have never tried to link a standard c++ DLL to a c# project) but for the client it would be useful.
We use it with our application, and it solved most of our IO concurrency problems.

Categories