2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-05-06 19:42:58 +00:00
This commit is contained in:
Ahmed Zamil 2020-03-25 08:52:15 +03:00
parent 8bd9b3282c
commit 836a1fdeae
23 changed files with 466 additions and 216 deletions

View File

@ -34,6 +34,8 @@ using Microsoft.EntityFrameworkCore.Proxies;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Esyur.Proxy; using Esyur.Proxy;
using System.Linq; using System.Linq;
using Microsoft.EntityFrameworkCore.Metadata;
using System.Reflection;
namespace Esyur.Stores.EntityCore namespace Esyur.Stores.EntityCore
{ {
@ -43,6 +45,16 @@ namespace Esyur.Stores.EntityCore
public event DestroyedEvent OnDestroy; public event DestroyedEvent OnDestroy;
struct TypeInfo
{
public string Name;
public IEntityType Type;
public PropertyInfo PrimaryKey;
}
Dictionary<string, TypeInfo> TypesByName = new Dictionary<string, TypeInfo>();
Dictionary<Type, TypeInfo> TypesByType = new Dictionary<Type, TypeInfo>();
/* /*
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ {
@ -74,9 +86,9 @@ namespace Esyur.Stores.EntityCore
public async AsyncReply<IResource> Get(string path) public async AsyncReply<IResource> Get(string path)
{ {
var p = path.Split('/'); var p = path.Split('/');
var type = Options.Cache.Keys.Where(x => x.Name.ToLower() == p[0].ToLower()).FirstOrDefault(); var ti = TypesByName[p[0]];
var id = Convert.ToInt32(p[1]); var id = Convert.ToInt32(p[1]);
return DbContext.Find(type, id) as IResource; return DbContext.Find(ti.Type.ClrType, id) as IResource;
} }
public async AsyncReply<bool> Put(IResource resource) public async AsyncReply<bool> Put(IResource resource)
@ -87,6 +99,7 @@ namespace Esyur.Stores.EntityCore
[Attribute] [Attribute]
public EsyurExtensionOptions Options { get; set; } public EsyurExtensionOptions Options { get; set; }
//DbContext dbContext;
[Attribute] [Attribute]
public DbContext DbContext { get; set; } public DbContext DbContext { get; set; }
@ -94,7 +107,16 @@ namespace Esyur.Stores.EntityCore
{ {
var type = ResourceProxy.GetBaseType(resource.GetType()); var type = ResourceProxy.GetBaseType(resource.GetType());
var id = Options.Cache[type].GetValue(resource); 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
// .FirstOrDefault()?.PropertyInfo
// .GetValue(resource);
// var id = Types
if (id != null) if (id != null)
return this.Instance.Name + "/" + type.Name + "/" + id.ToString(); return this.Instance.Name + "/" + type.Name + "/" + id.ToString();
@ -156,6 +178,24 @@ namespace Esyur.Stores.EntityCore
public AsyncReply<bool> Trigger(ResourceTrigger trigger) public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{ {
if (trigger == ResourceTrigger.SystemInitialized && DbContext != null)
{
var types = DbContext.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);
}
}
return new AsyncReply<bool>(true); return new AsyncReply<bool>(true);
} }

View File

@ -41,12 +41,12 @@ namespace Esyur.Stores.EntityCore
public class EsyurExtensionOptions : IDbContextOptionsExtension public class EsyurExtensionOptions : IDbContextOptionsExtension
{ {
public Dictionary<Type, PropertyInfo> Cache { get; } = new Dictionary<Type, PropertyInfo>(); //public Dictionary<Type, PropertyInfo> Cache { get; } = new Dictionary<Type, PropertyInfo>();
public void AddType(IEntityType type) //public void AddType(IEntityType type)
{ //{
if (!Cache.ContainsKey(type.ClrType)) // if (!Cache.ContainsKey(type.ClrType))
Cache.Add(type.ClrType, type.FindPrimaryKey().Properties[0].PropertyInfo); // Cache.Add(type.ClrType, type.FindPrimaryKey().Properties[0].PropertyInfo);
} //}

View File

@ -68,7 +68,7 @@ namespace Esyur.Stores.EntityCore
object[] constructorArguments) object[] constructorArguments)
{ {
//var key = entityType.FindPrimaryKey(); //var key = entityType.FindPrimaryKey();
options.AddType(entityType); //options.AddType(entityType);
var manager = options.Store.Instance.Managers.Count > 0 ? options.Store.Instance.Managers.First() : null; var manager = options.Store.Instance.Managers.Count > 0 ? options.Store.Instance.Managers.First() : null;
return Warehouse.New(entityType.ClrType, "", options.Store, null, manager); return Warehouse.New(entityType.ClrType, "", options.Store, null, manager);

View File

@ -56,6 +56,10 @@ namespace Esyur.Core
return (object[])base.Wait(); return (object[])base.Wait();
} }
public new object[] Wait(int timeout)
{
return (object[])base.Wait(timeout);
}
public void Seal() public void Seal()
{ {

View File

@ -30,11 +30,16 @@ namespace Esyur.Core
{ {
public class AsyncException : Exception public class AsyncException : Exception
{ {
public readonly ErrorType Type; public readonly ErrorType Type;
public readonly ExceptionCode Code; public readonly ExceptionCode Code;
public AsyncException(Exception exception) :base(exception.Message, exception)
{
Type = ErrorType.Exception;
Code = 0;
}
public override string StackTrace => InnerException != null && Type == ErrorType.Exception ? InnerException.StackTrace : base.StackTrace;
public AsyncException(ErrorType type, ushort code, string message) public AsyncException(ErrorType type, ushort code, string message)
: base(type == ErrorType.Management ? ((ExceptionCode)code).ToString() : message) : base(type == ErrorType.Management ? ((ExceptionCode)code).ToString() : message)

View File

@ -89,6 +89,27 @@ namespace Esyur.Core
} }
public object Wait(int millisecondsTimeout)
{
if (resultReady)
return result;
if (Debug)
Console.WriteLine($"AsyncReply: {Id} Wait");
if (!mutex.WaitOne(millisecondsTimeout))
{
var e = new Exception("AsyncReply timeout");
TriggerError(e);
throw e;
}
if (Debug)
Console.WriteLine($"AsyncReply: {Id} Wait ended");
return result;
}
public object Result public object Result
{ {
get { return result; } get { return result; }
@ -210,7 +231,7 @@ namespace Esyur.Core
if (exception is AsyncException) if (exception is AsyncException)
this.exception = exception as AsyncException; this.exception = exception as AsyncException;
else else
this.exception = new AsyncException(ErrorType.Management, 0, exception.Message); this.exception = new AsyncException(exception);
// lock (callbacksLock) // lock (callbacksLock)

View File

@ -79,6 +79,12 @@ namespace Esyur.Core
{ {
return (T)base.Wait(); return (T)base.Wait();
} }
public new T Wait(int millisecondsTimeout)
{
return (T)base.Wait(millisecondsTimeout);
}
/* /*
protected new List<Action> callbacks = new List<Action>(); protected new List<Action> callbacks = new List<Action>();
protected new object result; protected new object result;

View File

@ -49,9 +49,10 @@ namespace Esyur.Data
public event Cleared OnCleared; public event Cleared OnCleared;
public event Added OnAdd; public event Added OnAdd;
ST state;
bool removableList; bool removableList;
public ST State { get; set; }
/* /*
IOrderedEnumerable<T> OrderBy<T, TK>(Func<T, TK> keySelector) IOrderedEnumerable<T> OrderBy<T, TK>(Func<T, TK> keySelector)
{ {
@ -95,7 +96,7 @@ namespace Esyur.Data
/// <param name="state">State object to be included when an event is raised.</param> /// <param name="state">State object to be included when an event is raised.</param>
public AutoList(ST state) public AutoList(ST state)
{ {
this.state = state; State = state;
#if NETSTANDARD #if NETSTANDARD
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())); removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
#else #else
@ -110,7 +111,7 @@ namespace Esyur.Data
/// <returns></returns> /// <returns></returns>
public AutoList(ST state, T[] values) public AutoList(ST state, T[] values)
{ {
this.state = state; State = state;
#if NETSTANDARD #if NETSTANDARD
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())); removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
#else #else
@ -163,7 +164,7 @@ namespace Esyur.Data
lock (syncRoot) lock (syncRoot)
list[index] = value; list[index] = value;
OnModified?.Invoke(state, index, oldValue, value); OnModified?.Invoke(State, index, oldValue, value);
} }
} }
@ -179,7 +180,7 @@ namespace Esyur.Data
lock (syncRoot) lock (syncRoot)
list.Add(value); list.Add(value);
OnAdd?.Invoke(state, value); OnAdd?.Invoke(State, value);
} }
/// <summary> /// <summary>
@ -209,7 +210,7 @@ namespace Esyur.Data
lock (syncRoot) lock (syncRoot)
list.Clear(); list.Clear();
OnCleared?.Invoke(state); OnCleared?.Invoke(State);
} }
/// <summary> /// <summary>
@ -228,7 +229,7 @@ namespace Esyur.Data
lock (syncRoot) lock (syncRoot)
list.Remove(value); list.Remove(value);
OnRemoved?.Invoke(state, value); OnRemoved?.Invoke(State, value);
} }
/// <summary> /// <summary>

View File

@ -91,18 +91,18 @@ namespace Esyur.Data
if (obj is Structure) if (obj is Structure)
return obj as Structure; return obj as Structure;
else if (Codec.IsAnonymous(type)) else //if (Codec.IsAnonymous(type))
{ {
var st = new Structure(); var st = new Structure();
var pi = type.GetTypeInfo().GetProperties(); var pi = type.GetTypeInfo().GetProperties().Where(x=>x.CanRead);
foreach (var p in pi) foreach (var p in pi)
st[p.Name] = p.GetValue(obj); st[p.Name] = p.GetValue(obj);
return st; return st;
} }
else //else
return null; // return null;
} }
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{ {

View File

@ -265,7 +265,7 @@ namespace Esyur.Net.HTTP
try try
{ {
var ims = DateTime.Parse(Request.Headers["if-modified-since"]); var ims = DateTime.Parse(Request.Headers["if-modified-since"]);
if (Math.Abs((fileEditTime - ims).TotalSeconds) < 0) if ((fileEditTime - ims).TotalSeconds < 2)
{ {
Response.Number = HTTPResponsePacket.ResponseCode.NotModified; Response.Number = HTTPResponsePacket.ResponseCode.NotModified;
//Response.Text = "Not Modified"; //Response.Text = "Not Modified";
@ -274,7 +274,7 @@ namespace Esyur.Net.HTTP
} }
catch catch
{ {
return false;
} }
} }

View File

@ -102,17 +102,6 @@ namespace Esyur.Net.HTTP
} }
public enum ResponseCodes : int
{
HTTP_OK = 200,
HTTP_NOTFOUND = 404,
HTTP_SERVERERROR = 500,
HTTP_MOVED = 301,
HTTP_NOTMODIFIED = 304,
HTTP_REDIRECT = 307
}
public HTTPSession CreateSession(string id, int timeout) public HTTPSession CreateSession(string id, int timeout)
{ {
var s = new HTTPSession(); var s = new HTTPSession();
@ -322,9 +311,7 @@ namespace Esyur.Net.HTTP
// else // else
listener = new TCPSocket(new IPEndPoint(ipAdd, Port)); listener = new TCPSocket(new IPEndPoint(ipAdd, Port));
Start(listener, Start(listener);
Timeout,
Clock);
} }
else if (trigger == ResourceTrigger.Terminate) else if (trigger == ResourceTrigger.Terminate)
{ {

View File

@ -72,6 +72,9 @@ namespace Esyur.Net.IIP
bool ready, readyToEstablish; bool ready, readyToEstablish;
string _hostname;
ushort _port;
DateTime loginDate; DateTime loginDate;
/// <summary> /// <summary>
@ -194,10 +197,10 @@ namespace Esyur.Net.IIP
{ {
base.Assign(socket); base.Assign(socket);
session.RemoteAuthentication.Source.Attributes.Add(SourceAttributeType.IPv4, socket.RemoteEndPoint.Address); session.RemoteAuthentication.Source.Attributes[SourceAttributeType.IPv4] = socket.RemoteEndPoint.Address;
session.RemoteAuthentication.Source.Attributes.Add(SourceAttributeType.Port, socket.RemoteEndPoint.Port); session.RemoteAuthentication.Source.Attributes[SourceAttributeType.Port] = socket.RemoteEndPoint.Port;
session.LocalAuthentication.Source.Attributes.Add(SourceAttributeType.IPv4, socket.LocalEndPoint.Address); session.LocalAuthentication.Source.Attributes[SourceAttributeType.IPv4] = socket.LocalEndPoint.Address;
session.LocalAuthentication.Source.Attributes.Add(SourceAttributeType.Port, socket.LocalEndPoint.Port); session.LocalAuthentication.Source.Attributes[SourceAttributeType.Port] = socket.LocalEndPoint.Port;
if (session.LocalAuthentication.Type == AuthenticationType.Client) if (session.LocalAuthentication.Type == AuthenticationType.Client)
{ {
@ -831,31 +834,115 @@ namespace Esyur.Net.IIP
var domain = Domain != null ? Domain : address;// Instance.Attributes.ContainsKey("domain") ? Instance.Attributes["domain"].ToString() : address; var domain = Domain != null ? Domain : address;// Instance.Attributes.ContainsKey("domain") ? Instance.Attributes["domain"].ToString() : address;
session = new Session(new ClientAuthentication()
, new HostAuthentication());
session.LocalAuthentication.Domain = domain; return Connect(null, address, port, username, DC.ToBytes(Password), domain);
session.LocalAuthentication.Username = username;
localPassword = DC.ToBytes(Password);// Instance.Attributes["password"].ToString());
openReply = new AsyncReply<bool>();
var sock = new TCPSocket();
sock.Connect(address, port).Then((x)=> {
Assign(sock);
//rt.trigger(true);
}).Error((x) =>
openReply.TriggerError(x)
);
return openReply;
} }
} }
return new AsyncReply<bool>(); return new AsyncReply<bool>();
} }
protected override void ConnectionClosed()
{
// clean up
ready = false;
readyToEstablish = false;
foreach (var x in requests.Values)
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
foreach (var x in resourceRequests.Values)
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
foreach (var x in templateRequests.Values)
x.TriggerError(new AsyncException(ErrorType.Management, 0, "Connection closed"));
requests.Clear();
resourceRequests.Clear();
templateRequests.Clear();
foreach (var x in resources.Values)
x.Suspend();
}
public AsyncReply<bool> Connect(ISocket socket = null, string hostname = null, ushort port = 0, string username = null, byte[] password = null, string domain = null)
{
if (openReply != null)
throw new AsyncException(ErrorType.Exception, 0, "Connection in progress");
openReply = new AsyncReply<bool>();
if (hostname != null)
{
session = new Session(new ClientAuthentication()
, new HostAuthentication());
session.LocalAuthentication.Domain = domain;
session.LocalAuthentication.Username = username;
localPassword = password;
}
if (session == null)
throw new AsyncException(ErrorType.Exception, 0, "Session not initialized");
if (socket == null)
socket = new TCPSocket();
if (port > 0)
this._port = port;
if (hostname != null)
this._hostname = hostname;
socket.Connect(this._hostname, this._port).Then(x =>
{
Assign(socket);
}).Error((x) =>
{
openReply.TriggerError(x);
openReply = null;
});
return openReply;
}
public async AsyncReply<bool> Reconnect()
{
try
{
if (await Connect())
{
try
{
var bag = new AsyncBag();
for (var i = 0; i < resources.Keys.Count; i++)
{
var index = resources.Keys.ElementAt(i);
bag.Add(Fetch(index));
}
bag.Seal();
await bag;
}
catch (Exception ex)
{
Global.Log(ex);
//print(ex.toString());
}
}
}
catch
{
return false;
}
return true;
}
// AsyncReply<bool> connect({ISocket socket, String hostname, int port, String username, DC password, String domain})
/// <summary> /// <summary>
/// Store interface. /// Store interface.
/// </summary> /// </summary>

View File

@ -134,6 +134,18 @@ namespace Esyur.Net.IIP
return reply; return reply;
} }
internal AsyncReply<object[]> SendDetachRequest(uint instanceId)
{
try
{
return SendRequest(IIPPacket.IIPPacketAction.DetachResource).AddUInt32(instanceId).Done();
}
catch
{
return null;
}
}
internal AsyncReply<object> SendInvokeByNamedArguments(uint instanceId, byte index, Structure parameters) internal AsyncReply<object> SendInvokeByNamedArguments(uint instanceId, byte index, Structure parameters)
{ {
var pb = Codec.ComposeStructure(parameters, this, true, true, true); var pb = Codec.ComposeStructure(parameters, this, true, true, true);
@ -433,6 +445,7 @@ namespace Esyur.Net.IIP
void IIPRequestAttachResource(uint callback, uint resourceId) void IIPRequestAttachResource(uint callback, uint resourceId)
{ {
Warehouse.GetById(resourceId).Then((res) => Warehouse.GetById(resourceId).Then((res) =>
{ {
if (res != null) if (res != null)
@ -454,14 +467,7 @@ namespace Esyur.Net.IIP
//r.Instance.Attributes.OnModified -= Attributes_OnModified; //r.Instance.Attributes.OnModified -= Attributes_OnModified;
// subscribe // Console.WriteLine("Attach {0} {1}", r.Instance.Link, r.Instance.Id);
r.Instance.ResourceEventOccurred += Instance_EventOccurred;
r.Instance.ResourceModified += Instance_PropertyModified;
r.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
//r.Instance.Children.OnAdd += Children_OnAdd;
//r.Instance.Children.OnRemoved += Children_OnRemoved;
//r.Instance.Attributes.OnModified += Attributes_OnModified;
// add it to attached resources so GC won't remove it from memory // add it to attached resources so GC won't remove it from memory
attachedResources.Add(r); attachedResources.Add(r);
@ -490,6 +496,19 @@ namespace Esyur.Net.IIP
.AddUInt8Array(Codec.ComposePropertyValueArray(r.Instance.Serialize(), this, true)) .AddUInt8Array(Codec.ComposePropertyValueArray(r.Instance.Serialize(), this, true))
.Done(); .Done();
} }
// subscribe
r.Instance.ResourceEventOccurred += Instance_EventOccurred;
r.Instance.ResourceModified += Instance_PropertyModified;
r.Instance.ResourceDestroyed += Instance_ResourceDestroyed;
//r.Instance.Children.OnAdd += Children_OnAdd;
//r.Instance.Children.OnRemoved += Children_OnRemoved;
//r.Instance.Attributes.OnModified += Attributes_OnModified;
} }
else else
{ {
@ -1886,18 +1905,22 @@ namespace Esyur.Net.IIP
/// <returns>DistributedResource</returns> /// <returns>DistributedResource</returns>
public AsyncReply<DistributedResource> Fetch(uint id) public AsyncReply<DistributedResource> Fetch(uint id)
{ {
if (resourceRequests.ContainsKey(id) && resources.ContainsKey(id)) var resource = resources[id];
{ var request = resourceRequests[id];
Console.WriteLine("DEAD LOCK " + id);
return new AsyncReply<DistributedResource>(resources[id]); if (request != null)
// dig for dead locks {
return resourceRequests[id]; if (resource != null)
// dig for dead locks // or not
return new AsyncReply<DistributedResource>(resource);
else
return request;
} }
else if (resourceRequests.ContainsKey(id)) else if (resource != null && !resource.Suspended)
return resourceRequests[id]; {
else if (resources.ContainsKey(id)) return new AsyncReply<DistributedResource>(resource);
return new AsyncReply<DistributedResource>(resources[id]); }
var reply = new AsyncReply<DistributedResource>(); var reply = new AsyncReply<DistributedResource>();
resourceRequests.Add(id, reply); resourceRequests.Add(id, reply);
@ -1907,16 +1930,18 @@ namespace Esyur.Net.IIP
.Done() .Done()
.Then((rt) => .Then((rt) =>
{ {
var dr = new DistributedResource(this, id, (ulong)rt[1], (string)rt[2]);
var dr = resource ?? new DistributedResource(this, id, (ulong)rt[1], (string)rt[2]);
GetTemplate((Guid)rt[0]).Then((tmp) => GetTemplate((Guid)rt[0]).Then((tmp) =>
{ {
// ClassId, ResourceAge, ResourceLink, Content // ClassId, ResourceAge, ResourceLink, Content
if (resource == null)
Warehouse.Put(dr, id.ToString(), this, null, tmp); Warehouse.Put(dr, id.ToString(), this, null, tmp);
Codec.ParsePropertyValueArray((byte[])rt[3], this).Then((ar) => Codec.ParsePropertyValueArray((byte[])rt[3], this).Then((ar) =>
{ {
dr._Attached(ar); dr._Attach(ar);
resourceRequests.Remove(id); resourceRequests.Remove(id);
reply.Trigger(dr); reply.Trigger(dr);
}); });

View File

@ -58,9 +58,9 @@ namespace Esyur.Net.IIP
DistributedConnection connection; DistributedConnection connection;
bool isAttached = false; bool attached = false;
bool isReady = false; bool destroyed = false;
bool suspended = false;
//Structure properties = new Structure(); //Structure properties = new Structure();
@ -73,22 +73,6 @@ namespace Esyur.Net.IIP
DistributedResourceEvent[] events; DistributedResourceEvent[] events;
//ResourceTemplate template;
//DistributedResourceStack stack;
bool destroyed;
/*
Dictionary<AsyncReply, object> afterAttachmentTriggers = new Dictionary<AsyncReply, object>();
internal void AddAfterAttachement(AsyncReply trigger, object value)
{
afterAttachmentTriggers.Add(trigger, value);
}
*/
/// <summary> /// <summary>
@ -130,31 +114,28 @@ namespace Esyur.Net.IIP
public void Destroy() public void Destroy()
{ {
destroyed = true; destroyed = true;
attached = false;
connection.SendDetachRequest(instanceId);
OnDestroy?.Invoke(this); OnDestroy?.Invoke(this);
} }
/// <summary> /// <summary>
/// Resource is ready when all its properties are attached. /// Suspend resource
/// </summary> /// </summary>
internal bool IsReady
internal void Suspend()
{ {
get suspended = true;
{ attached = false;
return isReady;
}
} }
/// <summary> /// <summary>
/// Resource is attached when all its properties are received. /// Resource is attached when all its properties are received.
/// </summary> /// </summary>
internal bool IsAttached internal bool Attached => attached;
{
get
{
return isAttached;
}
}
internal bool Suspended => suspended;
// public DistributedResourceStack Stack // public DistributedResourceStack Stack
@ -182,11 +163,6 @@ namespace Esyur.Net.IIP
} }
internal void _Ready()
{
isReady = true;
}
/// <summary> /// <summary>
/// Export all properties with ResourceProperty attributed as bytes array. /// Export all properties with ResourceProperty attributed as bytes array.
/// </summary> /// </summary>
@ -203,12 +179,14 @@ namespace Esyur.Net.IIP
return props; return props;
} }
internal bool _Attached(PropertyValue[] properties) internal bool _Attach(PropertyValue[] properties)
{ {
if (isAttached) if (attached)
return false; return false;
else else
{ {
suspended = false;
this.properties = new object[properties.Length]; this.properties = new object[properties.Length];
this.events = new DistributedResourceEvent[Instance.Template.Events.Length]; this.events = new DistributedResourceEvent[Instance.Template.Events.Length];
@ -226,7 +204,7 @@ namespace Esyur.Net.IIP
//afterAttachmentTriggers.Clear(); //afterAttachmentTriggers.Clear();
isAttached = true; attached = true;
} }
return true; return true;
@ -244,6 +222,9 @@ namespace Esyur.Net.IIP
if (destroyed) if (destroyed)
throw new Exception("Trying to access destroyed object"); throw new Exception("Trying to access destroyed object");
if (suspended)
throw new Exception("Trying to access suspended object");
if (index >= Instance.Template.Functions.Length) if (index >= Instance.Template.Functions.Length)
throw new Exception("Function index is incorrect"); throw new Exception("Function index is incorrect");
@ -256,6 +237,9 @@ namespace Esyur.Net.IIP
if (destroyed) if (destroyed)
throw new Exception("Trying to access destroyed object"); throw new Exception("Trying to access destroyed object");
if (suspended)
throw new Exception("Trying to access suspended object");
if (index >= Instance.Template.Functions.Length) if (index >= Instance.Template.Functions.Length)
throw new Exception("Function index is incorrect"); throw new Exception("Function index is incorrect");
@ -270,7 +254,7 @@ namespace Esyur.Net.IIP
var reply = new AsyncReply<object>(); var reply = new AsyncReply<object>();
if (isAttached && ft!=null) if (attached && ft!=null)
{ {
if (args.Length == 1) if (args.Length == 1)
{ {
@ -321,9 +305,10 @@ namespace Esyur.Net.IIP
if (destroyed) if (destroyed)
throw new Exception("Trying to access destroyed object"); throw new Exception("Trying to access destroyed object");
result = null; result = null;
if (!isAttached) if (!attached)
return false; return false;
var pt = Instance.Template.GetPropertyTemplateByName(binder.Name); var pt = Instance.Template.GetPropertyTemplateByName(binder.Name);
@ -388,7 +373,10 @@ namespace Esyur.Net.IIP
if (destroyed) if (destroyed)
throw new Exception("Trying to access destroyed object"); throw new Exception("Trying to access destroyed object");
if (!isAttached) if (suspended)
throw new Exception("Trying to access suspended object");
if (!attached)
return false; return false;
var pt = Instance.Template.GetPropertyTemplateByName(binder.Name); var pt = Instance.Template.GetPropertyTemplateByName(binder.Name);

View File

@ -67,20 +67,6 @@ namespace Esyur.Net.IIP
set; set;
} }
[Attribute]
public uint Timeout
{
get;
set;
}
[Attribute]
public uint Clock
{
get;
set;
}
public Instance Instance public Instance Instance
@ -100,7 +86,7 @@ namespace Esyur.Net.IIP
else else
listener = new TCPSocket(new IPEndPoint(IPAddress.Any, Port)); listener = new TCPSocket(new IPEndPoint(IPAddress.Any, Port));
Start(listener, Timeout, Clock); Start(listener);
} }
else if (trigger == ResourceTrigger.Terminate) else if (trigger == ResourceTrigger.Terminate)
{ {

View File

@ -101,9 +101,15 @@ namespace Esyur.Net
private void Socket_OnClose() private void Socket_OnClose()
{ {
ConnectionClosed();
OnClose?.Invoke(this); OnClose?.Invoke(this);
} }
protected virtual void ConnectionClosed()
{
}
private void Socket_OnReceive(NetworkBuffer buffer) private void Socket_OnReceive(NetworkBuffer buffer)
{ {
try try
@ -264,6 +270,7 @@ namespace Esyur.Net
{ {
try try
{ {
lastAction = DateTime.Now;
return sock.SendAsync(message, offset, length); return sock.SendAsync(message, offset, length);
} }
catch catch

View File

@ -39,7 +39,6 @@ namespace Esyur.Net
public abstract class NetworkServer<TConnection> : IDestructible where TConnection : NetworkConnection, new() public abstract class NetworkServer<TConnection> : IDestructible where TConnection : NetworkConnection, new()
{ {
//private bool isRunning; //private bool isRunning;
uint clock;
private ISocket listener; private ISocket listener;
private AutoList<TConnection, NetworkServer<TConnection>> connections; private AutoList<TConnection, NetworkServer<TConnection>> connections;
@ -50,7 +49,6 @@ namespace Esyur.Net
protected abstract void ClientDisconnected(TConnection sender); protected abstract void ClientDisconnected(TConnection sender);
private uint timeout;
private Timer timer; private Timer timer;
//public KeyList<string, TSession> Sessions = new KeyList<string, TSession>(); //public KeyList<string, TSession> Sessions = new KeyList<string, TSession>();
@ -125,7 +123,7 @@ namespace Esyur.Net
{ {
foreach (TConnection c in connections) foreach (TConnection c in connections)
{ {
if (DateTime.Now.Subtract(c.LastAction).TotalSeconds >= timeout) if (DateTime.Now.Subtract(c.LastAction).TotalSeconds >= Timeout)
{ {
if (ToBeClosed == null) if (ToBeClosed == null)
ToBeClosed = new List<TConnection>(); ToBeClosed = new List<TConnection>();
@ -147,7 +145,7 @@ namespace Esyur.Net
} }
} }
public void Start(ISocket socket, uint timeout, uint clock) public void Start(ISocket socket)//, uint timeout, uint clock)
{ {
if (listener != null) if (listener != null)
return; return;
@ -161,16 +159,11 @@ namespace Esyur.Net
connections = new AutoList<TConnection, NetworkServer<TConnection>>(this); connections = new AutoList<TConnection, NetworkServer<TConnection>>(this);
if (timeout > 0 & clock > 0) if (Timeout > 0 & Clock > 0)
{ {
timer = new Timer(MinuteThread, null, TimeSpan.FromMinutes(0), TimeSpan.FromSeconds(clock)); timer = new Timer(MinuteThread, null, TimeSpan.FromMinutes(0), TimeSpan.FromSeconds(Clock));
this.timeout = timeout;
} }
//this.ip = ip;
//this.port = port;
this.clock = clock;
// start a new thread for the server to live on // start a new thread for the server to live on
//isRunning = true; //isRunning = true;
@ -208,12 +201,22 @@ namespace Esyur.Net
} }
*/ */
[Attribute]
public uint Timeout
{
get;
set;
}
[Attribute]
public uint Clock public uint Clock
{ {
get { return clock; } get;
set;
} }
public void Stop() public void Stop()
{ {
var port = 0; var port = 0;

View File

@ -134,7 +134,7 @@ namespace Esyur.Net.Packets
sMethod[1] = WebUtility.UrlDecode(sMethod[1]); sMethod[1] = WebUtility.UrlDecode(sMethod[1]);
if (sMethod[1].Length >= 7) if (sMethod[1].Length >= 7)
{ {
if (sMethod[1].Substring(0, 7) == "http://") if (sMethod[1].StartsWith("http://"))
{ {
sMethod[1] = sMethod[1].Substring(sMethod[1].IndexOf("/", 7)); sMethod[1] = sMethod[1].Substring(sMethod[1].IndexOf("/", 7));
} }

View File

@ -343,6 +343,9 @@ namespace Esyur.Net.Packets
var cl = data.GetUInt32(offset); var cl = data.GetUInt32(offset);
offset += 4; offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl); Content = data.Clip(offset, cl);
offset += cl; offset += cl;

View File

@ -160,42 +160,49 @@ namespace Esyur.Net.Sockets
{ {
try try
{ {
// SocketError err; if (state != SocketState.Established)
if (state == SocketState.Closed || state == SocketState.Terminated)
return; return;
if (e.BytesTransferred == 0) if (e.BytesTransferred <= 0)
{ {
Close(); Close();
return; return;
} }
//if (receiveNetworkBuffer.Protected)
// Console.WriteLine();
//lock (receiveNetworkBuffer.SyncLock)
// Console.WriteLine(e. + " " + e.BytesTransferred);
var recCount = e.BytesTransferred > e.Count ? e.Count : e.BytesTransferred; var recCount = e.BytesTransferred > e.Count ? e.Count : e.BytesTransferred;
receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)recCount); receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)recCount);
//Console.WriteLine("TC IN: " + (uint)e.BytesTransferred + " " + DC.ToHex(receiveBuffer, 0, (uint)e.BytesTransferred));
OnReceive?.Invoke(receiveNetworkBuffer); OnReceive?.Invoke(receiveNetworkBuffer);
if (state == SocketState.Established) if (state == SocketState.Established)
while(!sock.ReceiveAsync(e))
{ {
if (!sock.ReceiveAsync(socketArgs)) if (e.SocketError != SocketError.Success)
{ {
//Console.WriteLine("Sync"); Close();
SocketArgs_Completed(sender, e); return;
} }
if (State != SocketState.Established)
return;
if (e.BytesTransferred < 0)
Console.WriteLine("BytesTransferred is less than zero");
if (e.BytesTransferred <= 0)
{
Close();
return;
}
if (e.BytesTransferred > 100000)
Console.WriteLine("BytesTransferred is large " + e.BytesTransferred);
recCount = e.BytesTransferred > e.Count ? e.Count : e.BytesTransferred;
receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)recCount);
OnReceive?.Invoke(receiveNetworkBuffer);
} }
} }
@ -510,8 +517,9 @@ namespace Esyur.Net.Sockets
{ {
sock.BeginSend(msg, 0, msg.Length, SocketFlags.None, PacketSent, rt);// null); sock.BeginSend(msg, 0, msg.Length, SocketFlags.None, PacketSent, rt);// null);
} }
catch catch(Exception ex)
{ {
rt.TriggerError(ex);
asyncSending = false; asyncSending = false;
state = SocketState.Terminated; state = SocketState.Terminated;
Close(); Close();

View File

@ -80,7 +80,7 @@ namespace Esyur.Net.TCP
else else
listener = new TCPSocket(new IPEndPoint(IPAddress.Any, Port)); listener = new TCPSocket(new IPEndPoint(IPAddress.Any, Port));
Start(listener, Timeout, Clock); Start(listener);
} }

View File

@ -167,7 +167,76 @@ namespace Esyur.Resource.Template
if (classIsPublic) if (classIsPublic)
{ {
foreach (var pi in propsInfo)
{
var privateAttr = pi.GetCustomAttribute<PrivateAttribute>(true);
if (privateAttr == null)
{
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
var pt = new PropertyTemplate(this, i++, pi.Name);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
if (storageAttr != null)
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
if (annotationAttr != null)
pt.ReadExpansion = annotationAttr.Annotation;
else
pt.ReadExpansion = pi.PropertyType.Name;
pt.Info = pi;
//pt.Serilize = publicAttr.Serialize;
properties.Add(pt);
}
else
{
var attributeAttr = pi.GetCustomAttribute<AttributeAttribute>(true);
if (attributeAttr != null)
{
var at = new AttributeTemplate(this, 0, pi.Name);
at.Info = pi;
attributes.Add(at);
}
}
}
i = 0;
foreach (var ei in eventsInfo)
{
var privateAttr = ei.GetCustomAttribute<PrivateAttribute>(true);
if (privateAttr == null)
{
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
var et = new EventTemplate(this, i++, ei.Name);
et.Info = ei;
if (annotationAttr != null)
et.Expansion = annotationAttr.Annotation;
events.Add(et);
}
}
i = 0;
foreach (MethodInfo mi in methodsInfo)
{
var privateAttr = mi.GetCustomAttribute<PrivateAttribute>(true);
if (privateAttr == null)
{
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void));
if (annotationAttr != null)
ft.Expansion = annotationAttr.Annotation;
else
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
functions.Add(ft);
}
}
} }
else else
{ {

View File

@ -571,10 +571,20 @@ namespace Esyur.Resource
foreach (var p in ps) foreach (var p in ps)
{ {
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
if (pi != null) var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (pi != null && pi.CanWrite)
{
try
{
pi.SetValue(res, p.Value); pi.SetValue(res, p.Value);
} }
catch(Exception ex)
{
Global.Log(ex);
}
}
}
} }
if (store != null || parent != null || res is IStore) if (store != null || parent != null || res is IStore)