diff --git a/ZeroLevel.UnitTests/NetworkTest.cs b/ZeroLevel.UnitTests/NetworkTest.cs new file mode 100644 index 0000000..82b6655 --- /dev/null +++ b/ZeroLevel.UnitTests/NetworkTest.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using Xunit; +using ZeroLevel.Network; + +namespace ZeroLevel.UnitTests +{ + public class NetworkTest + { + [Fact] + public void ClientServerTest() + { + // Arrange + var server = ExchangeTransportFactory.GetServer(8181); + var client = ExchangeTransportFactory.GetClient("127.0.0.1:8181"); + + bool got_message_no_request = false; + bool got_message_with_request = false; + bool got_response_message_no_request = false; + bool got_response_message_with_request = false; + + using (var signal = new ManualResetEvent(false)) + { + server.RegisterInbox("empty", (_, __) => { signal.Set(); got_message_no_request = true; }); + server.RegisterInbox((_, __, ___) => { signal.Set(); got_message_with_request = true; }); + server.RegisterInbox("get_response", (_, __) => { return "Hello"; }); + server.RegisterInbox("convert", (num, _, __) => { return num.ToString(); }); + + // Act + signal.Reset(); + client.Send("empty"); + signal.WaitOne(1000); + + signal.Reset(); + client.Send("hello"); + signal.WaitOne(100); + + signal.Reset(); + client.Request("get_response", (s) => { signal.Set(); got_response_message_no_request = s.Equals("Hello", StringComparison.Ordinal); }); + signal.WaitOne(1000); + + signal.Reset(); + client.Request("convert", 10, (s) => { signal.Set(); got_response_message_with_request = s.Equals("10", StringComparison.Ordinal); }); + signal.WaitOne(1000); + } + + + + // Assert + Assert.True(got_message_no_request, "No signal for no request default inbox"); + Assert.True(got_message_with_request, "No signal for default inbox"); + Assert.True(got_response_message_no_request, "No response without request"); + Assert.True(got_response_message_with_request, "No response with request"); + } + } +} diff --git a/ZeroLevel/Services/Network/Contract/IExClient.cs b/ZeroLevel/Services/Network/Contract/IExClient.cs index 183d711..6593b83 100644 --- a/ZeroLevel/Services/Network/Contract/IExClient.cs +++ b/ZeroLevel/Services/Network/Contract/IExClient.cs @@ -15,6 +15,10 @@ namespace ZeroLevel.Network IPEndPoint Endpoint { get; } + InvokeResult Send(); + + InvokeResult Send(string inbox); + InvokeResult Send(T obj); InvokeResult Send(string inbox, T obj); diff --git a/ZeroLevel/Services/Network/Contract/IExService.cs b/ZeroLevel/Services/Network/Contract/IExService.cs index 8b47f9a..8c8a677 100644 --- a/ZeroLevel/Services/Network/Contract/IExService.cs +++ b/ZeroLevel/Services/Network/Contract/IExService.cs @@ -12,6 +12,8 @@ namespace ZeroLevel.Network void RegisterInbox(string inbox, Action handler); + void RegisterInbox(string inbox, Action handler); + void RegisterInbox(string inbox, Func handler); /// @@ -19,9 +21,10 @@ namespace ZeroLevel.Network /// void RegisterInbox(string inbox, Func handler); -/* -DEFAULT INBOXES -*/ + /* + DEFAULT INBOXES + */ + void RegisterInbox(Action handler); void RegisterInbox(Action handler); void RegisterInbox(Func handler); void RegisterInbox(Func handler); diff --git a/ZeroLevel/Services/Network/Services/ExClient.cs b/ZeroLevel/Services/Network/Services/ExClient.cs index ac665ec..8beba54 100644 --- a/ZeroLevel/Services/Network/Services/ExClient.cs +++ b/ZeroLevel/Services/Network/Services/ExClient.cs @@ -110,5 +110,15 @@ namespace ZeroLevel.Network { return Send(inbox, obj); } + + public InvokeResult Send() + { + return _fe.Send(DEFAULT_MESSAGE_INBOX); + } + + public InvokeResult Send(string inbox) + { + return _fe.Send(inbox); + } } } \ No newline at end of file diff --git a/ZeroLevel/Services/Network/Services/ExRouter.cs b/ZeroLevel/Services/Network/Services/ExRouter.cs index b4aa9fa..d02f0a2 100644 --- a/ZeroLevel/Services/Network/Services/ExRouter.cs +++ b/ZeroLevel/Services/Network/Services/ExRouter.cs @@ -45,8 +45,21 @@ namespace ZeroLevel.Network private Invoker _invoker; private Type _typeReq; private Type _typeResp; + private bool _noArguments = false; - public static MRInvoker Create(string inbox, Action handler) + public static MRInvoker Create(Action handler) + { + return new MRInvoker + { + _noArguments = true, + _typeReq = null, + _typeResp = null, + _instance = handler.Target, + _invoker = CreateCompiledExpression(handler) + }; + } + + public static MRInvoker Create(Action handler) { return new MRInvoker { @@ -57,7 +70,7 @@ namespace ZeroLevel.Network }; } - public static MRInvoker Create(string inbox, Func handler) + public static MRInvoker Create(Func handler) { return new MRInvoker { @@ -68,7 +81,7 @@ namespace ZeroLevel.Network }; } - public static MRInvoker Create(string inbox, Func handler) + public static MRInvoker Create(Func handler) { return new MRInvoker { @@ -84,7 +97,14 @@ namespace ZeroLevel.Network if (_typeResp == null) { var incoming = MessageSerializer.DeserializeCompatible(_typeReq, frame.Payload); - this._invoker.Invoke(this._instance, new object[] { incoming, frame.FrameId, client }); + if (_noArguments) + { + this._invoker.Invoke(this._instance, new object[] { frame.FrameId, client }); + } + else + { + this._invoker.Invoke(this._instance, new object[] { incoming, frame.FrameId, client }); + } } else if (_typeReq == null) { @@ -109,20 +129,29 @@ namespace ZeroLevel.Network #region Registration + public void RegisterInbox(string inbox, Action handler) + { + if (false == _handlers.ContainsKey(inbox)) + { + _handlers.Add(inbox, new List()); + } + _handlers[inbox].Add(MRInvoker.Create(handler)); + } + public void RegisterInbox(string inbox, Action handler) { if (false == _handlers.ContainsKey(inbox)) { _handlers.Add(inbox, new List()); } - _handlers[inbox].Add(MRInvoker.Create(inbox, handler)); + _handlers[inbox].Add(MRInvoker.Create(handler)); } public void RegisterInbox(string inbox, Func hanlder) { if (false == _requestors.ContainsKey(inbox)) { - _requestors.Add(inbox, MRInvoker.Create(inbox, hanlder)); + _requestors.Add(inbox, MRInvoker.Create(hanlder)); } else { @@ -134,7 +163,7 @@ namespace ZeroLevel.Network { if (false == _requestors.ContainsKey(inbox)) { - _requestors.Add(inbox, MRInvoker.Create(inbox, hanlder)); + _requestors.Add(inbox, MRInvoker.Create(hanlder)); } else { diff --git a/ZeroLevel/Services/Network/Services/ExService.cs b/ZeroLevel/Services/Network/Services/ExService.cs index 8b13dc7..ab6f168 100644 --- a/ZeroLevel/Services/Network/Services/ExService.cs +++ b/ZeroLevel/Services/Network/Services/ExService.cs @@ -96,6 +96,16 @@ namespace ZeroLevel.Network _router.RegisterInbox(DEFAULT_REQUEST_INBOX, handler); } + public void RegisterInbox(string inbox, Action handler) + { + _router.RegisterInbox(inbox, handler); + } + + public void RegisterInbox(Action handler) + { + _router.RegisterInbox(DEFAULT_REQUEST_INBOX, handler); + } + public override void Dispose() { _server.Dispose(); diff --git a/ZeroLevel/Services/Network/Services/FrameExchange.cs b/ZeroLevel/Services/Network/Services/FrameExchange.cs index e259e04..1a8f1c8 100644 --- a/ZeroLevel/Services/Network/Services/FrameExchange.cs +++ b/ZeroLevel/Services/Network/Services/FrameExchange.cs @@ -31,6 +31,21 @@ namespace ZeroLevel.Network } } + public InvokeResult Send(string inbox) + { + try + { + var frame = FrameBuilder.BuildFrame(inbox); + _current.Send(frame); + return InvokeResult.Succeeding(); + } + catch (Exception ex) + { + Log.SystemError(ex, "[FrameExchange] Fault send frame"); + return InvokeResult.Fault(ex.Message); + } + } + public InvokeResult Send(Frame frame) { try