diff --git a/Editor/UniNetty.Editor/UniNetty.Editor.asmdef b/Editor/UniNetty.Editor/UniNetty.Editor.asmdef index a9c4190..d96b296 100644 --- a/Editor/UniNetty.Editor/UniNetty.Editor.asmdef +++ b/Editor/UniNetty.Editor/UniNetty.Editor.asmdef @@ -26,7 +26,8 @@ "UniNetty.Examples.Telnet.Client", "UniNetty.Examples.Telnet.Server", "UniNetty.Examples.WebSockets.Client", - "UniNetty.Examples.WebSockets.Server" + "UniNetty.Examples.WebSockets.Server", + "UniNetty.Examples.DemoSupports" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Examples/UniNetty.Examples.DemoSupports/AnonymousDisposer.cs b/Examples/UniNetty.Examples.DemoSupports/AnonymousDisposer.cs new file mode 100644 index 0000000..1699d61 --- /dev/null +++ b/Examples/UniNetty.Examples.DemoSupports/AnonymousDisposer.cs @@ -0,0 +1,52 @@ +using System; + +namespace UniNetty.Examples.DemoSupports +{ + internal class AnonymousDisposer : IDisposable + { + private Action _action; + private bool _disposed; + private readonly object _lock = new object(); + + public static IDisposable Create(Action action) + { + return new AnonymousDisposer(action); + } + + private AnonymousDisposer(Action action) + { + _action = action ?? throw new ArgumentNullException(nameof(action)); + } + + ~AnonymousDisposer() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + bool needToDispose = false; + lock (_lock) + { + if (!_disposed) + { + needToDispose = true; + _disposed = true; + } + } + + if (needToDispose) + { + var temp = _action; + _action = null; + temp.Invoke(); + } + } + } +} \ No newline at end of file diff --git a/Examples/UniNetty.Examples.DemoSupports/ExampleContext.cs b/Examples/UniNetty.Examples.DemoSupports/ExampleContext.cs new file mode 100644 index 0000000..10b046c --- /dev/null +++ b/Examples/UniNetty.Examples.DemoSupports/ExampleContext.cs @@ -0,0 +1,209 @@ +using System; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using UniNetty.Examples.Discard.Client; +using UniNetty.Examples.Discard.Server; +using UniNetty.Examples.Echo.Client; +using UniNetty.Examples.Echo.Server; +using UniNetty.Examples.Factorial.Client; +using UniNetty.Examples.Factorial.Server; +using UniNetty.Examples.HttpServer; +using UniNetty.Examples.QuoteOfTheMoment.Client; +using UniNetty.Examples.QuoteOfTheMoment.Server; +using UniNetty.Examples.SecureChat.Client; +using UniNetty.Examples.SecureChat.Server; +using UniNetty.Examples.Telnet.Client; +using UniNetty.Examples.Telnet.Server; +using UniNetty.Examples.WebSockets.Client; +using UniNetty.Examples.WebSockets.Server; + +namespace UniNetty.Examples.DemoSupports +{ + public class ExampleContext + { + public X509Certificate2 Cert { get; private set; } + + public void SetCertificate(X509Certificate2 cert) + { + Cert = cert; + } + + // discard + public IDisposable RunDiscardServer(ExampleSetting setting) + { + var server = new DiscardServer(); + _ = server.StartAsync(Cert, setting.Port); + + return AnonymousDisposer.Create(() => + { + _ = server.StopAsync(); + }); + } + + public IDisposable RunDiscardClient(ExampleSetting setting) + { + var client = new DiscardClient(); + _ = client.StartAsync(Cert, IPAddress.Parse(setting.Ip), setting.Port, setting.Size); + + return AnonymousDisposer.Create(() => + { + _ = client.StopAsync(); + }); + } + + + // echo + public IDisposable RunEchoServer(ExampleSetting setting) + { + var server = new EchoServer(); + _ = server.StartAsync(Cert, setting.Port); + + return AnonymousDisposer.Create(() => + { + _ = server.StopAsync(); + }); + } + + public IDisposable RunEchoClient(ExampleSetting setting) + { + var client = new EchoClient(); + _ = client.StartAsync(Cert, IPAddress.Parse(setting.Ip), setting.Port, setting.Size); + return AnonymousDisposer.Create(() => + { + _ = client.StopAsync(); + }); + } + + // factorial + public IDisposable RunFactorialServer(ExampleSetting setting) + { + var server = new FactorialServer(); + _ = server.StartAsync(Cert, setting.Port); + + return AnonymousDisposer.Create(() => + { + _ = server.StopAsync(); + }); + } + + public IDisposable RunFactorialClient(ExampleSetting setting) + { + var client = new FactorialClient(); + _ = client.StartAsync(Cert, IPAddress.Parse(setting.Ip), setting.Port, setting.Count); + + + return AnonymousDisposer.Create(() => + { + _ = client.StopAsync(); + }); + } + + // QuoteOfTheMoment + public IDisposable QuoteOfTheMomentServer(ExampleSetting setting) + { + var server = new QuoteOfTheMomentServer(); + _ = server.StartAsync(setting.Port); + return AnonymousDisposer.Create(() => + { + _ = server.StopAsync(); + }); + } + + public IDisposable RunQuoteOfTheMomentClient(ExampleSetting setting) + { + var client = new QuoteOfTheMomentClient(); + _ = client.StartAsync(setting.Port); + + return AnonymousDisposer.Create(() => + { + _ = client.StopAsync(); + }); + } + + // secure + public IDisposable RunSecureChatServer(ExampleSetting setting) + { + var server = new SecureChatServer(); + _ = server.StartAsync(Cert, setting.Port); + return AnonymousDisposer.Create(() => + { + _ = server.StopAsync(); + }); + } + + public IDisposable RunSecureChatClient(ExampleSetting setting) + { + var client = new SecureChatClient(); + _ = client.StartAsync(Cert, IPAddress.Parse(setting.Ip), setting.Port); + return AnonymousDisposer.Create(() => + { + _ = client.StopAsync(); + }); + } + + // + public IDisposable RunTelnetServer(ExampleSetting setting) + { + var server = new TelnetServer(); + _ = server.StartAsync(Cert, setting.Port); + + return AnonymousDisposer.Create(() => + { + _ = server.StopAsync(); + }); + } + + + public IDisposable RunTelnetClient(ExampleSetting setting) + { + var client = new TelnetClient(); + _ = client.StartAsync(Cert, IPAddress.Parse(setting.Ip), setting.Port); + return AnonymousDisposer.Create(() => + { + _ = client.StopAsync(); + }); + } + + + // websocket + public IDisposable RunWebSocketServer(ExampleSetting setting) + { + var server = new WebSocketServer(); + _ = server.StartAsync(Cert, setting.Port); + return AnonymousDisposer.Create(() => + { + _ = server.StopAsync(); + }); + } + + public IDisposable RunWebSocketClient(ExampleSetting setting) + { + var client = new WebSocketClient(); + _ = client.StartAsync(Cert, IPAddress.Parse(setting.Ip), setting.Port, setting.Path); + + return AnonymousDisposer.Create(() => + { + _ = client.StopAsync(); + }); + } + + // http + public IDisposable RunHelloHttpServer(ExampleSetting setting) + { + var server = new HelloHttpServer(); + _ = server.StartAsync(Cert, setting.Port); + + return AnonymousDisposer.Create(() => + { + _ = server.StopAsync(); + }); + } + + public IDisposable RunHelloHttpClient(ExampleSetting setting) + { + ExampleSupport.Shared.OpenUrl($"https://{setting.Ip}:{setting.Port}/json"); + + return null; + } + } +} \ No newline at end of file diff --git a/Examples/UniNetty.Examples.DemoSupports/ExampleSetting.cs b/Examples/UniNetty.Examples.DemoSupports/ExampleSetting.cs new file mode 100644 index 0000000..82cf947 --- /dev/null +++ b/Examples/UniNetty.Examples.DemoSupports/ExampleSetting.cs @@ -0,0 +1,89 @@ +using System; + +namespace UniNetty.Examples.DemoSupports +{ + public class ExampleSetting + { + public readonly ExampleType Example; + + public string Ip { get; private set; } + public int Port { get; private set; } + public int Size { get; private set; } + public int Count { get; private set; } + public string Path { get; private set; } + + public bool IsRunningServer => null != _stopServer; + private Func _runServer; + private IDisposable _stopServer; + + public bool IsRunningClient => null != _stopClient; + private Func _runClient; + private IDisposable _stopClient; + + public ExampleSetting(ExampleType example) + { + Example = example; + } + + public void SetServer(Func runServer) + { + _runServer = runServer; + } + + public void SetClient(Func runClient) + { + _runClient = runClient; + } + + public void SetIp(string ip) + { + Ip = ip; + } + + public void SetPort(int port) + { + Port = port; + } + + public void SetSize(int size) + { + Size = size; + } + + public void SetCount(int count) + { + Count = count; + } + + public void SetPath(string path) + { + Path = path; + } + + public void ToggleServer() + { + if (null == _stopServer) + { + _stopServer = _runServer?.Invoke(this); + } + else + { + _stopServer.Dispose(); + _stopServer = null; + } + } + + public void ToggleClient() + { + if (null == _stopClient) + { + _stopClient = _runClient?.Invoke(this); + } + else + { + _stopClient.Dispose(); + _stopClient = null; + } + } + } +} \ No newline at end of file diff --git a/Examples/UniNetty.Examples.DemoSupports/ExampleSupport.cs b/Examples/UniNetty.Examples.DemoSupports/ExampleSupport.cs new file mode 100644 index 0000000..030b535 --- /dev/null +++ b/Examples/UniNetty.Examples.DemoSupports/ExampleSupport.cs @@ -0,0 +1,55 @@ +using System; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using UniNetty.Common.Internal.Logging; + +namespace UniNetty.Examples.DemoSupports +{ + public class ExampleSupport + { + private static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); + + public static readonly ExampleSupport Shared = new ExampleSupport(); + + public void OpenUrl(string url) + { + try + { + // OS에 따라 다른 명령 실행 + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var psi = new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true }; + Process.Start(psi); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Process.Start("open", url); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Process.Start("xdg-open", url); + } + } + catch (Exception ex) + { + Logger.Info($"Error opening web browser: {ex.Message}"); + } + } + + public string GetPrivateIp() + { + var host = Dns.GetHostEntry(Dns.GetHostName()); + foreach (var ip in host.AddressList) + { + if (ip.AddressFamily == AddressFamily.InterNetwork) + { + return ip.ToString(); + } + } + + return string.Empty; + } + } +} \ No newline at end of file diff --git a/Examples/UniNetty.Examples.DemoSupports/ExampleType.cs b/Examples/UniNetty.Examples.DemoSupports/ExampleType.cs new file mode 100644 index 0000000..ed618d6 --- /dev/null +++ b/Examples/UniNetty.Examples.DemoSupports/ExampleType.cs @@ -0,0 +1,53 @@ +using UniNetty.Common.Collections.Immutable; + +namespace UniNetty.Examples.DemoSupports +{ + /* + * { + "ssl": "false", + "host": "127.0.0.1", + "port": "8080", + "path": "/websocket", + "size": "256", + "count": "100", + "Logging": { + "LogLevel": { + "Default": "Trace" + } + } +} + */ + public class ExampleType + { + public static readonly ExampleType None = new ExampleType(0, nameof(None)); + public static readonly ExampleType Discard = new ExampleType(1, nameof(Discard)); + public static readonly ExampleType Echo = new ExampleType(2, nameof(Echo)); + public static readonly ExampleType Factorial = new ExampleType(3, nameof(Factorial)); + public static readonly ExampleType HttpServer = new ExampleType(4, nameof(HttpServer)); + public static readonly ExampleType QuoteOfTheMoment = new ExampleType(5, nameof(QuoteOfTheMoment)); + public static readonly ExampleType SecureChat = new ExampleType(6, nameof(SecureChat)); + public static readonly ExampleType Telnet = new ExampleType(7, nameof(Telnet)); + public static readonly ExampleType WebSocket = new ExampleType(8, nameof(WebSocket)); + + public static readonly UniImmutableArray Values = UniImmutableArrays.CreateRange( + None, + Discard, + Echo, + Factorial, + HttpServer, + QuoteOfTheMoment, + SecureChat, + Telnet, + WebSocket + ); + + public readonly int Index; + public readonly string Name; + + private ExampleType(int index, string name) + { + Index = index; + Name = name; + } + } +} \ No newline at end of file diff --git a/Examples/UniNetty.Examples.DemoSupports/UniNetty.Examples.DemoSupports.asmdef b/Examples/UniNetty.Examples.DemoSupports/UniNetty.Examples.DemoSupports.asmdef new file mode 100644 index 0000000..c9ca67c --- /dev/null +++ b/Examples/UniNetty.Examples.DemoSupports/UniNetty.Examples.DemoSupports.asmdef @@ -0,0 +1,40 @@ +{ + "name": "UniNetty.Examples.DemoSupports", + "rootNamespace": "UniNetty.Examples.DemoSupports", + "references": [ + "UniNetty.Logging", + "UniNetty.Common", + "UniNetty.Transport", + "UniNetty.Handlers", + "UniNetty.Buffers", + "UniNetty.Codecs", + "UniNetty.Codecs.Http", + "UniNetty.Codecs.Mqtt", + "UniNetty.Codecs.Redis", + "UniNetty.Examples.Discard.Client", + "UniNetty.Examples.Discard.Server", + "UniNetty.Examples.Echo.Client", + "UniNetty.Examples.Echo.Server", + "UniNetty.Examples.Factorial", + "UniNetty.Examples.Factorial.Client", + "UniNetty.Examples.Factorial.Server", + "UniNetty.Examples.HttpServer", + "UniNetty.Examples.QuoteOfTheMoment.Client", + "UniNetty.Examples.QuoteOfTheMoment.Server", + "UniNetty.Examples.SecureChat.Client", + "UniNetty.Examples.SecureChat.Server", + "UniNetty.Examples.Telnet.Client", + "UniNetty.Examples.Telnet.Server", + "UniNetty.Examples.WebSockets.Client", + "UniNetty.Examples.WebSockets.Server" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Examples/UniNetty.Examples.Echo.Server/UniNetty.Examples.Echo.Server.asmdef b/Examples/UniNetty.Examples.Echo.Server/UniNetty.Examples.Echo.Server.asmdef index 16931ef..75ef037 100644 --- a/Examples/UniNetty.Examples.Echo.Server/UniNetty.Examples.Echo.Server.asmdef +++ b/Examples/UniNetty.Examples.Echo.Server/UniNetty.Examples.Echo.Server.asmdef @@ -1,5 +1,5 @@ { - "name": "UniNetty.UniNetty.Examples.Echo.Server", + "name": "UniNetty.Examples.Echo.Server", "rootNamespace": "UniNetty.Examples.Echo.Server", "references": [ "UniNetty.Logging",