• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 283
  • Last Modified:

What's the best practice for TCP console applications launched by a service?

Hello experts.  I have a program that runs as a windows service.  It will be used as a "host server" for which a Controller will connect to it via Silverlight on a particular port and will send a command to launch/close another TCP server which is created from a Win32 Console Application.  Several instances of this console application can be created by the running service.  I do not need to see any output on this console application because it is managed by the running service and using C#'s "Process" class and I will probably have it write the status to the event log or some other log for monitoring.  I actually have two questions for this.

1)  Is creating this other TCP server as a console application the best method?
internal int CreateAuctionProcess()
{
            
    Process auction = new Process();
    auction.StartInfo.FileName = _auctionServerFileName;
    auction.StartInfo.WorkingDirectory = _workingDirectory;
    auction.StartInfo.RedirectStandardInput = true;
    auction.StartInfo.UseShellExecute = false;
    auction.EnableRaisingEvents = true;
    auction.Exited += new EventHandler(auction_Exited);

    try
    { 
        auction.Start();

        lock (_auctionServers)
        {
            _auctionServers.Add(auction);
        }

        return auction.Id;
    }
    catch (Exception ERROR)
    {
#if DEBUG
            eventLog1.WriteEntry("Failed to create auction process.\nERROR: " + ERROR.ToString(), EventLogEntryType.Error);
#else
            eventLog1.WriteEntry("Failed to create auction process.\nThe error given was: " + ERROR.Message, EventLogEntryType.Error);
#endif
    }

    return -1;
}

Open in new window


2) For this console TCP server application... I don't want to be forced to "Kill" the application because I want to make sure the exit cleanup code executes, so I redirect the input for the process and have the server polling for a NewLine input which I pass to it in order to close it.  Is there another way to poll for closing this without force-killing it?  Using the Process.Close() sends the event for it to close but it's blocked polling for input.

Here's the code for the console application
public static void Main(string[] args)
{
    KaidAuctionServer auctionServer = new KaidAuctionServer();
    auctionServer.Start();
    Console.WriteLine("Auction server started.");

    Console.WriteLine("Press Enter to exit.");

    // New line character shuts down the server
    Console.ReadLine();

    auctionServer.Stop();
    Console.WriteLine("Auction server shut down.");
}

Open in new window


Here's the code for stopping the process.
 
internal void StopAuctionProcess()
{
    lock (_auctionServers)
    {
        if (_auctionServers.Count > 0)
        {
            try
            {
                Process auction = _auctionServers[0];

                StreamWriter writer = auction.StandardInput;
                writer.WriteLine();
                writer.Flush();

                auction.Close();

                lock (_auctionServers)
                {
                    _auctionServers.Remove(auction);
                }
                        
                auction.Dispose();
            }
            catch (Exception ERROR)
            {
#if DEBUG
                eventLog1.WriteEntry("Failed to stop auction process.\nERROR: " + ERROR.ToString(), EventLogEntryType.Error);
#else
                eventLog1.WriteEntry("Failed to stop auction process.\nThe error given was: " + ERROR.Message, EventLogEntryType.Error);
#endif
            }
        }
        else
        {
            eventLog1.WriteEntry("Attempted to stop auction proccess when no process was running.");
        }
    }
}

Open in new window


All of this works fine now, but when it's under load and launching several servers and closing them... is this a good efficient way?  I didn't want to use a windows forms application (though it would look for windows events) because of the unnecessary resources loaded.
0
Astynax777
Asked:
Astynax777
  • 4
  • 3
1 Solution
 
brutaldevCommented:
Change your console application to a Windows Service and use WCF. You can create a TCP endpoint and your service will automatically deal with multiple concurrent requests without having to start a new application each time.

Your client application that can generate a proxy automatically to connect to your new service's endpoint by using the "Add Service Reference" option in Visual Studio. This will greatly reduce your code and make things a lot easier once you get the hand of it.
0
 
Astynax777Author Commented:
Well the reason I created a separate application was because I can pass in parameters to each instance (which I didn't show in my code because I haven't reached that point yet) and because I can terminate individual servers without affecting any other servers.  Looking down the road I could also expand my program to launch servers individually on different servers for load balancing.

As for the WCF - I have seriously been considering using that - as I have very little experience with networking and it seems to encapsulate it well.  I am ordering a book now to learn it so I can utilize.  Networking and Threading are not my strong points but I am working to try to maintain best practices in both.
0
 
brutaldevCommented:
When you create your service contract interface just provide a bunch of overloads that you can call just like the parameters you are passing into your new process. You app will be completely type-safe. You can configure your WCF service to be a singleton so a new instance is created for each request but without the headache of new processes.

Add a new project and look for WCF Service, it will provide you with tons of boiler-plate code to get this working in no time. Generate the proxy in another app to create an instance and call it. There is also a WCF configuration utility (so you don't even need to look at XML) under Tools in VS to setup your TCP endpoint. Happy coding!
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Astynax777Author Commented:
Ok.  This sounds like it has great potential.  So to clarify: I will be able to have a service running which can

1)  Allow multiple Controllers to connect to it and start/stop these other servers

2)  The servers created by the service can be run as a new "instance" (which I assume won't show up in task manager?) and listen on separate ports for clients to connect to.

3) The instances of each server created by the service can be run independently so that if any of them crash it won't affect the others or the service.

You're saying this can all be accomplished under a single running service without separate applications being launched by the service?
 The plan...
0
 
brutaldevCommented:
1) WCF allows many users to connect concurrently and manages request queuing. You wouldn't need to start or stop anything. While the single service is running, it will just wait for requests.

2) The service acts like the server portion of your application. You can add as many different endpoints with different ports and even different protocols that your WCF service can expose.

3) An instance of your service contract class is created and if something crashes it will not bring down the service. The Windows Service merely acts as a host for your WCF service.

So yes, the plan looks good. Think of IIS, it's one worker process to handle multiple web requests through one or more ports.

Getting started with WCF
0
 
Astynax777Author Commented:
I'm gonna attempt the WCF method but it's very murky water for me with all this publish/subscribe and the msn documentation is not very helpful to me.  Neither is the book that I got.  Thanks for your help!
0
 
brutaldevCommented:
The best way to learn is to actually do it. I was also apprehensive when it came to this new technology and took a little time to get used to, then you wonder how you ever lived without it. Glad I could help, I'm sure you'll find that experience with WCF is extremely useful.
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now