From ba084b79e6c12391344292fe36ad12e45722a6c9 Mon Sep 17 00:00:00 2001 From: Ahmed Zamil Date: Mon, 5 Oct 2020 00:46:51 +0300 Subject: [PATCH] Bugfix --- Esyur.Stores.EntityCore/EntityResource.cs | 8 +- Esyur.Stores.EntityCore/EntityStore.cs | 58 +-- .../Esyur.Stores.EntityCore.csproj | 9 +- .../EsyurExtensionOptions.cs | 3 +- Esyur.Stores.EntityCore/EsyurExtensions.cs | 24 +- Esyur.Stores.EntityCore/EsyurPlugin.cs | 2 +- Esyur.Stores.EntityCore/EsyurProxyRewrite.cs | 49 ++- .../Properties/launchSettings.json | 8 + Esyur/Core/ExceptionCode.cs | 3 +- Esyur/Data/DataConverter.cs | 87 +++-- Esyur/Net/HTTP/HTTPConnection.cs | 116 +++++- Esyur/Net/HTTP/HTTPFilter.cs | 2 +- Esyur/Net/HTTP/HTTPServer.cs | 142 ++------ Esyur/Net/HTTP/IIPoHTTP.cs | 2 +- Esyur/Net/HTTP/IIPoWS.cs | 6 +- Esyur/Net/IIP/DistributedConnection.cs | 305 +++++++++------- Esyur/Net/IIP/DistributedServer.cs | 83 +++-- Esyur/Net/INetworkReceiver.cs | 15 + Esyur/Net/NetworkConnection.cs | 244 ++++++++----- Esyur/Net/NetworkServer.cs | 286 ++++++--------- Esyur/Net/Packets/HTTPRequestPacket.cs | 2 +- Esyur/Net/Sockets/ISocket.cs | 14 +- Esyur/Net/Sockets/SSLSocket.cs | 24 +- Esyur/Net/Sockets/TCPSocket.cs | 43 ++- Esyur/Net/Sockets/WSSocket.cs | 334 ++++++++++-------- Esyur/Net/TCP/TCPConnection.cs | 19 +- Esyur/Net/TCP/TCPServer.cs | 32 +- Esyur/Resource/Instance.cs | 4 +- Esyur/Resource/Warehouse.cs | 54 ++- 29 files changed, 1135 insertions(+), 843 deletions(-) create mode 100644 Esyur.Stores.EntityCore/Properties/launchSettings.json create mode 100644 Esyur/Net/INetworkReceiver.cs diff --git a/Esyur.Stores.EntityCore/EntityResource.cs b/Esyur.Stores.EntityCore/EntityResource.cs index a2aa464..afadaaf 100644 --- a/Esyur.Stores.EntityCore/EntityResource.cs +++ b/Esyur.Stores.EntityCore/EntityResource.cs @@ -36,8 +36,8 @@ namespace Esyur.Stores.EntityCore { public class EntityResource : IResource { - [NotMapped] - internal object _PrimaryId; + //[NotMapped] + //internal object _PrimaryId; public event DestroyedEvent OnDestroy; public event PropertyChangedEventHandler PropertyChanged; @@ -49,7 +49,7 @@ namespace Esyur.Stores.EntityCore { } - + protected virtual void Create() { @@ -69,6 +69,6 @@ namespace Esyur.Stores.EntityCore //throw new NotImplementedException(); } - + } } \ No newline at end of file diff --git a/Esyur.Stores.EntityCore/EntityStore.cs b/Esyur.Stores.EntityCore/EntityStore.cs index 3b7f1b5..882c310 100644 --- a/Esyur.Stores.EntityCore/EntityStore.cs +++ b/Esyur.Stores.EntityCore/EntityStore.cs @@ -29,9 +29,6 @@ using Esyur.Resource.Template; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; -using System.Text; -using Microsoft.EntityFrameworkCore.Proxies; -using Microsoft.EntityFrameworkCore.Infrastructure; using Esyur.Proxy; using System.Linq; using Microsoft.EntityFrameworkCore.Metadata; @@ -65,7 +62,8 @@ namespace Esyur.Stores.EntityCore { var p = path.Split('/'); var ti = TypesByName[p[0]]; - var id = Convert.ToInt32(p[1]); + var id = Convert.ChangeType(p[1], ti.PrimaryKey.PropertyType);// Convert.ToInt32(); + //Type.cas ti.PrimaryKey.PropertyType. return DbContextProvider().Find(ti.Type.ClrType, id) as IResource; } @@ -76,7 +74,9 @@ namespace Esyur.Stores.EntityCore var type = ResourceProxy.GetBaseType(resource);//.GetType().; - var eid = (resource as EntityResource)._PrimaryId;// (int)resource.Instance.Variables["eid"]; + //var eid = (resource as EntityResource)._PrimaryId;// (int)resource.Instance.Variables["eid"]; + + var eid = TypesByType[type].PrimaryKey.GetValue(resource); if (DB[type].ContainsKey(eid)) DB[type].Remove(eid); @@ -86,7 +86,7 @@ namespace Esyur.Stores.EntityCore return true; } - public IResource GetById(Type type, int id) + public IResource GetById(Type type, object id) { if (!DB[type].ContainsKey(id)) return null; @@ -114,7 +114,7 @@ namespace Esyur.Stores.EntityCore var id = TypesByType[type].PrimaryKey.GetValue(resource); //DbContext.Model.FindEntityType(type).DisplayName(); - + // DbContext.Model.FindEntityType(type).DisplayName //var entityType = DbContext.Model.FindEntityType(type); //var id = entityType.FindPrimaryKey().Properties @@ -188,29 +188,37 @@ namespace Esyur.Stores.EntityCore if (DbContextProvider == null) DbContextProvider = () => Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext; - var context = Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext; - - var types = context.Model.GetEntityTypes(); - foreach (var t in types) - { - var ti = new TypeInfo() - { - Name = t.ClrType.Name, - PrimaryKey = t.FindPrimaryKey().Properties.FirstOrDefault()?.PropertyInfo, - Type = t - }; - - TypesByName.Add(t.ClrType.Name, ti); - TypesByType.Add(t.ClrType, ti); - - DB.Add(t.ClrType, new Dictionary()); - } - + ReloadModel(); } return new AsyncReply(true); } + public void ReloadModel() + { + TypesByName.Clear(); + TypesByType.Clear(); + + var context = DbContextProvider();// Activator.CreateInstance(Options.Options.ContextType, Options.Options) as DbContext; + + var types = context.Model.GetEntityTypes(); + foreach (var t in types) + { + var ti = new TypeInfo() + { + Name = t.ClrType.Name, + PrimaryKey = t.FindPrimaryKey().Properties.FirstOrDefault()?.PropertyInfo, + Type = t + }; + + TypesByName.Add(t.ClrType.Name, ti); + TypesByType.Add(t.ClrType, ti); + + if (!DB.ContainsKey(t.ClrType)) + DB.Add(t.ClrType, new Dictionary()); + } + } + public void Destroy() { //throw new NotImplementedException(); diff --git a/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj b/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj index 2430544..99d29f3 100644 --- a/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj +++ b/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj @@ -11,14 +11,7 @@ - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + diff --git a/Esyur.Stores.EntityCore/EsyurExtensionOptions.cs b/Esyur.Stores.EntityCore/EsyurExtensionOptions.cs index 70fd4f6..318d418 100644 --- a/Esyur.Stores.EntityCore/EsyurExtensionOptions.cs +++ b/Esyur.Stores.EntityCore/EsyurExtensionOptions.cs @@ -30,7 +30,6 @@ using System.Text; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Utilities; -using Microsoft.EntityFrameworkCore.Proxies.Internal; using System.Linq; using Microsoft.EntityFrameworkCore.Metadata; using System.Reflection; @@ -60,7 +59,7 @@ namespace Esyur.Stores.EntityCore public void ApplyServices(IServiceCollection services) { - services.AddEntityFrameworkProxies(); + // services.AddEntityFrameworkProxies(); new EntityFrameworkServicesBuilder(services) .TryAdd(); diff --git a/Esyur.Stores.EntityCore/EsyurExtensions.cs b/Esyur.Stores.EntityCore/EsyurExtensions.cs index 35e3fed..57e4d8e 100644 --- a/Esyur.Stores.EntityCore/EsyurExtensions.cs +++ b/Esyur.Stores.EntityCore/EsyurExtensions.cs @@ -29,6 +29,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace Esyur.Stores.EntityCore @@ -40,19 +41,28 @@ namespace Esyur.Stores.EntityCore // return dbContext.GetInfrastructure().CreateResource(properties); //} - - public static T AddResource(this DbSet dbSet, object properties = null) where T:class,IResource + + public static T AddResource(this DbSet dbSet, object properties = null) where T : class, IResource { var store = dbSet.GetInfrastructure().GetService().FindExtension().Store; + var manager = store.Instance.Managers.FirstOrDefault();// > 0 ? store.Instance.Managers.First() : null; + + //var db = dbSet.GetService().Context; //var resource = dbSet.GetInfrastructure().CreateResource(properties); //var resource = Warehouse.New("", options.Store, null, null, null, properties); var resource = Warehouse.New("", null, null, null, null, properties); - dbSet.Add(resource); + var entity = dbSet.Add(resource); + entity.Context.SaveChanges(); + + var id = store.TypesByType[typeof(T)].PrimaryKey.GetValue(resource); + + Warehouse.Put(resource, id.ToString(), store, null, null, 0, manager); + return resource; } - public static T CreateResource(this IServiceProvider serviceProvider, object properties = null) where T:class,IResource + public static T CreateResource(this IServiceProvider serviceProvider, object properties = null) where T : class, IResource { var options = serviceProvider.GetService().FindExtension(); @@ -72,7 +82,7 @@ namespace Esyur.Stores.EntityCore ) { var extension = optionsBuilder.Options.FindExtension(); - + if (extension == null) { @@ -90,7 +100,7 @@ namespace Esyur.Stores.EntityCore public static DbContextOptionsBuilder UseEsyur( this DbContextOptionsBuilder optionsBuilder, - //DbContext context, + //DbContext context, string name = null, IResource parent = null, IPermissionsManager manager = null, @@ -100,7 +110,7 @@ namespace Esyur.Stores.EntityCore var extension = optionsBuilder.Options.FindExtension(); - + if (extension == null) { var store = Warehouse.New(name, null, parent, manager, new { Options = optionsBuilder, DbContextProvider = dbContextProvider }); diff --git a/Esyur.Stores.EntityCore/EsyurPlugin.cs b/Esyur.Stores.EntityCore/EsyurPlugin.cs index bc786f4..91879e6 100644 --- a/Esyur.Stores.EntityCore/EsyurPlugin.cs +++ b/Esyur.Stores.EntityCore/EsyurPlugin.cs @@ -25,7 +25,7 @@ SOFTWARE. using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Proxies.Internal; +//using Microsoft.EntityFrameworkCore.Proxies.Internal; using System; using System.Collections.Generic; using System.Text; diff --git a/Esyur.Stores.EntityCore/EsyurProxyRewrite.cs b/Esyur.Stores.EntityCore/EsyurProxyRewrite.cs index c71ff1e..7cd3f02 100644 --- a/Esyur.Stores.EntityCore/EsyurProxyRewrite.cs +++ b/Esyur.Stores.EntityCore/EsyurProxyRewrite.cs @@ -47,15 +47,26 @@ namespace Esyur.Stores.EntityCore private readonly ConstructorBindingConvention _directBindingConvention; + //public static object CreateInstance(IDbContextOptions dbContextOptions, IEntityType entityType, + // object[] constructorArguments, DbContext context, long id) + //{ + // return CreateInstance(dbContextOptions, entityType, + // constructorArguments, context, id); + //} + public static object CreateInstance( - IDbContextOptions dbContextOptions, - IEntityType entityType, - // ILazyLoader loader, - object[] constructorArguments, - DbContext context, - int id = 0 -) + IDbContextOptions dbContextOptions, + IEntityType entityType, + object[] properties + + // ILazyLoader loader, + // object[] constructorArguments, + //DbContext context, + ) { + ///var id = constructorArguments.Last(); + var id = properties.First(); + var options = dbContextOptions.FindExtension(); var manager = options.Store.Instance.Managers.Count > 0 ? options.Store.Instance.Managers.First() : null; @@ -66,11 +77,11 @@ namespace Esyur.Stores.EntityCore // check if the object exists var obj = Warehouse.New(entityType.ClrType) as EntityResource;//, "", options.Store, null, manager); - obj._PrimaryId = id; + //obj._PrimaryId = id; options.Store.TypesByType[entityType.ClrType].PrimaryKey.SetValue(obj, id); Warehouse.Put(obj, id.ToString(), options.Store, null, null, 0, manager); -// obj.Instance.IntVal = id;//.Variables.Add("eid", id); + // obj.Instance.IntVal = id;//.Variables.Add("eid", id); return obj; } @@ -82,21 +93,21 @@ namespace Esyur.Stores.EntityCore } - + public void ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext context) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { var proxyType = ResourceProxy.GetProxy(entityType.ClrType); - var ann = entityType.GetAnnotation(CoreAnnotationNames.ConstructorBinding); + // var ann = entityType.GetAnnotation(CoreAnnotationNames.ConstructorBinding); var binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding]; if (binding == null) _directBindingConvention.ProcessModelFinalized(modelBuilder, context); binding = (InstantiationBinding)entityType[CoreAnnotationNames.ConstructorBinding]; - + try @@ -109,12 +120,18 @@ namespace Esyur.Stores.EntityCore { new DependencyInjectionParameterBinding(typeof(IDbContextOptions), typeof(IDbContextOptions)), new EntityTypeParameterBinding(), - //new DependencyInjectionParameterBinding(typeof(ILazyLoader), typeof(ILazyLoader)), - new ObjectArrayParameterBinding(binding.ParameterBindings), - new ContextParameterBinding(typeof(DbContext)), - new PropertyParameterBinding(entityType.FindPrimaryKey().Properties.FirstOrDefault()) + // constructor arguments + //new ObjectArrayParameterBinding(binding.ParameterBindings), + //new ContextParameterBinding(typeof(DbContext)), + new ObjectArrayParameterBinding(new ParameterBinding[]{ + new PropertyParameterBinding(entityType.FindPrimaryKey().Properties.FirstOrDefault()) + }) + // new Microsoft.EntityFrameworkCore.Metadata.ObjectArrayParameterBinding(), + //new ObjectArrayParameterBinding() + }, proxyType)); + } catch { diff --git a/Esyur.Stores.EntityCore/Properties/launchSettings.json b/Esyur.Stores.EntityCore/Properties/launchSettings.json new file mode 100644 index 0000000..ed0d750 --- /dev/null +++ b/Esyur.Stores.EntityCore/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Esyur.Stores.EntityCore": { + "commandName": "Project", + "commandLineArgs": "--migrate" + } + } +} \ No newline at end of file diff --git a/Esyur/Core/ExceptionCode.cs b/Esyur/Core/ExceptionCode.cs index 603101f..4ce7a2c 100644 --- a/Esyur/Core/ExceptionCode.cs +++ b/Esyur/Core/ExceptionCode.cs @@ -34,6 +34,7 @@ namespace Esyur.Core MethodNotFound, PropertyNotFound, SetPropertyDenied, - ReadOnlyProperty + ReadOnlyProperty, + GeneralFailure, } } diff --git a/Esyur/Data/DataConverter.cs b/Esyur/Data/DataConverter.cs index 9d919c0..0fafce3 100644 --- a/Esyur/Data/DataConverter.cs +++ b/Esyur/Data/DataConverter.cs @@ -659,9 +659,11 @@ namespace Esyur.Data public static Int16[] GetInt16Array(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; + var rt = new Int16[length / 2]; - for (var i = 0; i < length; i += 2) - rt[i] = GetInt16(data, (uint)(offset + i)); + for (var i = offset; i < end; i += 2) + rt[j++] = GetInt16(data, i); return rt; } @@ -673,10 +675,14 @@ namespace Esyur.Data public static UInt16[] GetUInt16Array(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new UInt16[length / 2]; - for (var i = 0; i < length; i += 2) - rt[i] = GetUInt16(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 2) + rt[j++] = GetUInt16(data, i); + return rt; + } public static Int32 GetInt32(this byte[] data, uint offset) @@ -686,9 +692,11 @@ namespace Esyur.Data public static Int32[] GetInt32Array(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; + var rt = new Int32[length / 4]; - for (var i = 0; i < length; i += 4) - rt[i] = GetInt32(data, (uint)(offset + i)); + for (var i = offset; i < end; i += 4) + rt[j++] = GetInt32(data, i); return rt; } @@ -700,9 +708,11 @@ namespace Esyur.Data public static UInt32[] GetUInt32Array(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new UInt32[length / 4]; - for (var i = 0; i < length; i += 4) - rt[i] = GetUInt32(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 4) + rt[j++] = GetUInt16(data, i); return rt; } @@ -728,9 +738,11 @@ namespace Esyur.Data public static Int64[] GetInt64Array(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new Int64[length / 8]; - for (var i = 0; i < length; i += 8) - rt[i] = GetInt64(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 8) + rt[j++] = GetInt64(data, i); return rt; } @@ -767,9 +779,11 @@ namespace Esyur.Data public static UInt64[] GetUInt64Array(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new UInt64[length / 8]; - for (var i = 0; i < length; i += 8) - rt[i] = GetUInt64(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 8) + rt[j++] = GetUInt64(data, i); return rt; } @@ -787,9 +801,11 @@ namespace Esyur.Data public static float[] GetFloat32Array(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new float[length / 4]; - for (var i = 0; i < length; i += 4) - rt[i] = GetFloat32(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 4) + rt[j++] = GetFloat32(data, i); return rt; } @@ -813,9 +829,11 @@ namespace Esyur.Data public static double[] GetFloat64Array(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new double[length / 8]; - for (var i = 0; i < length; i += 8) - rt[i] = GetFloat64(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 8) + rt[j++] = GetFloat64(data, i); return rt; } @@ -840,9 +858,13 @@ namespace Esyur.Data public static char[] GetCharArray(this byte[] data, uint offset, uint length) { + + var j = 0; var end = offset + length; var rt = new char[length / 2]; - for (var i = 0; i < length; i += 2) - rt[i] = GetChar(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 2) + rt[j++] = GetChar(data, i); + return rt; } @@ -875,9 +897,12 @@ namespace Esyur.Data public static Guid[] GetGuidArray(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new Guid[length / 16]; - for (var i = 0; i < length; i += 16) - rt[i] = GetGuid(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 16) + rt[j++] = GetGuid(data, i); + return rt; } @@ -889,9 +914,12 @@ namespace Esyur.Data public static DateTime[] GetDateTimeArray(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new DateTime[length / 8]; - for (var i = 0; i < length; i += 8) - rt[i] = GetDateTime(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 8) + rt[j++] = GetDateTime(data, i); + return rt; } @@ -902,9 +930,12 @@ namespace Esyur.Data public static IPAddress[] GetIPv4AddressArray(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new IPAddress[length / 4]; - for (var i = 0; i < length; i += 4) - rt[i] = GetIPv4Address(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 4) + rt[j++] = GetIPv6Address(data, i); + return rt; } @@ -915,10 +946,14 @@ namespace Esyur.Data public static IPAddress[] GetIPv6AddressArray(this byte[] data, uint offset, uint length) { + var j = 0; var end = offset + length; var rt = new IPAddress[length / 16]; - for (var i = 0; i < length; i += 16) - rt[i] = GetIPv6Address(data, (uint)(offset + i)); + + for (var i = offset; i < end; i += 16) + rt[j++] = GetIPv6Address(data, i); + return rt; + } diff --git a/Esyur/Net/HTTP/HTTPConnection.cs b/Esyur/Net/HTTP/HTTPConnection.cs index c2acabc..ccf1749 100644 --- a/Esyur/Net/HTTP/HTTPConnection.cs +++ b/Esyur/Net/HTTP/HTTPConnection.cs @@ -43,13 +43,11 @@ namespace Esyur.Net.HTTP public class HTTPConnection : NetworkConnection { - public void SetParent(HTTPServer Parent) - { - Server = Parent; - } + public bool WSMode { get; internal set; } - private HTTPServer Server; + public HTTPServer Server { get; internal set; } + public WebsocketPacket WSRequest { get; set; } public HTTPRequestPacket Request { get; set; } public HTTPResponsePacket Response { get; } = new HTTPResponsePacket(); @@ -100,7 +98,7 @@ namespace Esyur.Net.HTTP public void Flush() { // close the connection - if (Request.Headers["connection"].ToLower() != "keep-alive" & Connected) + if (Request.Headers["connection"].ToLower() != "keep-alive" & IsConnected) Close(); } @@ -232,6 +230,102 @@ namespace Esyur.Net.HTTP } } + protected override void DataReceived(NetworkBuffer data) + { + + byte[] msg = data.Read(); + + var BL = Parse(msg); + + if (BL == 0) + { + if (Request.Method == HTTPRequestPacket.HTTPMethod.UNKNOWN) + { + Close(); + return; + } + if (Request.URL == "") + { + Close(); + return; + } + } + else if (BL == -1) + { + data.HoldForNextWrite(msg); + return; + } + else if (BL < 0) + { + data.HoldFor(msg, (uint)(msg.Length - BL)); + return; + } + else if (BL > 0) + { + if (BL > Server.MaxPost) + { + Send( + "POST method content is larger than " + + Server.MaxPost + + " bytes."); + + Close(); + } + else + { + data.HoldFor(msg, (uint)(msg.Length + BL)); + } + return; + } + else if (BL < 0) // for security + { + Close(); + return; + } + + + + if (IsWebsocketRequest() & !WSMode) + { + Upgrade(); + //return; + } + + + //return; + + try + { + if (!Server.Execute(this)) + { + Response.Number = HTTPResponsePacket.ResponseCode.InternalServerError; + Send("Bad Request"); + Close(); + } + } + catch (Exception ex) + { + if (ex.Message != "Thread was being aborted.") + { + + Global.Log("HTTPServer", LogType.Error, ex.ToString()); + + //Console.WriteLine(ex.ToString()); + //EventLog.WriteEntry("HttpServer", ex.ToString(), EventLogEntryType.Error); + Send(Error500(ex.Message)); + } + + } + } + + private string Error500(string msg) + { + return "500 Internal Server Error
\r\n" + + "
\r\n" + + "500 Internal Server Error
" + msg + "\r\n" + + "
\r\n" + + "
\r\n"; + } public async AsyncReply SendFile(string filename) { @@ -329,5 +423,15 @@ namespace Esyur.Net.HTTP return false; } } + + protected override void Connected() + { + // do nothing + } + + protected override void Disconencted() + { + // do nothing + } } } \ No newline at end of file diff --git a/Esyur/Net/HTTP/HTTPFilter.cs b/Esyur/Net/HTTP/HTTPFilter.cs index 10d2672..70eeecb 100644 --- a/Esyur/Net/HTTP/HTTPFilter.cs +++ b/Esyur/Net/HTTP/HTTPFilter.cs @@ -62,7 +62,7 @@ namespace Esyur.Net.HTTP } */ - public abstract bool Execute(HTTPConnection sender); + public abstract AsyncReply Execute(HTTPConnection sender); public virtual void ClientConnected(HTTPConnection HTTP) { diff --git a/Esyur/Net/HTTP/HTTPServer.cs b/Esyur/Net/HTTP/HTTPServer.cs index 0ead13b..63385e1 100644 --- a/Esyur/Net/HTTP/HTTPServer.cs +++ b/Esyur/Net/HTTP/HTTPServer.cs @@ -140,113 +140,23 @@ namespace Esyur.Net.HTTP return Cookie; } - protected override void ClientDisconnected(HTTPConnection sender) + protected override void ClientDisconnected(HTTPConnection connection) { - //Console.WriteLine("OUT: " + this.Connections.Count); - foreach (var filter in filters) - filter.ClientDisconnected(sender); + filter.ClientDisconnected(connection); } + - - protected override void DataReceived(HTTPConnection sender, NetworkBuffer data) + internal bool Execute(HTTPConnection sender) { - - byte[] msg = data.Read(); - - var BL = sender.Parse(msg); - - if (BL == 0) - { - if (sender.Request.Method == HTTPRequestPacket.HTTPMethod.UNKNOWN) - { - sender.Close(); - return; - } - if (sender.Request.URL == "") - { - sender.Close(); - return; - } - } - else if (BL == -1) - { - data.HoldForNextWrite(msg); - return; - } - else if (BL < 0) - { - data.HoldFor(msg, (uint) (msg.Length - BL)); - return; - } - else if (BL > 0) - { - if (BL > MaxPost) - { - sender.Send( - "POST method content is larger than " - + MaxPost - + " bytes."); - - sender.Close(); - } - else - { - data.HoldFor(msg, (uint)(msg.Length + BL)); - } - return; - } - else if (BL < 0) // for security - { - sender.Close(); - return; - } - - - - if (sender.IsWebsocketRequest() & !sender.WSMode) - { - sender.Upgrade(); - //return; - } - - - //return; - - try - { - foreach (var resource in filters) - if (resource.Execute(sender)) - return; - - sender.Response.Number = HTTPResponsePacket.ResponseCode.InternalServerError; - sender.Send("Bad Request"); - sender.Close(); - } - catch (Exception ex) - { - if (ex.Message != "Thread was being aborted.") - { - - Global.Log("HTTPServer", LogType.Error, ex.ToString()); - - //Console.WriteLine(ex.ToString()); - //EventLog.WriteEntry("HttpServer", ex.ToString(), EventLogEntryType.Error); - sender.Send(Error500(ex.Message)); - } - - } + foreach (var resource in filters) + if (resource.Execute(sender).Wait(30000)) + return true; + return false; } - private string Error500(string msg) - { - return "500 Internal Server Error
\r\n" - + "
\r\n" - + "500 Internal Server Error
" + msg + "\r\n" - + "
\r\n" - + "
\r\n"; - } + /* @@ -283,7 +193,7 @@ namespace Esyur.Net.HTTP return Timeout;// mTimeout; } } - */ + */ public async AsyncReply Trigger(ResourceTrigger trigger) @@ -298,7 +208,7 @@ namespace Esyur.Net.HTTP //if (ip == null) ip = IPAddress.Any; - ISocket listener; + Sockets.ISocket listener; IPAddress ipAdd; if (IP == null) @@ -330,30 +240,34 @@ namespace Esyur.Net.HTTP return true; } - - protected override void ClientConnected(HTTPConnection sender) - { - //sender.SessionModified += SessionModified; - //sender.SessionEnded += SessionExpired; - sender.SetParent(this); - //Console.WriteLine("IN: " + this.Connections.Count); + + public override void Add(HTTPConnection connection) + { + connection.Server = this; + base.Add(connection); + } + + public override void Remove(HTTPConnection connection) + { + connection.Server = null; + base.Remove(connection); + } + + protected override void ClientConnected(HTTPConnection connection) + { if (filters.Length == 0) { - sender.Close(); + connection.Close(); return; } foreach (var resource in filters) { - resource.ClientConnected(sender); + resource.ClientConnected(connection); } } - public void Destroy() - { - - } /* public int LocalPort diff --git a/Esyur/Net/HTTP/IIPoHTTP.cs b/Esyur/Net/HTTP/IIPoHTTP.cs index 34a05d3..de3f3c1 100644 --- a/Esyur/Net/HTTP/IIPoHTTP.cs +++ b/Esyur/Net/HTTP/IIPoHTTP.cs @@ -13,7 +13,7 @@ namespace Esyur.Net.HTTP [Attribute] EntryPoint EntryPoint { get; set; } - public override bool Execute(HTTPConnection sender) + public async override AsyncReply Execute(HTTPConnection sender) { if (sender.Request.URL != "iip") return false; diff --git a/Esyur/Net/HTTP/IIPoWS.cs b/Esyur/Net/HTTP/IIPoWS.cs index 2e8bc81..a9a6e68 100644 --- a/Esyur/Net/HTTP/IIPoWS.cs +++ b/Esyur/Net/HTTP/IIPoWS.cs @@ -43,7 +43,7 @@ namespace Esyur.Net.HTTP set; } - public override bool Execute(HTTPConnection sender) + public async override AsyncReply Execute(HTTPConnection sender) { if (sender.IsWebsocketRequest()) @@ -58,11 +58,11 @@ namespace Esyur.Net.HTTP var httpServer = sender.Parent; var wsSocket = new WSSocket(tcpSocket); - httpServer.RemoveConnection(sender); + httpServer.Remove(sender); var iipConnection = new DistributedConnection(); - Server.AddConnection(iipConnection); + Server.Add(iipConnection); iipConnection.Assign(wsSocket); wsSocket.Begin(); diff --git a/Esyur/Net/IIP/DistributedConnection.cs b/Esyur/Net/IIP/DistributedConnection.cs index 8e46959..e81fa61 100644 --- a/Esyur/Net/IIP/DistributedConnection.cs +++ b/Esyur/Net/IIP/DistributedConnection.cs @@ -101,11 +101,7 @@ namespace Esyur.Net.IIP /// /// Distributed server responsible for this connection, usually for incoming connections. /// - public DistributedServer Server - { - get; - set; - } + public DistributedServer Server { get; internal set; } public bool Remove(IResource resource) { @@ -193,7 +189,7 @@ namespace Esyur.Net.IIP /// Assign a socket to the connection. /// /// Any socket that implements ISocket. - public override void Assign(ISocket socket) + public override void Assign(Sockets.ISocket socket) { base.Assign(socket); @@ -202,39 +198,22 @@ namespace Esyur.Net.IIP session.LocalAuthentication.Source.Attributes[SourceAttributeType.IPv4] = socket.LocalEndPoint.Address; session.LocalAuthentication.Source.Attributes[SourceAttributeType.Port] = socket.LocalEndPoint.Port; - if (session.LocalAuthentication.Type == AuthenticationType.Client) + if (socket.State == SocketState.Established && + session.LocalAuthentication.Type == AuthenticationType.Client) { // declare (Credentials -> No Auth, No Enctypt) var un = DC.ToBytes(session.LocalAuthentication.Username); var dmn = DC.ToBytes(session.LocalAuthentication.Domain);// domain); - if (socket.State == SocketState.Established) - { - SendParams() - .AddUInt8(0x60) - .AddUInt8((byte)dmn.Length) - .AddUInt8Array(dmn) - .AddUInt8Array(localNonce) - .AddUInt8((byte)un.Length) - .AddUInt8Array(un) - .Done();//, dmn, localNonce, (byte)un.Length, un); - } - else - { - socket.OnConnect += () => - { // declare (Credentials -> No Auth, No Enctypt) - //SendParams((byte)0x60, (byte)dmn.Length, dmn, localNonce, (byte)un.Length, un); - SendParams() - .AddUInt8(0x60) - .AddUInt8((byte)dmn.Length) - .AddUInt8Array(dmn) - .AddUInt8Array(localNonce) - .AddUInt8((byte)un.Length) - .AddUInt8Array(un) - .Done(); - }; - } + SendParams() + .AddUInt8(0x60) + .AddUInt8((byte)dmn.Length) + .AddUInt8Array(dmn) + .AddUInt8Array(localNonce) + .AddUInt8((byte)un.Length) + .AddUInt8Array(un) + .Done();//, dmn, localNonce, (byte)un.Length, un); } } @@ -246,7 +225,7 @@ namespace Esyur.Net.IIP /// Working domain. /// Username. /// Password. - public DistributedConnection(ISocket socket, string domain, string username, string password) + public DistributedConnection(Sockets.ISocket socket, string domain, string username, string password) { this.session = new Session(new ClientAuthentication() , new HostAuthentication()); @@ -264,7 +243,7 @@ namespace Esyur.Net.IIP Assign(socket); } - public DistributedConnection(ISocket socket, string domain, ulong tokenIndex, string token) + public DistributedConnection(Sockets.ISocket socket, string domain, ulong tokenIndex, string token) { this.session = new Session(new ClientAuthentication() , new HostAuthentication()); @@ -327,6 +306,12 @@ namespace Esyur.Net.IIP r.NextBytes(localNonce); } + public override void Destroy() + { + this.OnReady = null; + this.OnError = null; + base.Destroy(); + } private uint processPacket(byte[] msg, uint offset, uint ends, NetworkBuffer data, int chunkId) @@ -620,55 +605,78 @@ namespace Esyur.Net.IIP if (authPacket.RemoteMethod == AuthenticationMethod.Credentials && authPacket.LocalMethod == AuthenticationMethod.None) { - Server.Membership.UserExists(authPacket.RemoteUsername, authPacket.Domain).Then(x => + try { - if (x) + Server.Membership.UserExists(authPacket.RemoteUsername, authPacket.Domain).Then(x => { - session.RemoteAuthentication.Username = authPacket.RemoteUsername; - remoteNonce = authPacket.RemoteNonce; - session.RemoteAuthentication.Domain = authPacket.Domain; - SendParams() - .AddUInt8(0xa0) - .AddUInt8Array(localNonce) - .Done(); - //SendParams((byte)0xa0, localNonce); - } - else - { - //Console.WriteLine("User not found"); - SendParams().AddUInt8(0xc0) - .AddUInt8((byte)ExceptionCode.UserOrTokenNotFound) - .AddUInt16(14) - .AddString("User not found").Done(); - } - }); + if (x) + { + session.RemoteAuthentication.Username = authPacket.RemoteUsername; + remoteNonce = authPacket.RemoteNonce; + session.RemoteAuthentication.Domain = authPacket.Domain; + SendParams() + .AddUInt8(0xa0) + .AddUInt8Array(localNonce) + .Done(); + //SendParams((byte)0xa0, localNonce); + } + else + { + //Console.WriteLine("User not found"); + SendParams().AddUInt8(0xc0) + .AddUInt8((byte)ExceptionCode.UserOrTokenNotFound) + .AddUInt16(14) + .AddString("User not found").Done(); + } + }); + } + catch (Exception ex) + { + var errMsg = DC.ToBytes(ex.Message); + SendParams().AddUInt8(0xc0) + .AddUInt8((byte)ExceptionCode.GeneralFailure) + .AddUInt16((ushort)errMsg.Length) + .AddUInt8Array(errMsg).Done(); + } } else if (authPacket.RemoteMethod == AuthenticationMethod.Token && authPacket.LocalMethod == AuthenticationMethod.None) { - // Check if user and token exists - Server.Membership.TokenExists(authPacket.RemoteTokenIndex, authPacket.Domain).Then(x => + try { - if (x != null) + // Check if user and token exists + Server.Membership.TokenExists(authPacket.RemoteTokenIndex, authPacket.Domain).Then(x => { - session.RemoteAuthentication.Username = x; - session.RemoteAuthentication.TokenIndex = authPacket.RemoteTokenIndex; - remoteNonce = authPacket.RemoteNonce; - session.RemoteAuthentication.Domain = authPacket.Domain; - SendParams() - .AddUInt8(0xa0) - .AddUInt8Array(localNonce) - .Done(); - } - else - { - //Console.WriteLine("User not found"); - SendParams().AddUInt8(0xc0) - .AddUInt8((byte)ExceptionCode.UserOrTokenNotFound) - .AddUInt16(15) - .AddString("Token not found").Done(); - } - }); + if (x != null) + { + session.RemoteAuthentication.Username = x; + session.RemoteAuthentication.TokenIndex = authPacket.RemoteTokenIndex; + remoteNonce = authPacket.RemoteNonce; + session.RemoteAuthentication.Domain = authPacket.Domain; + SendParams() + .AddUInt8(0xa0) + .AddUInt8Array(localNonce) + .Done(); + } + else + { + //Console.WriteLine("User not found"); + SendParams().AddUInt8(0xc0) + .AddUInt8((byte)ExceptionCode.UserOrTokenNotFound) + .AddUInt16(15) + .AddString("Token not found").Done(); + } + }); + } + catch (Exception ex) + { + var errMsg = DC.ToBytes(ex.Message); + + SendParams().AddUInt8(0xc0) + .AddUInt8((byte)ExceptionCode.GeneralFailure) + .AddUInt16((ushort)errMsg.Length) + .AddUInt8Array(errMsg).Done(); + } } } else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Action) @@ -678,54 +686,66 @@ namespace Esyur.Net.IIP var remoteHash = authPacket.Hash; AsyncReply reply = null; - if (session.RemoteAuthentication.Method == AuthenticationMethod.Credentials) + try { - reply = Server.Membership.GetPassword(session.RemoteAuthentication.Username, - session.RemoteAuthentication.Domain); - } - else if (session.RemoteAuthentication.Method == AuthenticationMethod.Token) - { - reply = Server.Membership.GetToken(session.RemoteAuthentication.TokenIndex, - session.RemoteAuthentication.Domain); - } - else - { - // Error - } - - reply.Then((pw) => - { - if (pw != null) + if (session.RemoteAuthentication.Method == AuthenticationMethod.Credentials) { - var hashFunc = SHA256.Create(); - //var hash = hashFunc.ComputeHash(BinaryList.ToBytes(pw, remoteNonce, localNonce)); - var hash = hashFunc.ComputeHash((new BinaryList()) - .AddUInt8Array(pw) - .AddUInt8Array(remoteNonce) - .AddUInt8Array(localNonce) - .ToArray()); - if (hash.SequenceEqual(remoteHash)) - { - // send our hash - //var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localNonce, remoteNonce, pw)); - //SendParams((byte)0, localHash); - - var localHash = hashFunc.ComputeHash((new BinaryList()).AddUInt8Array(localNonce).AddUInt8Array(remoteNonce).AddUInt8Array(pw).ToArray()); - SendParams().AddUInt8(0).AddUInt8Array(localHash).Done(); - - readyToEstablish = true; - } - else - { - //Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:DENIED"); - SendParams().AddUInt8(0xc0) - .AddUInt8((byte)ExceptionCode.AccessDenied) - .AddUInt16(13) - .AddString("Access Denied") - .Done(); - } + reply = Server.Membership.GetPassword(session.RemoteAuthentication.Username, + session.RemoteAuthentication.Domain); } - }); + else if (session.RemoteAuthentication.Method == AuthenticationMethod.Token) + { + reply = Server.Membership.GetToken(session.RemoteAuthentication.TokenIndex, + session.RemoteAuthentication.Domain); + } + else + { + // Error + } + + reply.Then((pw) => + { + if (pw != null) + { + var hashFunc = SHA256.Create(); + //var hash = hashFunc.ComputeHash(BinaryList.ToBytes(pw, remoteNonce, localNonce)); + var hash = hashFunc.ComputeHash((new BinaryList()) + .AddUInt8Array(pw) + .AddUInt8Array(remoteNonce) + .AddUInt8Array(localNonce) + .ToArray()); + if (hash.SequenceEqual(remoteHash)) + { + // send our hash + //var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localNonce, remoteNonce, pw)); + //SendParams((byte)0, localHash); + + var localHash = hashFunc.ComputeHash((new BinaryList()).AddUInt8Array(localNonce).AddUInt8Array(remoteNonce).AddUInt8Array(pw).ToArray()); + SendParams().AddUInt8(0).AddUInt8Array(localHash).Done(); + + readyToEstablish = true; + } + else + { + //Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:DENIED"); + SendParams().AddUInt8(0xc0) + .AddUInt8((byte)ExceptionCode.AccessDenied) + .AddUInt16(13) + .AddString("Access Denied") + .Done(); + } + } + }); + } + catch (Exception ex) + { + var errMsg = DC.ToBytes(ex.Message); + + SendParams().AddUInt8(0xc0) + .AddUInt8((byte)ExceptionCode.GeneralFailure) + .AddUInt16((ushort)errMsg.Length) + .AddUInt8Array(errMsg).Done(); + } } else if (authPacket.Action == IIPAuthPacket.IIPAuthPacketAction.NewConnection) { @@ -741,9 +761,12 @@ namespace Esyur.Net.IIP .Done(); ready = true; + Warehouse.Put(this, this.LocalUsername, null, Server); + openReply?.Trigger(true); OnReady?.Invoke(this); - Server.Membership.Login(session); + + Server?.Membership.Login(session); //Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:AUTH"); @@ -813,6 +836,9 @@ namespace Esyur.Net.IIP session.Id = authPacket.SessionId; ready = true; + // put it in the warehouse + Warehouse.Put(this, this.LocalUsername, null, Server); + openReply?.Trigger(true); OnReady?.Invoke(this); @@ -925,7 +951,7 @@ namespace Esyur.Net.IIP } - protected override void ConnectionClosed() + protected void NetworkClose() { // clean up ready = false; @@ -948,7 +974,7 @@ namespace Esyur.Net.IIP x.Suspend(); } - public AsyncReply Connect(AuthenticationMethod method = AuthenticationMethod.Certificate, ISocket socket = null, string hostname = null, ushort port = 0, string username = null, ulong tokenIndex = 0, byte[] passwordOrToken = null, string domain = null) + public AsyncReply Connect(AuthenticationMethod method = AuthenticationMethod.Certificate, Sockets.ISocket socket = null, string hostname = null, ushort port = 0, string username = null, ulong tokenIndex = 0, byte[] passwordOrToken = null, string domain = null) { if (openReply != null) throw new AsyncException(ErrorType.Exception, 0, "Connection in progress"); @@ -1093,6 +1119,37 @@ namespace Esyur.Net.IIP return null; } + + protected override void Connected() + { + if (session.LocalAuthentication.Type == AuthenticationType.Client) + { + // declare (Credentials -> No Auth, No Enctypt) + + var un = DC.ToBytes(session.LocalAuthentication.Username); + var dmn = DC.ToBytes(session.LocalAuthentication.Domain);// domain); + + SendParams() + .AddUInt8(0x60) + .AddUInt8((byte)dmn.Length) + .AddUInt8Array(dmn) + .AddUInt8Array(localNonce) + .AddUInt8((byte)un.Length) + .AddUInt8Array(un) + .Done(); + } + } + + protected override void Disconencted() + { + if (ready) + { + Server?.Membership.Logout(session); + Warehouse.Remove(this); + ready = false; + } + } + /* public AsyncBag Children(IResource resource) { diff --git a/Esyur/Net/IIP/DistributedServer.cs b/Esyur/Net/IIP/DistributedServer.cs index 8064417..d9e584b 100644 --- a/Esyur/Net/IIP/DistributedServer.cs +++ b/Esyur/Net/IIP/DistributedServer.cs @@ -103,44 +103,67 @@ namespace Esyur.Net.IIP - protected override void DataReceived(DistributedConnection sender, NetworkBuffer data) - { - //throw new NotImplementedException(); + //protected override void DataReceived(DistributedConnection sender, NetworkBuffer data) + //{ + // //throw new NotImplementedException(); + //} + + + + //protected override void ClientConnected(DistributedConnection sender) + //{ + // //Console.WriteLine("DistributedConnection Client Connected"); + //} + + //private void ConnectionReadyEventReceiver(DistributedConnection sender) + //{ + // sender.OnReady -= ConnectionReadyEventReceiver; + // Warehouse.Put(sender, sender.LocalUsername, null, this); + //} + + + //public override void RemoveConnection(DistributedConnection connection) + //{ + // connection.OnReady -= Sender_OnReady; + // //connection.Server = null; + // base.RemoveConnection(connection); + //} + + //public override void AddConnection(DistributedConnection connection) + //{ + // connection.OnReady += Sender_OnReady; + // connection.Server = this; + // base.AddConnection(connection); + //} + + + + protected override void ClientConnected(DistributedConnection connection) + { + //connection.OnReady += ConnectionReadyEventReceiver; } - private void SessionModified(DistributedConnection session, string key, object newValue) + public override void Add(DistributedConnection connection) { - - } - - protected override void ClientConnected(DistributedConnection sender) - { - //Console.WriteLine("DistributedConnection Client Connected"); - } - - private void Sender_OnReady(DistributedConnection sender) - { - Warehouse.Put(sender, sender.LocalUsername, null, this); - } - - public override void RemoveConnection(DistributedConnection connection) - { - connection.OnReady -= Sender_OnReady; - //connection.Server = null; - base.RemoveConnection(connection); - } - - public override void AddConnection(DistributedConnection connection) - { - connection.OnReady += Sender_OnReady; connection.Server = this; - base.AddConnection(connection); + base.Add(connection); } - protected override void ClientDisconnected(DistributedConnection sender) + public override void Remove(DistributedConnection connection) { - Warehouse.Remove(sender); + connection.Server = null; + base.Remove(connection); } + + protected override void ClientDisconnected(DistributedConnection connection) + { + //connection.OnReady -= ConnectionReadyEventReceiver; + //Warehouse.Remove(connection); + + + } + + } } diff --git a/Esyur/Net/INetworkReceiver.cs b/Esyur/Net/INetworkReceiver.cs new file mode 100644 index 0000000..4a026ed --- /dev/null +++ b/Esyur/Net/INetworkReceiver.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esyur.Net +{ + public interface INetworkReceiver + { + void NetworkClose(T sender); + void NetworkReceive(T sender, NetworkBuffer buffer); + //void NetworkError(T sender); + + void NetworkConnect(T sender); + } +} diff --git a/Esyur/Net/NetworkConnection.cs b/Esyur/Net/NetworkConnection.cs index 8901274..5160a87 100644 --- a/Esyur/Net/NetworkConnection.cs +++ b/Esyur/Net/NetworkConnection.cs @@ -38,20 +38,22 @@ using Esyur.Resource; namespace Esyur.Net { - public class NetworkConnection : IDestructible// : IResource where TS : NetworkSession + public abstract class NetworkConnection: IDestructible, INetworkReceiver// : IResource where TS : NetworkSession { - private ISocket sock; + private Sockets.ISocket sock; // private bool connected; private DateTime lastAction; - public delegate void DataReceivedEvent(NetworkConnection sender, NetworkBuffer data); - public delegate void ConnectionClosedEvent(NetworkConnection sender); - public delegate void ConnectionEstablishedEvent(NetworkConnection sender); + //public delegate void DataReceivedEvent(NetworkConnection sender, NetworkBuffer data); + //public delegate void ConnectionClosedEvent(NetworkConnection sender); + public delegate void NetworkConnectionEvent(NetworkConnection connection); - public event ConnectionEstablishedEvent OnConnect; - public event DataReceivedEvent OnDataReceived; - public event ConnectionClosedEvent OnClose; + public event NetworkConnectionEvent OnConnect; + //public event DataReceivedEvent OnDataReceived; + public event NetworkConnectionEvent OnClose; + + public event DestroyedEvent OnDestroy; //object receivingLock = new object(); @@ -59,22 +61,31 @@ namespace Esyur.Net bool processing = false; + // public INetworkReceiver Receiver { get; set; } - public void Destroy() + public virtual void Destroy() { - // if (connected) + // remove references + //sock.OnClose -= Socket_OnClose; + //sock.OnConnect -= Socket_OnConnect; + //sock.OnReceive -= Socket_OnReceive; + sock.Destroy(); + //Receiver = null; Close(); + sock = null; + + OnClose = null; + OnConnect = null; + //OnDataReceived = null; OnDestroy?.Invoke(this); + OnDestroy = null; } - public NetworkConnection() - { - - } + - public ISocket Socket + public Sockets.ISocket Socket { get { @@ -82,81 +93,46 @@ namespace Esyur.Net } } - public virtual void Assign(ISocket socket) + public virtual void Assign(Sockets.ISocket socket) { lastAction = DateTime.Now; sock = socket; - //connected = true; - socket.OnReceive += Socket_OnReceive; - socket.OnClose += Socket_OnClose; - socket.OnConnect += Socket_OnConnect; - //if (socket.State == SocketState.Established) - // socket.Begin(); + sock.Receiver = this; + + //socket.OnReceive += Socket_OnReceive; + //socket.OnClose += Socket_OnClose; + //socket.OnConnect += Socket_OnConnect; } - private void Socket_OnConnect() - { - OnConnect?.Invoke(this); - } + //private void Socket_OnConnect() + //{ + // OnConnect?.Invoke(this); + //} - private void Socket_OnClose() - { - ConnectionClosed(); - OnClose?.Invoke(this); - } + //private void Socket_OnClose() + //{ + // ConnectionClosed(); + // OnClose?.Invoke(this); + //} - protected virtual void ConnectionClosed() - { + //protected virtual void ConnectionClosed() + //{ - } + //} - private void Socket_OnReceive(NetworkBuffer buffer) - { - try - { - // Unassigned ? - if (sock == null) - return; + //private void Socket_OnReceive(NetworkBuffer buffer) + //{ + //} - // Closed ? - if (sock.State == SocketState.Closed || sock.State == SocketState.Terminated) // || !connected) - return; - - lastAction = DateTime.Now; - - if (!processing) - { - processing = true; - - try - { - //lock(buffer.SyncLock) - while (buffer.Available > 0 && !buffer.Protected) - DataReceived(buffer); - } - catch - { - - } - - processing = false; - } - - } - catch (Exception ex) - { - Global.Log("NetworkConnection", LogType.Warning, ex.ToString()); - } - } - - public ISocket Unassign() + public Sockets.ISocket Unassign() { if (sock != null) { // connected = false; - sock.OnClose -= Socket_OnClose; - sock.OnConnect -= Socket_OnConnect; - sock.OnReceive -= Socket_OnReceive; + //sock.OnClose -= Socket_OnClose; + //sock.OnConnect -= Socket_OnConnect; + //sock.OnReceive -= Socket_OnReceive; + sock.Receiver = null; var rt = sock; sock = null; @@ -167,20 +143,20 @@ namespace Esyur.Net return null; } - protected virtual void DataReceived(NetworkBuffer data) - { - if (OnDataReceived != null) - { - try - { - OnDataReceived?.Invoke(this, data); - } - catch (Exception ex) - { - Global.Log("NetworkConenction:DataReceived", LogType.Error, ex.ToString()); - } - } - } + //protected virtual void DataReceived(NetworkBuffer data) + //{ + // if (OnDataReceived != null) + // { + // try + // { + // OnDataReceived?.Invoke(this, data); + // } + // catch (Exception ex) + // { + // Global.Log("NetworkConenction:DataReceived", LogType.Error, ex.ToString()); + // } + // } + //} public void Close() { @@ -234,11 +210,11 @@ namespace Esyur.Net } - public bool Connected + public bool IsConnected { get { - return sock.State == SocketState.Established;// connected; + return sock.State == SocketState.Established; } } @@ -283,7 +259,7 @@ namespace Esyur.Net { try { - sock.Send(msg); + sock?.Send(msg); lastAction = DateTime.Now; } catch @@ -309,5 +285,87 @@ namespace Esyur.Net { Send(Encoding.UTF8.GetBytes(data)); } + + public void NetworkClose(ISocket socket) + { + Disconencted(); + OnClose?.Invoke(this); + } + + public void NetworkConnect(ISocket socket) + { + Connected(); + OnConnect?.Invoke(this); + } + + //{ + //ConnectionClosed(); + //OnClose?.Invoke(this); + + //Receiver?.NetworkClose(this); + //} + + //public void NetworkConenct(ISocket sender) + //{ + // OnConnect?.Invoke(this); + //} + + protected abstract void DataReceived(NetworkBuffer buffer); + protected abstract void Connected(); + protected abstract void Disconencted(); + + public void NetworkReceive(ISocket sender, NetworkBuffer buffer) + { + try + { + // Unassigned ? + if (sock == null) + return; + + // Closed ? + if (sock.State == SocketState.Closed || sock.State == SocketState.Terminated) // || !connected) + return; + + lastAction = DateTime.Now; + + if (!processing) + { + processing = true; + + try + { + //lock(buffer.SyncLock) + while (buffer.Available > 0 && !buffer.Protected) + { + //Receiver?.NetworkReceive(this, buffer); + DataReceived(buffer); + } + } + catch + { + + } + + processing = false; + } + + } + catch (Exception ex) + { + Global.Log("NetworkConnection", LogType.Warning, ex.ToString()); + } + } + + + //{ + // Receiver?.NetworkError(this); + //throw new NotImplementedException(); + //} + + //public void NetworkConnect(ISocket sender) + //{ + // Receiver?.NetworkConnect(this); + //throw new NotImplementedException(); + //} } } \ No newline at end of file diff --git a/Esyur/Net/NetworkServer.cs b/Esyur/Net/NetworkServer.cs index 1871743..f413be7 100644 --- a/Esyur/Net/NetworkServer.cs +++ b/Esyur/Net/NetworkServer.cs @@ -39,14 +39,14 @@ namespace Esyur.Net public abstract class NetworkServer : IDestructible where TConnection : NetworkConnection, new() { //private bool isRunning; - private ISocket listener; - private AutoList> connections; + private Sockets.ISocket listener; + public AutoList> Connections { get; private set; } private Thread thread; - protected abstract void DataReceived(TConnection sender, NetworkBuffer data); - protected abstract void ClientConnected(TConnection sender); - protected abstract void ClientDisconnected(TConnection sender); + //protected abstract void DataReceived(TConnection sender, NetworkBuffer data); + //protected abstract void ClientConnected(TConnection sender); + //protected abstract void ClientDisconnected(TConnection sender); private Timer timer; @@ -54,74 +54,16 @@ namespace Esyur.Net public event DestroyedEvent OnDestroy; - public AutoList> Connections - { - get - { - return connections; - } - } - - /* - public void RemoveSession(string ID) - { - Sessions.Remove(ID); - } - - public void RemoveSession(TSession Session) - { - if (Session != null) - Sessions.Remove(Session.Id); - } - */ - - /* - public TSession CreateSession(string ID, int Timeout) - { - TSession s = new TSession(); - - s.SetSession(ID, Timeout, new NetworkSession.SessionModifiedEvent(SessionModified) - , new NetworkSession.SessionEndedEvent(SessionEnded)); - - - Sessions.Add(ID, s); - return s; - } - */ - - /* - private void pSessionModified(TSession session, string key, object oldValue, object newValue) - { - SessionModified((TSession)session, key, oldValue, newValue); - } - - private void pSessionEnded(NetworkSession session) - { - SessionEnded((TSession)session); - } - */ - - /* - protected virtual void SessionModified(NetworkSession session, string key, object oldValue, object newValue) - { - - } - - protected virtual void SessionEnded(NetworkSession session) - { - Sessions.Remove(session.Id); - session.Destroy(); - } - */ + //public AutoList> Connections => connections; private void MinuteThread(object state) { List ToBeClosed = null; - lock (connections.SyncRoot) + lock (Connections.SyncRoot) { - foreach (TConnection c in connections) + foreach (TConnection c in Connections) { if (DateTime.Now.Subtract(c.LastAction).TotalSeconds >= Timeout) { @@ -132,8 +74,6 @@ namespace Esyur.Net } } - //Console.WriteLine("UnLock MinuteThread"); - if (ToBeClosed != null) { //Console.WriteLine("Term: " + ToBeClosed.Count + " " + this.listener.LocalEndPoint.ToString()); @@ -145,18 +85,13 @@ namespace Esyur.Net } } - public void Start(ISocket socket)//, uint timeout, uint clock) + public void Start(Sockets.ISocket socket)//, uint timeout, uint clock) { if (listener != null) return; - //if (socket.State == SocketState.Listening) - // return; - //if (isRunning) - // return; - - connections = new AutoList>(this); + Connections = new AutoList>(this); if (Timeout > 0 & Clock > 0) @@ -165,11 +100,6 @@ namespace Esyur.Net } - // start a new thread for the server to live on - //isRunning = true; - - - listener = socket; // Start accepting @@ -182,8 +112,43 @@ namespace Esyur.Net { while (true) { - var s = listener.Accept(); - NewConnection(s); + try + { + var s = listener.Accept(); + + if (s == null) + { + Console.Write("sock == null"); + return; + } + + var c = new TConnection(); + //c.OnClose += ClientDisconnectedEventReceiver; + c.Assign(s); + Add(c); + //Connections.Add(c); + + try + { + //ClientConnected(c); + ClientConnected(c); + //NetworkConnect(c); + } + catch + { + // something wrong with the child. + } + + s.Begin(); + + // Accept more + //listener.Accept().Then(NewConnection); + + } + catch (Exception ex) + { + Console.WriteLine(ex); + } } })); @@ -191,15 +156,6 @@ namespace Esyur.Net } - /* - public int LocalPort - { - get - { - return port; - } - } - */ [Attribute] public uint Timeout @@ -237,7 +193,7 @@ namespace Esyur.Net //Console.WriteLine("Listener stopped"); - var cons = connections.ToArray(); + var cons = Connections.ToArray(); //lock (connections.SyncRoot) //{ @@ -261,67 +217,22 @@ namespace Esyur.Net } - public virtual void RemoveConnection(TConnection connection) + public virtual void Remove(TConnection connection) { - connection.OnDataReceived -= OnDataReceived; - connection.OnConnect -= OnClientConnect; - connection.OnClose -= OnClientClose; - connections.Remove(connection); + //connection.OnDataReceived -= OnDataReceived; + //connection.OnConnect -= OnClientConnect; + connection.OnClose -= ClientDisconnectedEventReceiver; + Connections.Remove(connection); } - public virtual void AddConnection(TConnection connection) + public virtual void Add(TConnection connection) { - connection.OnDataReceived += OnDataReceived; - connection.OnConnect += OnClientConnect; - connection.OnClose += OnClientClose; - connections.Add(connection); + //connection.OnDataReceived += OnDataReceived; + //connection.OnConnect += OnClientConnect; + connection.OnClose += ClientDisconnectedEventReceiver;// OnClientClose; + Connections.Add(connection); } - private void NewConnection(ISocket sock) - { - try - { - - - if (sock == null) - { - Console.Write("sock == null"); - return; - } - - - TConnection c = new TConnection(); - AddConnection(c); - - c.Assign(sock); - - - try - { - ClientConnected(c); - } - catch - { - // something wrong with the child. - } - - sock.Begin(); - - // Accept more - //listener.Accept().Then(NewConnection); - - - } - catch (Exception ex) - { - //Console.WriteLine("TSERVER " + ex.ToString()); - Global.Log("NetworkServer", LogType.Error, ex.ToString()); - } - - //isRunning = false; - - - } public bool IsRunning { @@ -332,44 +243,31 @@ namespace Esyur.Net } } - public void OnDataReceived(NetworkConnection sender, NetworkBuffer data) - { - DataReceived((TConnection)sender, data); - } + //public void OnDataReceived(ISocket sender, NetworkBuffer data) + //{ + // DataReceived((TConnection)sender, data); + //} - public void OnClientConnect(NetworkConnection sender) - { - if (sender == null) - return; + //public void OnClientConnect(ISocket sender) + //{ + // if (sender == null) + // return; - if (sender.RemoteEndPoint == null || sender.LocalEndPoint == null) - { } - //Console.WriteLine("NULL"); - else - Global.Log("Connections", LogType.Debug, sender.RemoteEndPoint.Address.ToString() - + "->" + sender.LocalEndPoint.Port + " at " + DateTime.UtcNow.ToString("d") - + " " + DateTime.UtcNow.ToString("d"), false); + // if (sender.RemoteEndPoint == null || sender.LocalEndPoint == null) + // { } + // //Console.WriteLine("NULL"); + // else + // Global.Log("Connections", LogType.Debug, sender.RemoteEndPoint.Address.ToString() + // + "->" + sender.LocalEndPoint.Port + " at " + DateTime.UtcNow.ToString("d") + // + " " + DateTime.UtcNow.ToString("d"), false); - // Console.WriteLine("Connected " + sender.RemoteEndPoint.ToString()); - ClientConnected((TConnection)sender); - } + // // Console.WriteLine("Connected " + sender.RemoteEndPoint.ToString()); + // ClientConnected((TConnection)sender); + //} - public void OnClientClose(NetworkConnection sender) - { - try - { - sender.Destroy(); - RemoveConnection((TConnection)sender); - ClientDisconnected((TConnection)sender); - } - catch (Exception ex) - { - Global.Log("NetworkServer:OnClientDisconnect", LogType.Error, ex.ToString()); - } - - sender = null; - GC.Collect(); - } + //public void OnClientClose(ISocket sender) + //{ + //} public void Destroy() @@ -378,10 +276,34 @@ namespace Esyur.Net OnDestroy?.Invoke(this); } + private void ClientDisconnectedEventReceiver(NetworkConnection connection) + { + try + { + var con = connection as TConnection; + con.Destroy(); + // con.OnClose -= ClientDisconnectedEventReceiver; + + Remove(con); + + //Connections.Remove(con); + ClientDisconnected(con); + //RemoveConnection((TConnection)sender); + //connections.Remove(sender) + //ClientDisconnected((TConnection)sender); + } + catch (Exception ex) + { + Global.Log("NetworkServer:OnClientDisconnect", LogType.Error, ex.ToString()); + } + } + + protected abstract void ClientDisconnected(TConnection connection); + protected abstract void ClientConnected(TConnection connection); + ~NetworkServer() { Stop(); - //Connections = null; listener = null; } } diff --git a/Esyur/Net/Packets/HTTPRequestPacket.cs b/Esyur/Net/Packets/HTTPRequestPacket.cs index 55495ba..449df59 100644 --- a/Esyur/Net/Packets/HTTPRequestPacket.cs +++ b/Esyur/Net/Packets/HTTPRequestPacket.cs @@ -240,7 +240,7 @@ namespace Esyur.Net.Packets // check limit if (postSize > data.Length - headerSize) - return postSize - (data.Length - headerSize); + return -(postSize - (data.Length - headerSize)); if (Headers["content-type"].StartsWith("application/x-www-form-urlencoded") diff --git a/Esyur/Net/Sockets/ISocket.cs b/Esyur/Net/Sockets/ISocket.cs index 999afc5..db3855d 100644 --- a/Esyur/Net/Sockets/ISocket.cs +++ b/Esyur/Net/Sockets/ISocket.cs @@ -38,17 +38,19 @@ using Esyur.Core; namespace Esyur.Net.Sockets { - public delegate void ISocketReceiveEvent(NetworkBuffer buffer); - public delegate void ISocketConnectEvent(); - public delegate void ISocketCloseEvent(); + //public delegate void ISocketReceiveEvent(NetworkBuffer buffer); + //public delegate void ISocketConnectEvent(); + //public delegate void ISocketCloseEvent(); public interface ISocket : IDestructible { SocketState State { get; } - event ISocketReceiveEvent OnReceive; - event ISocketConnectEvent OnConnect; - event ISocketCloseEvent OnClose; + //event ISocketReceiveEvent OnReceive; + //event ISocketConnectEvent OnConnect; + //event ISocketCloseEvent OnClose; + + INetworkReceiver Receiver { get; set; } AsyncReply SendAsync(byte[] message, int offset, int length); diff --git a/Esyur/Net/Sockets/SSLSocket.cs b/Esyur/Net/Sockets/SSLSocket.cs index 5ee6c40..8bc4d52 100644 --- a/Esyur/Net/Sockets/SSLSocket.cs +++ b/Esyur/Net/Sockets/SSLSocket.cs @@ -41,6 +41,9 @@ namespace Esyur.Net.Sockets { public class SSLSocket : ISocket { + + public INetworkReceiver Receiver { get; set; } + Socket sock; byte[] receiveBuffer; @@ -59,12 +62,11 @@ namespace Esyur.Net.Sockets SocketState state = SocketState.Initial; - public event ISocketReceiveEvent OnReceive; - public event ISocketConnectEvent OnConnect; - public event ISocketCloseEvent OnClose; + //public event ISocketReceiveEvent OnReceive; + //public event ISocketConnectEvent OnConnect; + //public event ISocketCloseEvent OnClose; public event DestroyedEvent OnDestroy; - SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs(); SslStream ssl; X509Certificate2 cert; @@ -87,8 +89,8 @@ namespace Esyur.Net.Sockets { await BeginAsync(); state = SocketState.Established; - OnConnect?.Invoke(); - + //OnConnect?.Invoke(); + Receiver?.NetworkConnect(this); } catch (Exception ex) { @@ -271,7 +273,8 @@ namespace Esyur.Net.Sockets } } - OnClose?.Invoke(); + Receiver?.NetworkClose(this); + //OnClose?.Invoke(); } } @@ -428,7 +431,9 @@ namespace Esyur.Net.Sockets receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)bytesReceived); - OnReceive?.Invoke(receiveNetworkBuffer); + //OnReceive?.Invoke(receiveNetworkBuffer); + + Receiver?.NetworkReceive(this, receiveNetworkBuffer); ssl.BeginRead(receiveBuffer, 0, receiveBuffer.Length, ReceiveCallback, this); @@ -453,7 +458,10 @@ namespace Esyur.Net.Sockets public void Destroy() { Close(); + Receiver = null; + receiveNetworkBuffer = null; OnDestroy?.Invoke(this); + OnDestroy = null; } public async AsyncReply AcceptAsync() diff --git a/Esyur/Net/Sockets/TCPSocket.cs b/Esyur/Net/Sockets/TCPSocket.cs index 42a8e92..13b83e1 100644 --- a/Esyur/Net/Sockets/TCPSocket.cs +++ b/Esyur/Net/Sockets/TCPSocket.cs @@ -39,6 +39,8 @@ namespace Esyur.Net.Sockets { public class TCPSocket : ISocket { + public INetworkReceiver Receiver { get; set; } + Socket sock; byte[] receiveBuffer; @@ -58,9 +60,9 @@ namespace Esyur.Net.Sockets SocketState state = SocketState.Initial; - public event ISocketReceiveEvent OnReceive; - public event ISocketConnectEvent OnConnect; - public event ISocketCloseEvent OnClose; + //public event ISocketReceiveEvent OnReceive; + //public event ISocketConnectEvent OnConnect; + //public event ISocketCloseEvent OnClose; public event DestroyedEvent OnDestroy; SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs(); @@ -103,7 +105,8 @@ namespace Esyur.Net.Sockets { state = SocketState.Established; - OnConnect?.Invoke(); + //OnConnect?.Invoke(); + Receiver?.NetworkConnect(this); Begin(); rt.Trigger(true); } @@ -134,7 +137,8 @@ namespace Esyur.Net.Sockets } receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)task.Result); - OnReceive?.Invoke(receiveNetworkBuffer); + //OnReceive?.Invoke(receiveNetworkBuffer); + Receiver?.NetworkReceive(this, receiveNetworkBuffer); if (state == SocketState.Established) sock.ReceiveAsync(receiveBufferSegment, SocketFlags.None).ContinueWith(DataReceived); @@ -163,11 +167,18 @@ namespace Esyur.Net.Sockets Close(); return; } + else if (e.SocketError != SocketError.Success) + { + Close(); + return; + + } var recCount = e.BytesTransferred > e.Count ? e.Count : e.BytesTransferred; receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)recCount); - OnReceive?.Invoke(receiveNetworkBuffer); + //OnReceive?.Invoke(receiveNetworkBuffer); + Receiver?.NetworkReceive(this, receiveNetworkBuffer); if (state == SocketState.Established) while (!sock.ReceiveAsync(e)) @@ -189,6 +200,12 @@ namespace Esyur.Net.Sockets Close(); return; } + else if (e.SocketError != SocketError.Success) + { + Close(); + return; + } + //if (e.BytesTransferred > 100000) // Console.WriteLine("BytesTransferred is large " + e.BytesTransferred); @@ -197,7 +214,8 @@ namespace Esyur.Net.Sockets receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)recCount); - OnReceive?.Invoke(receiveNetworkBuffer); + //OnReceive?.Invoke(receiveNetworkBuffer); + Receiver?.NetworkReceive(this, receiveNetworkBuffer); } } @@ -341,7 +359,8 @@ namespace Esyur.Net.Sockets } } - OnClose?.Invoke(); + //OnClose?.Invoke(); + Receiver?.NetworkClose(this); } } @@ -454,7 +473,15 @@ namespace Esyur.Net.Sockets public void Destroy() { Close(); + //OnClose = null; + //OnConnect = null; + //OnReceive = null; + Receiver = null; + receiveNetworkBuffer = null; + socketArgs.Completed -= SocketArgs_Completed; + socketArgs = null; OnDestroy?.Invoke(this); + OnDestroy = null; } public ISocket Accept() diff --git a/Esyur/Net/Sockets/WSSocket.cs b/Esyur/Net/Sockets/WSSocket.cs index 1f622c3..f440cc2 100644 --- a/Esyur/Net/Sockets/WSSocket.cs +++ b/Esyur/Net/Sockets/WSSocket.cs @@ -34,10 +34,11 @@ using System.IO; using Esyur.Core; using Esyur.Resource; using Esyur.Data; +using System.Globalization; namespace Esyur.Net.Sockets { - public class WSSocket : ISocket + public class WSSocket : ISocket, INetworkReceiver { WebsocketPacket pkt_receive = new WebsocketPacket(); WebsocketPacket pkt_send = new WebsocketPacket(); @@ -49,9 +50,9 @@ namespace Esyur.Net.Sockets object sendLock = new object(); bool held; - public event ISocketReceiveEvent OnReceive; - public event ISocketConnectEvent OnConnect; - public event ISocketCloseEvent OnClose; + //public event ISocketReceiveEvent OnReceive; + //public event ISocketConnectEvent OnConnect; + //public event ISocketCloseEvent OnClose; public event DestroyedEvent OnDestroy; long totalSent, totalReceived; @@ -63,8 +64,6 @@ namespace Esyur.Net.Sockets get { return (IPEndPoint)sock.LocalEndPoint; } } - - public IPEndPoint RemoteEndPoint { get { return sock.RemoteEndPoint; } @@ -79,6 +78,7 @@ namespace Esyur.Net.Sockets } } + public INetworkReceiver Receiver { get; set; } public WSSocket(ISocket socket) { @@ -86,12 +86,175 @@ namespace Esyur.Net.Sockets pkt_send.Mask = false; pkt_send.Opcode = WebsocketPacket.WSOpcode.BinaryFrame; sock = socket; - sock.OnClose += Sock_OnClose; - sock.OnConnect += Sock_OnConnect; - sock.OnReceive += Sock_OnReceive; + + sock.Receiver = this; + + //sock.OnClose += Sock_OnClose; + //sock.OnConnect += Sock_OnConnect; + //sock.OnReceive += Sock_OnReceive; } - private void Sock_OnReceive(NetworkBuffer buffer) + //private void Sock_OnReceive(NetworkBuffer buffer) + //{ + + //} + + //private void Sock_OnConnect() + //{ + // OnConnect?.Invoke(); + //} + + //private void Sock_OnClose() + //{ + // OnClose?.Invoke(); + //} + + public void Send(WebsocketPacket packet) + { + lock (sendLock) + if (packet.Compose()) + sock.Send(packet.Data); + } + + public void Send(byte[] message) + { + lock (sendLock) + { + if (held) + { + sendNetworkBuffer.Write(message); + } + else + { + totalSent += message.Length; + //Console.WriteLine("TX " + message.Length +"/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size)); + + pkt_send.Message = message; + + + if (pkt_send.Compose()) + sock.Send(pkt_send.Data); + + } + } + } + + + public void Send(byte[] message, int offset, int size) + { + lock (sendLock) + { + if (held) + { + sendNetworkBuffer.Write(message, (uint)offset, (uint)size); + } + else + { + totalSent += size; + //Console.WriteLine("TX " + size + "/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size)); + + pkt_send.Message = new byte[size]; + Buffer.BlockCopy(message, offset, pkt_send.Message, 0, size); + if (pkt_send.Compose()) + sock.Send(pkt_send.Data); + } + } + } + + + public void Close() + { + sock?.Close(); + } + + public AsyncReply Connect(string hostname, ushort port) + { + throw new NotImplementedException(); + } + + + public bool Begin() + { + return sock.Begin(); + } + + public bool Trigger(ResourceTrigger trigger) + { + return true; + } + + public void Destroy() + { + Close(); + //OnClose = null; + //OnConnect = null; + //OnReceive = null; + receiveNetworkBuffer = null; + //sock.OnReceive -= Sock_OnReceive; + //sock.OnClose -= Sock_OnClose; + //sock.OnConnect -= Sock_OnConnect; + sock.Receiver = null; + sock = null; + OnDestroy?.Invoke(this); + OnDestroy = null; + } + + public AsyncReply AcceptAsync() + { + throw new NotImplementedException(); + } + + public void Hold() + { + //Console.WriteLine("WS Hold "); + held = true; + } + + public void Unhold() + { + lock (sendLock) + { + held = false; + + var message = sendNetworkBuffer.Read(); + + //Console.WriteLine("WS Unhold {0}", message == null ? 0 : message.Length); + + if (message == null) + return; + + totalSent += message.Length; + + pkt_send.Message = message; + if (pkt_send.Compose()) + sock.Send(pkt_send.Data); + + + + } + } + + public AsyncReply SendAsync(byte[] message, int offset, int length) + { + throw new NotImplementedException(); + } + + public ISocket Accept() + { + throw new NotImplementedException(); + } + + public AsyncReply BeginAsync() + { + return sock.BeginAsync(); + } + + public void NetworkClose(ISocket sender) + { + Receiver?.NetworkClose(sender); + } + + public void NetworkReceive(ISocket sender, NetworkBuffer buffer) { if (sock.State == SocketState.Closed || sock.State == SocketState.Terminated) @@ -161,8 +324,9 @@ namespace Esyur.Net.Sockets if (offset == msg.Length) { - // Console.WriteLine("WS IN: " + receiveNetworkBuffer.Available); - OnReceive?.Invoke(receiveNetworkBuffer); + + //OnReceive?.Invoke(receiveNetworkBuffer); + Receiver?.NetworkReceive(this, receiveNetworkBuffer); return; } @@ -180,152 +344,20 @@ namespace Esyur.Net.Sockets //Console.WriteLine("WS IN: " + receiveNetworkBuffer.Available); - OnReceive?.Invoke(receiveNetworkBuffer); + //OnReceive?.Invoke(receiveNetworkBuffer); + Receiver?.NetworkReceive(this, receiveNetworkBuffer); processing = false; if (buffer.Available > 0 && !buffer.Protected) - Sock_OnReceive(buffer); + Receiver?.NetworkReceive(this, buffer); + //Sock_OnReceive(buffer); } - private void Sock_OnConnect() + + public void NetworkConnect(ISocket sender) { - OnConnect?.Invoke(); - } - - private void Sock_OnClose() - { - OnClose?.Invoke(); - } - - public void Send(WebsocketPacket packet) - { - lock (sendLock) - if (packet.Compose()) - sock.Send(packet.Data); - } - - public void Send(byte[] message) - { - lock (sendLock) - { - if (held) - { - sendNetworkBuffer.Write(message); - } - else - { - totalSent += message.Length; - //Console.WriteLine("TX " + message.Length +"/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size)); - - pkt_send.Message = message; - - - if (pkt_send.Compose()) - sock.Send(pkt_send.Data); - - } - } - } - - - public void Send(byte[] message, int offset, int size) - { - lock (sendLock) - { - if (held) - { - sendNetworkBuffer.Write(message, (uint)offset, (uint)size); - } - else - { - totalSent += size; - //Console.WriteLine("TX " + size + "/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size)); - - pkt_send.Message = new byte[size]; - Buffer.BlockCopy(message, offset, pkt_send.Message, 0, size); - if (pkt_send.Compose()) - sock.Send(pkt_send.Data); - } - } - } - - - public void Close() - { - sock.Close(); - } - - public AsyncReply Connect(string hostname, ushort port) - { - throw new NotImplementedException(); - } - - - public bool Begin() - { - return sock.Begin(); - } - - public bool Trigger(ResourceTrigger trigger) - { - return true; - } - - public void Destroy() - { - Close(); - OnDestroy?.Invoke(this); - } - - public AsyncReply AcceptAsync() - { - throw new NotImplementedException(); - } - - public void Hold() - { - //Console.WriteLine("WS Hold "); - held = true; - } - - public void Unhold() - { - lock (sendLock) - { - held = false; - - var message = sendNetworkBuffer.Read(); - - //Console.WriteLine("WS Unhold {0}", message == null ? 0 : message.Length); - - if (message == null) - return; - - totalSent += message.Length; - - pkt_send.Message = message; - if (pkt_send.Compose()) - sock.Send(pkt_send.Data); - - - - } - } - - public AsyncReply SendAsync(byte[] message, int offset, int length) - { - throw new NotImplementedException(); - } - - public ISocket Accept() - { - throw new NotImplementedException(); - } - - public AsyncReply BeginAsync() - { - return sock.BeginAsync(); + Receiver?.NetworkConnect(this); } } } \ No newline at end of file diff --git a/Esyur/Net/TCP/TCPConnection.cs b/Esyur/Net/TCP/TCPConnection.cs index a3d9583..ea2a596 100644 --- a/Esyur/Net/TCP/TCPConnection.cs +++ b/Esyur/Net/TCP/TCPConnection.cs @@ -34,11 +34,11 @@ using Esyur.Data; namespace Esyur.Net.TCP { - public class TCPConnection: NetworkConnection - { + public class TCPConnection:NetworkConnection { private KeyList variables = new KeyList(); + public TCPServer Server { get; internal set; } public KeyList Variables { @@ -47,5 +47,20 @@ namespace Esyur.Net.TCP return variables; } } + + protected override void Connected() + { + // do nothing + } + + protected override void DataReceived(NetworkBuffer buffer) + { + Server?.Execute(this, buffer); + } + + protected override void Disconencted() + { + // do nothing + } } } diff --git a/Esyur/Net/TCP/TCPServer.cs b/Esyur/Net/TCP/TCPServer.cs index 0bcfed8..82420ea 100644 --- a/Esyur/Net/TCP/TCPServer.cs +++ b/Esyur/Net/TCP/TCPServer.cs @@ -103,15 +103,19 @@ namespace Esyur.Net.TCP - protected override void DataReceived(TCPConnection sender, NetworkBuffer data) + + + internal bool Execute(TCPConnection sender, NetworkBuffer data) { var msg = data.Read(); foreach (var filter in filters) { if (filter.Execute(msg, data, sender)) - return; + return true; } + + return false; } private void SessionModified(TCPConnection session, string key, object newValue) @@ -119,22 +123,34 @@ namespace Esyur.Net.TCP } - protected override void ClientConnected(TCPConnection sender) + protected override void ClientDisconnected(TCPConnection connection) { + foreach (var filter in filters) { - filter.Connected(sender); + filter.Connected(connection); } } - protected override void ClientDisconnected(TCPConnection sender) + public override void Add(TCPConnection connection) + { + connection.Server = this; + base.Add(connection); + } + + public override void Remove(TCPConnection connection) + { + connection.Server = null; + base.Remove(connection); + } + + protected override void ClientConnected(TCPConnection connection) { foreach (var filter in filters) { - filter.Disconnected(sender); + filter.Disconnected(connection); } } - - } + } } diff --git a/Esyur/Resource/Instance.cs b/Esyur/Resource/Instance.cs index c8913ef..3ff8ed1 100644 --- a/Esyur/Resource/Instance.cs +++ b/Esyur/Resource/Instance.cs @@ -897,7 +897,9 @@ namespace Esyur.Resource //if (evt.EventHandlerType != typeof(ResourceEventHanlder)) // continue; - + if (evt.Info == null) + continue; + if (evt.Info.EventHandlerType == typeof(ResourceEventHanlder)) { diff --git a/Esyur/Resource/Warehouse.cs b/Esyur/Resource/Warehouse.cs index 2fe8c7f..a68fd2b 100644 --- a/Esyur/Resource/Warehouse.cs +++ b/Esyur/Resource/Warehouse.cs @@ -36,6 +36,7 @@ using Esyur.Net.IIP; using System.Text.RegularExpressions; using Esyur.Misc; using System.Collections.Concurrent; +using System.Collections; namespace Esyur.Resource { @@ -61,16 +62,18 @@ namespace Esyur.Resource public static event StoreConnectedEvent StoreConnected; public static event StoreDisconnectedEvent StoreDisconnected; - public static KeyList> Protocols { get; } = getSupportedProtocols(); + public delegate IStore ProtocolInstance(string name, object properties); + + public static KeyList Protocols { get; } = GetSupportedProtocols(); private static Regex urlRegex = new Regex(@"^(?:([\S]*)://([^/]*)/?)"); //private static object resourcesLock = new object(); - static KeyList> getSupportedProtocols() + static KeyList GetSupportedProtocols() { - var rt = new KeyList>(); - rt.Add("iip", () => new DistributedConnection()); + var rt = new KeyList(); + rt.Add("iip", (name, props) => Warehouse.New(name, null, null, null, props)); return rt; } @@ -396,26 +399,29 @@ namespace Esyur.Resource { var handler = Protocols[url[1]]; - var store = handler(); - Put(store, url[2], null, parent, null, 0, manager, attributes); - + var store = handler(url[2], attributes); store.Trigger(ResourceTrigger.Open).Then(x => { warehouseIsOpen = true; + Put(store, url[2], null, parent, null, 0, manager, attributes); if (url[3].Length > 0 && url[3] != "") store.Get(url[3]).Then(r => { rt.Trigger(r); - }).Error(e => rt.TriggerError(e)); + }).Error(e => + { + Warehouse.Remove(store); + rt.TriggerError(e); + }); else rt.Trigger(store); }).Error(e => { rt.TriggerError(e); - Warehouse.Remove(store); + //Warehouse.Remove(store); }); return rt; @@ -457,13 +463,23 @@ namespace Esyur.Resource if (parent is IStore) { store = (IStore)parent; - stores[store].Add(resourceReference); + List> list; + if (stores.TryGetValue(store, out list)) + lock (((ICollection)list).SyncRoot) + list.Add(resourceReference); + //stores[store].Add(resourceReference); } // assign parent's store as a store else if (parent != null) { store = parent.Instance.Store; - stores[store].Add(resourceReference); + + List> list; + if (stores.TryGetValue(store, out list)) + lock (((ICollection)list).SyncRoot) + list.Add(resourceReference); + + //stores[store].Add(resourceReference); } // assign self as a store (root store) else if (resource is IStore) @@ -499,6 +515,7 @@ namespace Esyur.Resource if (resource is IStore) { + stores.TryAdd(resource as IStore, new List>()); StoreConnected?.Invoke(resource as IStore, name); } @@ -574,7 +591,7 @@ namespace Esyur.Resource foreach (var p in ps) { - + var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); if (pi != null && pi.CanWrite) { @@ -582,7 +599,7 @@ namespace Esyur.Resource { pi.SetValue(res, p.Value); } - catch(Exception ex) + catch (Exception ex) { Global.Log(ex); } @@ -679,8 +696,17 @@ namespace Esyur.Resource //} if (resource != resource.Instance.Store) - stores[resource.Instance.Store].Remove(resourceReference); + { + List> list; + if (stores.TryGetValue(resource.Instance.Store, out list)) + { + lock (((ICollection)list).SyncRoot) + list.Remove(resourceReference); + + //list.TryTake(resourceReference); + }//.Remove(resourceReference); + } if (resource is IStore) { var store = resource as IStore;