0

I have a Windows service that runs some tasks. I need to add some networking functionality to its list of tasks.

Here is what the networking logic will look like:

+-------------------+                                                  +---------------+
|                   |                                    send request  |               |
|                   |                                   for some data  |               |
|                   |  <---------------------------------------------  |               |
|                   |                                                  |               |
|                   |  process request                                 |    Client     |
|  Windows Service  |                                                  |  Application  |
|                   |  send response                                   |               |
|                   |  --------------------------------------------->  |               |
|                   |                                                  |               |
|                   |                                process response  |               |
+-------------------+                                                  +---------------+

NOTE: There can be multiple client applications requesting data simultaneously.

NOTE: Each client application can send multiple requests for data simultaneously.

NOTE: The Windows service and client application could reside within the same network or on separate networks.

Here's the basic layout of the Windows service:

class Processor : System.ServiceProcess.ServiceBase
{
    private System.Timers.Timer Timer1 = null;
    private System.Timers.Timer Timer2 = null;
    private System.Timers.Timer Timer3 = null;

    protected override void OnStart(string[] args)
    {
        Timer1 = new System.Timers.Timer();
        Timer1.Interval = ...;
        Timer1.AutoReset = true;
        Timer1.Elapsed += new ElapsedEventHandler(...);
        Timer1.Start();

        Timer2 = new System.Timers.Timer();
        Timer2.Interval = ...;
        Timer2.AutoReset = true;
        Timer2.Elapsed += new ElapsedEventHandler(...);
        Timer2.Start();

        Timer3 = new System.Timers.Timer();
        Timer3.Interval = ...;
        Timer3.AutoReset = true;
        Timer3.Elapsed += new ElapsedEventHandler(...);
        Timer3.Start();

        // I was thinking of creating a new Task (System.Threading.Tasks.Task) or Timer (System.Timers.Timer) here to handle the networking-related logic.
    }

    protected override void OnStop()
    {
        Timer1.Stop();
        Timer1.Close();

        Timer2.Stop();
        Timer2.Close();

        Timer3.Stop();
        Timer3.Close();
    }
}

I've been reading Microsoft's Network Programming documentation, but I still don't know which class would be best for my situation.

The classes I've been thinking of using are:

The TcpListener and TcpClient classes are wrappers of the Socket class. They seem to hide many of the implementation details and make the code easier to understand. The Socket class seems quite overwhelming with the amount of functionality it provides, but it can handle multiple client connections. Can the TcpListener handle multiple clients or is it only able to listen for one at-a-time?

What networking class would be best for my situation? How can I guarantee the requests will be served in a responsive manner, while also guaranteeing the non-network related tasks will continue without being blocked?

Max Jacob
  • 701
  • 1
  • 9
  • 20
  • 1
    I like your question.. but it's loaded, so I'll just give you my initial thoughts... I would consider using Windows Communication Foundation, it'll let you do everything you want to do, and in a strongly-typed way. As far as blocking, make sure all networking stuff is asynchronous. – rfmodulator Mar 11 '20 at 18:53
  • 1
    When you say "make sure all networking stuff is asynchronous", would spawning the "network object" (whatever it may be) in a separate thread/task/timer suffice? – Max Jacob Mar 11 '20 at 18:56
  • 1
    May be relevant: https://stackoverflow.com/questions/48522849/what-replaces-wcf-in-net-core – chadnt Mar 11 '20 at 18:58
  • 1
    I just mean asynchronous as a general concept (threads, callbacks, whatever makes the sense). This is likely going to involve `async`/`await` against `Tasks` in .NET. `TcpClient` for example, has a `Connect` method and a `ConnectAsync` method, you'll probably favor the later if this is the direction you choose go. – rfmodulator Mar 11 '20 at 19:04
  • @chadnt https://www.dotnetfoundation.org/blog/2019/06/07/welcoming-core-wcf-to-the-net-foundation – rfmodulator Mar 11 '20 at 19:05

2 Answers2

1

NOTE: The Windows service and client application could reside within the same network or on separate networks.

At least here I can give you a semi good answer. The Networking classes do not care if the other end is on the same Computer, the same switch, or the Voyager 2 probe. If it works against localhost, it is generally the Network Administrators job to make sure there is a path.

Getting a service reachable across networks - especially on the internet, unfortuantely goes into Server Hosting. Wich is a totally different topic from programming. The changes nessesary can range from "nothing" to "total change of the server design", depending on the realities of the environment. But it should be more on the "Nothing" side, as it is the Server Admins job to make sure the server is reachable.

Christopher
  • 9,634
  • 2
  • 17
  • 31
0

I did some research and I was wrong. The TcpListener class can handle more than one pending client connection at a time.

Since the messages should remain quite small, the HTTP-related classes seem like overkill.

Since my requirements are relatively simple and I'd rather stick to a simpler design, I'll be using the TcpListener and TcpClient classes.

Max Jacob
  • 701
  • 1
  • 9
  • 20