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

View File

@ -72,6 +72,9 @@ namespace Esyur.Net.IIP
bool ready, readyToEstablish;
string _hostname;
ushort _port;
DateTime loginDate;
/// <summary>
@ -194,15 +197,15 @@ namespace Esyur.Net.IIP
{
base.Assign(socket);
session.RemoteAuthentication.Source.Attributes.Add(SourceAttributeType.IPv4, socket.RemoteEndPoint.Address);
session.RemoteAuthentication.Source.Attributes.Add(SourceAttributeType.Port, socket.RemoteEndPoint.Port);
session.LocalAuthentication.Source.Attributes.Add(SourceAttributeType.IPv4, socket.LocalEndPoint.Address);
session.LocalAuthentication.Source.Attributes.Add(SourceAttributeType.Port, socket.LocalEndPoint.Port);
session.RemoteAuthentication.Source.Attributes[SourceAttributeType.IPv4] = socket.RemoteEndPoint.Address;
session.RemoteAuthentication.Source.Attributes[SourceAttributeType.Port] = socket.RemoteEndPoint.Port;
session.LocalAuthentication.Source.Attributes[SourceAttributeType.IPv4] = socket.LocalEndPoint.Address;
session.LocalAuthentication.Source.Attributes[SourceAttributeType.Port] = socket.LocalEndPoint.Port;
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);
@ -245,7 +248,7 @@ namespace Esyur.Net.IIP
/// <param name="password">Password.</param>
public DistributedConnection(ISocket socket, string domain, string username, string password)
{
this.session = new Session( new ClientAuthentication()
this.session = new Session(new ClientAuthentication()
, new HostAuthentication());
//Instance.Name = Global.GenerateCode(12);
//this.hostType = AuthenticationType.Client;
@ -309,7 +312,7 @@ namespace Esyur.Net.IIP
{
//var packet = new IIPPacket();
// packets++;
@ -430,7 +433,7 @@ namespace Esyur.Net.IIP
case IIPPacketAction.ResourceParents:
IIPRequestResourceParents(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.ResourceHistory:
IIPRequestInquireResourceHistory(packet.CallbackId, packet.ResourceId, packet.FromDate, packet.ToDate);
break;
@ -503,7 +506,7 @@ namespace Esyur.Net.IIP
IIPReply(packet.CallbackId);
break;
// Inquire
// Inquire
case IIPPacket.IIPPacketAction.TemplateFromClassName:
case IIPPacket.IIPPacketAction.TemplateFromClassId:
@ -634,7 +637,7 @@ namespace Esyur.Net.IIP
//var hash = hashFunc.ComputeHash(BinaryList.ToBytes(pw, remoteNonce, localNonce));
var hash = hashFunc.ComputeHash((new BinaryList())
.AddUInt8Array(pw)
.AddUInt8Array( remoteNonce)
.AddUInt8Array(remoteNonce)
.AddUInt8Array(localNonce)
.ToArray());
if (hash.SequenceEqual(remoteHash))
@ -719,7 +722,7 @@ namespace Esyur.Net.IIP
.AddUInt8Array(localPassword)
.ToArray());
if (remoteHash.SequenceEqual(authPacket.Hash))
{
// send establish request
@ -764,7 +767,7 @@ namespace Esyur.Net.IIP
return offset;
//if (offset < ends)
// processPacket(msg, offset, ends, data, chunkId);
// processPacket(msg, offset, ends, data, chunkId);
}
protected override void DataReceived(NetworkBuffer data)
@ -773,14 +776,14 @@ namespace Esyur.Net.IIP
var msg = data.Read();
uint offset = 0;
uint ends = (uint)msg.Length;
var packs = new List<string>();
var chunkId = (new Random()).Next(1000, 1000000);
var list = new List<Structure>();// double, IIPPacketCommand>();
this.Socket.Hold();
try
@ -798,7 +801,7 @@ namespace Esyur.Net.IIP
{
this.Socket.Unhold();
}
}
}
[Attribute]
@ -831,31 +834,115 @@ namespace Esyur.Net.IIP
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;
session.LocalAuthentication.Username = username;
localPassword = DC.ToBytes(Password);// Instance.Attributes["password"].ToString());
return Connect(null, address, port, username, DC.ToBytes(Password), domain);
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>();
}
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>
/// Store interface.
/// </summary>
@ -908,7 +995,7 @@ namespace Esyur.Net.IIP
throw new Exception("SS");
//if (Codec.IsLocalResource(resource, this))
// return new AsyncBag<T>((resource as DistributedResource).children.Where(x => x.GetType() == typeof(T)).Select(x => (T)x));
// return new AsyncBag<T>((resource as DistributedResource).children.Where(x => x.GetType() == typeof(T)).Select(x => (T)x));
return null;
}
@ -917,7 +1004,7 @@ namespace Esyur.Net.IIP
{
throw new Exception("SS");
//if (Codec.IsLocalResource(resource, this))
// return (resource as DistributedResource).parents.Where(x => x.GetType() == typeof(T)).Select(x => (T)x);
// return (resource as DistributedResource).parents.Where(x => x.GetType() == typeof(T)).Select(x => (T)x);
return null;
}

View File

@ -134,6 +134,18 @@ namespace Esyur.Net.IIP
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)
{
var pb = Codec.ComposeStructure(parameters, this, true, true, true);
@ -433,6 +445,7 @@ namespace Esyur.Net.IIP
void IIPRequestAttachResource(uint callback, uint resourceId)
{
Warehouse.GetById(resourceId).Then((res) =>
{
if (res != null)
@ -449,19 +462,12 @@ namespace Esyur.Net.IIP
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.Children.OnAdd -= Children_OnAdd;
// r.Instance.Children.OnRemoved -= Children_OnRemoved;
//r.Instance.Attributes.OnModified -= Attributes_OnModified;
// 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;
// Console.WriteLine("Attach {0} {1}", r.Instance.Link, r.Instance.Id);
// add it to attached resources so GC won't remove it from memory
attachedResources.Add(r);
@ -490,6 +496,19 @@ namespace Esyur.Net.IIP
.AddUInt8Array(Codec.ComposePropertyValueArray(r.Instance.Serialize(), this, true))
.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
{
@ -1886,19 +1905,23 @@ namespace Esyur.Net.IIP
/// <returns>DistributedResource</returns>
public AsyncReply<DistributedResource> Fetch(uint id)
{
if (resourceRequests.ContainsKey(id) && resources.ContainsKey(id))
var resource = resources[id];
var request = resourceRequests[id];
if (request != null)
{
Console.WriteLine("DEAD LOCK " + id);
return new AsyncReply<DistributedResource>(resources[id]);
// 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 (resource != null && !resource.Suspended)
{
return new AsyncReply<DistributedResource>(resource);
}
else if (resourceRequests.ContainsKey(id))
return resourceRequests[id];
else if (resources.ContainsKey(id))
return new AsyncReply<DistributedResource>(resources[id]);
var reply = new AsyncReply<DistributedResource>();
resourceRequests.Add(id, reply);
@ -1907,16 +1930,18 @@ namespace Esyur.Net.IIP
.Done()
.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) =>
{
// ClassId, ResourceAge, ResourceLink, Content
Warehouse.Put(dr, id.ToString(), this, null, tmp);
if (resource == null)
Warehouse.Put(dr, id.ToString(), this, null, tmp);
Codec.ParsePropertyValueArray((byte[])rt[3], this).Then((ar) =>
{
dr._Attached(ar);
dr._Attach(ar);
resourceRequests.Remove(id);
reply.Trigger(dr);
});

View File

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

View File

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