**AMPSharp** - An AMP library for Mono and Microsoft .NET ===================================================== * 100% managed C# code * Client and Server * Extensive unit-test coverage * Runs with Microsoft .NET or Mono * Blocking and Non-Blocking (asynchronous) interfaces * Full set of AMP data types * Packaged in Debian unstable as of September, 2011 * Packaged via NuGet Code and downloads are hosted on Launchpad: +++++++++++++++++++++++++++++++++++++++++++ * ``_ Examples ++++++++ Server for a ``Sum`` and ``Divide`` command:: using System; using System.Net; using System.Net.Sockets; using System.Text; namespace MathServer { class Server { static void Main(string[] args) { int port = 1234; var listener = new TcpListener(port); listener.Start(5); Console.WriteLine("Listening on port {0}", port); TcpClient client; AMP.Protocol protocol; // the AMP.Command's we're going to respond to var sum = new Sum(); var div = new Divide(); while (true) { client = listener.AcceptTcpClient(); protocol = new AMP.Protocol(client.GetStream()); // we could also pass a 'state' argument to RegisterResponder // which becomes the 'state' argument in the responders (below). // Since we aren't passing anything, then state will always be null protocol.RegisterResponder(sum, handleSum); protocol.RegisterResponder(div, handleDivide); protocol.StartReading(); // start the async data-reading loop } } static Object handleSum(AMP.Msg reqMsg, Object state) { int a = (int)reqMsg["a"]; int b = (int)reqMsg["b"]; int total = a + b; Console.WriteLine("Did a sum: {0} + {1} = {2}", a, b, total); return new AMP.Msg {{"total", total}}; } static Object handleDivide(AMP.Msg reqMsg, Object state) { int numerator = (int)reqMsg["numerator"]; int denominator = (int)reqMsg["denominator"]; decimal result = (decimal)numerator / denominator; Console.WriteLine("Did a division: {0} / {1} = {2}", numerator, denominator, result); return new AMP.Msg { { "result", result } }; } } public class Sum: AMP.Command { public Sum() : base("Sum") { AMP.IAmpType int32 = new AMP.Type.Int32(); AddArgument("a", int32); AddArgument("b", int32); AddResponse("total", int32); } } public class Divide : AMP.Command { public Divide() : base("Divide") { AMP.IAmpType int32 = new AMP.Type.Int32(); AMP.IAmpType dec = new AMP.Type.Decimal(); AddArgument("numerator", int32); AddArgument("denominator", int32); AddResponse("result", dec); AddError(typeof(DivideByZeroException), Encoding.UTF8.GetBytes("ZERO_DIVISION")); } } } Client code that excersies ``Sum`` and ``Divide`` commands in various ways:: using System; using System.Net.Sockets; using System.Threading; namespace MathClient { class Client { static void Main(string[] args) { string hostname = "localhost"; int port = 1234; var client = new TcpClient(hostname, port); var protocol = new AMP.Protocol(client.GetStream()); protocol.StartReading(); // start the async data-reading loop // Instantiate the Commands we're going to call AMP.Command sum = new MathServer.Sum(); AMP.Command div = new MathServer.Divide(); // Make one remote call synchronously. CallRemote() will raise an exception if // anything goes wrong making the call. AMP.Msg msg = protocol.CallRemote(sum, new AMP.Msg { { "a", 5 }, { "b", 7 } }); Console.WriteLine("Got sum result: {0}", (int)msg["total"]); Thread.Sleep(2000); // Now make some asynchronous calls in a loop int count = 3; while (count-- > 0) { // pass the AMP.Protocol object though as the `state' parameter since we need it in the callback protocol.BeginCallRemote(sum, new AMP.Msg { { "a", 13 }, { "b", 81 } }, CBGotSumResponse, protocol); Thread.Sleep(2000); } // Do a division try { msg = protocol.CallRemote(div, new AMP.Msg { { "numerator", 10 }, { "denominator", 3 } }); } catch (DivideByZeroException) { System.Console.WriteLine("Shouldn't have caused zero division here!"); return; } Console.WriteLine("Got division result: {0}", (decimal)msg["result"]); // Now do it again, but this time cause a DivideByZeroException on the remote end, // which will result in a DivideByZeroException being raised here, because the // Divide command has been implemented to handle this particular Exception. try { msg = protocol.CallRemote(div, new AMP.Msg { { "numerator", 10 }, { "denominator", 0 } }); } catch (DivideByZeroException) { System.Console.WriteLine("Got DivideByZeroException as expected."); } Console.ReadKey(); // Press any key to continue... } // Call-back method for receiving result from server asynchronously static void CBGotSumResponse(IAsyncResult ar) { var protocol = (AMP.Protocol)ar.AsyncState; // EndCallRemote() will raise if any error occured during the remote call AMP.Msg respMsg = protocol.EndCallRemote(ar); Console.WriteLine("Got sum: {0}", (int)respMsg["total"]); } } }