// This file automatically generated by:
//   Apache Etch 1.1.0-incubating (LOCAL-0) / csharp 1.1.0-incubating (LOCAL-0)
//   Mon Feb 16 11:13:50 CST 2009
// This file is automatically created for your convenience and will not be
// overwritten once it exists! Please edit this file as necessary to implement
// your service logic.

using System;

using Org.Apache.Etch.Bindings.Csharp.Support;
using Org.Apache.Etch.Bindings.Csharp.Util;

using org.apache.etch.interoptester.example.iot.types.IOT;

namespace org.apache.etch.interoptester.example.iot
{
	///<summary>Main implementation for IOTListener.</summary>
	public class MainIOTListener : IOTHelper.IOTServerFactory
	{
 		///<summary>Main for IOTListener.</summary>
		///<param name="args">Command Line Arguments</param>
		public static void Main(String[] args)
        {
            if (args.Length > 1)
            {
                Console.WriteLine("usage: MainIOTListener [uri]");
                return;
            }
		
            string uri = args.Length > 0 ? args[0] : "tcp://localhost:4001";
			
			ServerFactory listener = IOTHelper.NewListener( uri, null, new MainIOTListener());
			
			// Start the Listener
			listener.TransportControl( TransportConsts.START_AND_WAIT_UP, 4000 );
            Console.WriteLine( "listener started: "+listener );
		}

		///<summary>Return a new instance of IOTServer.</summary>
		///<param name="client">Reference to remote service</param>
		///<returns>Server Implementation</returns>
		public IOTServer NewIOTServer( RemoteIOTClient client )
		{
			return new ImplIOTServer( client );
		}
	}
}