using System; using System.Net; using System.Collections; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using CookComputing.XmlRpc; using Mono.GetOptions; // hatte keine Lust mir noch ein anderes an zu schauen namespace xml_rpc_deamon { //####################################################################### // Klasse zum Parsen der Kommandozeielenargumente ( mono spezifisch ) class SampleOptions : Options { [Option ("Runn as deamon", 'd')] public bool deamon=false; [Option ("set port who runns on", 'p')] public int port=5678; [Option ("set the ip to bind to", "s")] public string host=null; public SampleOptions() { base.ParsingMode = OptionsParsingMode.Both; } } //####################################################################### // Klasse zum verwalten der Serveranfragen // XML-RPC public class TestServer : MarshalByRefObject { // nachfolgend wird der name der "funktion" benannt // er Aufruf ist dasnn ugefähr http://127.0.0.1/test/test.Running [XmlRpcMethod("test.Running")] public void testRunning() { Console.Error.WriteLine("IS RUNNING"); } // siehe oben [XmlRpcMethod("test.Get")] public string GetTest(int Number) { if (Number < 1 || Number > test_List.Length) return ""; return test_List[Number-1]; } private static string[] test_List={ "test1", "test2", "test3", "test4", "test5" }; } //####################################################################### // Mainklasse public class MainClass { public static void Main (string[] args) { // parsen der Kommadozeilenargumente SampleOptions options = new SampleOptions(); options.ProcessArgs (args); IDictionary props = new Hashtable(); // Name des Prozesses // ist hier nicht wichtig // kann alles drin stehen props["name"] = "MyHttpChannel"; // der Port auf dem gelauscht wird // default 5678 props["port"] = options.port; // auf eine IP begrenzen // default: Alle IPS // wenn eine ungültige IP, // dann localhost (meist 127.0.0.1) if(options.host != null) { IPAddress ip=null; try { ip=IPAddress.Parse(options.host); } catch {} if(ip != null) { props["bindTo"] = ip.ToString(); } else { props["bindTo"] = IPAddress.Loopback.ToString(); } } //Ip:Port belegen und lauschen HttpChannel channel=null; try { //könnte fehl schlagen // ip existiert nicht oder // port ist belegt channel = new HttpChannel(props,null,new XmlRpcServerFormatterSinkProvider()); } catch { //bindTo ignorieren props.Remove("bindTo"); try { // port könnte belegt sein channel = new HttpChannel(props,null,new XmlRpcServerFormatterSinkProvider()); } catch { // aufgeben return; } } ChannelServices.RegisterChannel(channel,false); // Service anmelden. es wird eien Instanz von der Klasse ober erzeugt // und unter "http://127.0.0.1/test/" registriert RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestServer),"test",WellKnownObjectMode.Singleton); // als deamon gestartet // in enen endlosen loop // oder andernfalls // ein paar ausgeben und aur return zum beenden warten if(options.deamon) { // STDIN STDOUT STDERR schließen Console.Out.Close(); //Console.Error.Close(); Console.In.Close(); while(true) System.Threading.Thread.Sleep( 1000 ); } else { Console.WriteLine("Service running as:"); string ip=""; if(props["bindTo"] != null) ip=props["bindTo"].ToString(); Console.WriteLine("http://{0}:{1}/test/",ip,props["port"]); Console.WriteLine("Press to shutdown"); Console.Out.Close(); Console.ReadLine(); } } } }