mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2026-03-31 10:28:21 +00:00
renaming 2
This commit is contained in:
38
Esiur/Protocol/EntryPoint.cs
Normal file
38
Esiur/Protocol/EntryPoint.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2019 - 2024 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Esiur.Core;
|
||||
using Esiur.Data;
|
||||
using Esiur.Resource;
|
||||
using Esiur.Data.Types;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
|
||||
public abstract class EntryPoint : Resource.Resource
|
||||
{
|
||||
public abstract AsyncReply<IResource> Query(string path, EpConnection sender);
|
||||
protected abstract override bool Create();
|
||||
}
|
||||
1753
Esiur/Protocol/EpConnection.cs
Normal file
1753
Esiur/Protocol/EpConnection.cs
Normal file
File diff suppressed because it is too large
Load Diff
35
Esiur/Protocol/EpConnectionConfig.cs
Normal file
35
Esiur/Protocol/EpConnectionConfig.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Esiur.Core;
|
||||
using Esiur.Data;
|
||||
using Esiur.Net.Packets;
|
||||
using Esiur.Security.Membership;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
|
||||
public class EpConnectionConfig
|
||||
{
|
||||
public ExceptionLevel ExceptionLevel { get; set; }
|
||||
= ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace;
|
||||
|
||||
public Func<AuthorizationRequest, AsyncReply<object>> Authenticator { get; set; }
|
||||
|
||||
public bool AutoReconnect { get; set; } = false;
|
||||
|
||||
public uint ReconnectInterval { get; set; } = 5;
|
||||
|
||||
public string Username { get; set; }
|
||||
|
||||
public bool UseWebSocket { get; set; }
|
||||
|
||||
public bool SecureWebSocket { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
|
||||
public string Token { get; set; }
|
||||
|
||||
public ulong TokenIndex { get; set; }
|
||||
|
||||
public string Domain { get; set; }
|
||||
}
|
||||
2183
Esiur/Protocol/EpConnectionProtocol.cs
Normal file
2183
Esiur/Protocol/EpConnectionProtocol.cs
Normal file
File diff suppressed because it is too large
Load Diff
13
Esiur/Protocol/EpConnectionStatus.cs
Normal file
13
Esiur/Protocol/EpConnectionStatus.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Protocol
|
||||
{
|
||||
public enum EpConnectionStatus
|
||||
{
|
||||
Closed,
|
||||
Connecting,
|
||||
Connected
|
||||
}
|
||||
}
|
||||
560
Esiur/Protocol/EpResource.cs
Normal file
560
Esiur/Protocol/EpResource.cs
Normal file
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using Esiur.Misc;
|
||||
using Esiur.Data;
|
||||
using System.Dynamic;
|
||||
using System.Security.Cryptography;
|
||||
using Esiur.Core;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Reflection.Emit;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Esiur.Resource;
|
||||
using Esiur.Net.Packets;
|
||||
using Esiur.Data.Types;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
|
||||
//[System.Runtime.InteropServices.ComVisible(true)]
|
||||
public class EpResource : DynamicObject, IResource, INotifyPropertyChanged, IDynamicResource
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the distributed resource is destroyed.
|
||||
/// </summary>
|
||||
public event DestroyedEvent OnDestroy;
|
||||
//public event PropertyModifiedEvent PropertyModified;
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
uint instanceId;
|
||||
TypeDef typeDef;
|
||||
EpConnection connection;
|
||||
|
||||
|
||||
bool attached = false;
|
||||
bool destroyed = false;
|
||||
bool suspended = false;
|
||||
|
||||
//Structure properties = new Structure();
|
||||
|
||||
string link;
|
||||
ulong age;
|
||||
|
||||
protected object[] properties;
|
||||
internal List<EpResource> parents = new List<EpResource>();
|
||||
internal List<EpResource> children = new List<EpResource>();
|
||||
|
||||
EpResourceEvent[] events;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Connection responsible for the distributed resource.
|
||||
/// </summary>
|
||||
public EpConnection DistributedResourceConnection
|
||||
{
|
||||
get { return connection; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resource link
|
||||
/// </summary>
|
||||
public string DistributedResourceLink
|
||||
{
|
||||
get { return link; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instance Id given by the other end.
|
||||
/// </summary>
|
||||
public uint DistributedResourceInstanceId
|
||||
{
|
||||
get { return instanceId; }
|
||||
internal set { instanceId = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IDestructible interface.
|
||||
/// </summary>
|
||||
public void Destroy()
|
||||
{
|
||||
destroyed = true;
|
||||
attached = false;
|
||||
connection.SendDetachRequest(instanceId);
|
||||
OnDestroy?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Suspend resource
|
||||
/// </summary>
|
||||
|
||||
internal void Suspend()
|
||||
{
|
||||
suspended = true;
|
||||
attached = false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resource is attached when all its properties are received.
|
||||
/// </summary>
|
||||
public bool DistributedResourceAttached => attached;
|
||||
|
||||
public bool DistributedResourceSuspended => suspended;
|
||||
|
||||
|
||||
// public DistributedResourceStack Stack
|
||||
//{
|
||||
// get { return stack; }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new distributed resource.
|
||||
/// </summary>
|
||||
/// <param name="connection">Connection responsible for the distributed resource.</param>
|
||||
/// <param name="template">Resource template.</param>
|
||||
/// <param name="instanceId">Instance Id given by the other end.</param>
|
||||
/// <param name="age">Resource age.</param>
|
||||
public EpResource(EpConnection connection, uint instanceId, ulong age, string link)
|
||||
{
|
||||
this.link = link;
|
||||
this.connection = connection;
|
||||
this.instanceId = instanceId;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
internal bool _Attach(PropertyValue[] properties)
|
||||
{
|
||||
if (attached)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
suspended = false;
|
||||
|
||||
this.properties = new object[properties.Length];
|
||||
|
||||
this.events = new EpResourceEvent[Instance.Definition.Events.Length];
|
||||
|
||||
for (byte i = 0; i < properties.Length; i++)
|
||||
{
|
||||
Instance.SetAge(i, properties[i].Age);
|
||||
Instance.SetModificationDate(i, properties[i].Date);
|
||||
this.properties[i] = properties[i].Value;
|
||||
}
|
||||
|
||||
// trigger holded events/property updates.
|
||||
//foreach (var r in afterAttachmentTriggers)
|
||||
// r.Key.Trigger(r.Value);
|
||||
|
||||
//afterAttachmentTriggers.Clear();
|
||||
|
||||
attached = true;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
protected internal virtual void _EmitEventByIndex(byte index, object args)
|
||||
{
|
||||
var et = Instance.Definition.GetEventDefByIndex(index);
|
||||
events[index]?.Invoke(this, args);
|
||||
Instance.EmitResourceEvent(et, args);
|
||||
}
|
||||
|
||||
public AsyncReply _Invoke(byte index, object args)
|
||||
{
|
||||
if (destroyed)
|
||||
throw new Exception("Trying to access a destroyed object.");
|
||||
|
||||
if (suspended)
|
||||
throw new Exception("Trying to access a suspended object.");
|
||||
|
||||
if (index >= Instance.Definition.Functions.Length)
|
||||
throw new Exception("Function index is incorrect.");
|
||||
|
||||
var ft = Instance.Definition.GetFunctionDefByIndex(index);
|
||||
|
||||
if (ft == null)
|
||||
throw new Exception("Function template not found.");
|
||||
|
||||
if (ft.IsStatic)
|
||||
return connection.StaticCall(Instance.Definition.Id, index, args);
|
||||
else
|
||||
return connection.SendInvoke(instanceId, index, args);
|
||||
}
|
||||
|
||||
public AsyncReply Subscribe(EventDef et)
|
||||
{
|
||||
if (et == null)
|
||||
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.MethodNotFound, ""));
|
||||
|
||||
if (!et.Subscribable)
|
||||
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotSubscribable, ""));
|
||||
|
||||
return connection.SendSubscribeRequest(instanceId, et.Index);
|
||||
}
|
||||
|
||||
public AsyncReply Subscribe(string eventName)
|
||||
{
|
||||
var et = Instance.Definition.GetEventDefByName(eventName);
|
||||
|
||||
return Subscribe(et);
|
||||
}
|
||||
|
||||
|
||||
public AsyncReply Unsubscribe(EventDef et)
|
||||
{
|
||||
if (et == null)
|
||||
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.MethodNotFound, ""));
|
||||
|
||||
if (!et.Subscribable)
|
||||
return new AsyncReply().TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.NotSubscribable, ""));
|
||||
|
||||
return connection.SendUnsubscribeRequest(instanceId, et.Index);
|
||||
}
|
||||
|
||||
public AsyncReply Unsubscribe(string eventName)
|
||||
{
|
||||
var et = Instance.Definition.GetEventDefByName(eventName);
|
||||
|
||||
return Unsubscribe(et);
|
||||
}
|
||||
|
||||
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||
{
|
||||
if (destroyed)
|
||||
throw new Exception("Trying to access a destroyed object.");
|
||||
|
||||
if (suspended)
|
||||
throw new Exception("Trying to access a suspended object.");
|
||||
|
||||
var ft = Instance.Definition.GetFunctionDefByName(binder.Name);
|
||||
|
||||
var reply = new AsyncReply<object>();
|
||||
|
||||
if (attached && ft != null)
|
||||
{
|
||||
|
||||
if (args.Length == 1)
|
||||
{
|
||||
// Detect anonymous types
|
||||
var type = args[0].GetType();
|
||||
|
||||
|
||||
if (Codec.IsAnonymous(type))
|
||||
{
|
||||
var indexedArgs = new Map<byte, object>();
|
||||
|
||||
var pis = type.GetProperties();
|
||||
|
||||
for (byte i = 0; i < ft.Arguments.Length; i++)
|
||||
{
|
||||
var pi = pis.FirstOrDefault(x => x.Name == ft.Arguments[i].Name);
|
||||
if (pi != null)
|
||||
indexedArgs.Add(i, pi.GetValue(args[0]));
|
||||
}
|
||||
|
||||
result = _Invoke(ft.Index, indexedArgs);
|
||||
}
|
||||
else if (args[0] is object[] || args[0] is Map<byte, object>)
|
||||
{
|
||||
result = _Invoke(ft.Index, new object[] { args });
|
||||
}
|
||||
else
|
||||
{
|
||||
result = _Invoke(ft.Index, args);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
result = _Invoke(ft.Index, args);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Get a property value.
|
||||
///// </summary>
|
||||
///// <param name="index">Zero-based property index.</param>
|
||||
///// <returns>Value</returns>
|
||||
//protected internal object _Get(byte index)
|
||||
//{
|
||||
//}
|
||||
|
||||
public bool TryGetPropertyValue(byte index, out object value)
|
||||
{
|
||||
if (index >= properties.Length)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = properties[index];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||
{
|
||||
if (destroyed)
|
||||
throw new Exception("Trying to access a destroyed object.");
|
||||
|
||||
|
||||
result = null;
|
||||
|
||||
if (!attached)
|
||||
return false;
|
||||
|
||||
var pt = Instance.Definition.GetPropertyDefByName(binder.Name);
|
||||
|
||||
if (pt != null)
|
||||
{
|
||||
result = properties[pt.Index];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var et = Instance.Definition.GetEventDefByName(binder.Name);
|
||||
if (et == null)
|
||||
return false;
|
||||
|
||||
result = events[et.Index];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal void _UpdatePropertyByIndex(byte index, object value)
|
||||
{
|
||||
var pt = Instance.Definition.GetPropertyDefByIndex(index);
|
||||
properties[index] = value;
|
||||
Instance.EmitModification(pt, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set property value.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <param name="value">Value</param>
|
||||
/// <returns>Indicator when the property is set.</returns>
|
||||
//protected object _SetSync(byte index, object value)
|
||||
//{
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Set property value.
|
||||
///// </summary>
|
||||
///// <param name="index">Zero-based property index.</param>
|
||||
///// <param name="value">Value</param>
|
||||
///// <returns>Indicator when the property is set.</returns>
|
||||
//protected internal AsyncReply<object> _Set(byte index, object value)
|
||||
//{
|
||||
//}
|
||||
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||
{
|
||||
if (destroyed)
|
||||
throw new Exception("Trying to access a destroyed object.");
|
||||
|
||||
if (suspended)
|
||||
throw new Exception("Trying to access a suspended object.");
|
||||
|
||||
if (!attached)
|
||||
return false;
|
||||
|
||||
var pt = Instance.Definition.GetPropertyDefByName(binder.Name);
|
||||
|
||||
if (pt != null)
|
||||
{
|
||||
SetResourceProperty(pt.Index, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var et = Instance.Definition.GetEventDefByName(binder.Name);
|
||||
if (et == null)
|
||||
return false;
|
||||
|
||||
events[et.Index] = (EpResourceEvent)value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resource interface.
|
||||
/// </summary>
|
||||
public Instance Instance
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public TypeDef ResourceDefinition
|
||||
{
|
||||
get
|
||||
{
|
||||
return typeDef;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
typeDef = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of distributed resource.
|
||||
/// </summary>
|
||||
public EpResource()
|
||||
{
|
||||
//stack = new DistributedResourceStack(this);
|
||||
//this.Instance.ResourceModified += this.OnModified;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resource interface.
|
||||
/// </summary>
|
||||
/// <param name="trigger"></param>
|
||||
/// <returns></returns>
|
||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||
{
|
||||
|
||||
if (trigger == ResourceTrigger.Initialize)
|
||||
{
|
||||
this.Instance.PropertyModified += (x) =>
|
||||
this.PropertyChanged?.Invoke(this, new ResourcePropertyChangedEventArgs(x.Name));
|
||||
}
|
||||
// do nothing.
|
||||
return new AsyncReply<bool>(true);
|
||||
}
|
||||
|
||||
protected virtual void EmitPropertyChanged(string name)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
}
|
||||
|
||||
public PropertyValue[] SerializeResource()
|
||||
{
|
||||
var props = new PropertyValue[properties.Length];
|
||||
|
||||
for (byte i = 0; i < properties.Length; i++)
|
||||
props[i] = new PropertyValue(properties[i],
|
||||
Instance.GetAge(i),
|
||||
Instance.GetModificationDate(i));
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
public Map<byte, PropertyValue> SerializeResourceAfter(ulong age = 0)
|
||||
{
|
||||
var rt = new Map<byte, PropertyValue>();
|
||||
|
||||
for (byte i = 0; i < properties.Length; i++)
|
||||
if (Instance.GetAge(i) > age)
|
||||
rt.Add(i, new PropertyValue(properties[i],
|
||||
Instance.GetAge(i),
|
||||
Instance.GetModificationDate(i)));
|
||||
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public object GetResourceProperty(byte index)
|
||||
{
|
||||
if (index >= properties.Length)
|
||||
return null;
|
||||
return properties[index];
|
||||
}
|
||||
|
||||
public AsyncReply SetResourcePropertyAsync(byte index, object value)
|
||||
{
|
||||
if (destroyed)
|
||||
throw new Exception("Trying to access a destroyed object.");
|
||||
|
||||
if (suspended)
|
||||
throw new Exception("Trying to access a suspended object.");
|
||||
|
||||
if (!attached)
|
||||
throw new Exception("Resource is not attached.");
|
||||
|
||||
if (index >= properties.Length)
|
||||
throw new Exception("Property index not found."); ;
|
||||
|
||||
var reply = new AsyncReply<object>();
|
||||
|
||||
connection.SendSetProperty(instanceId, index, value)
|
||||
.Then((res) =>
|
||||
{
|
||||
// not really needed, server will always send property modified,
|
||||
// this only happens if the programmer forgot to emit in property setter
|
||||
properties[index] = value;
|
||||
reply.Trigger(null);
|
||||
});
|
||||
|
||||
return reply;
|
||||
|
||||
}
|
||||
|
||||
public void SetResourceProperty(byte index, object value)
|
||||
{
|
||||
// Don't set the same current value
|
||||
if (properties[index] == value)
|
||||
return;
|
||||
|
||||
SetResourcePropertyAsync(index, value).Wait();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
~EpResource()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
19
Esiur/Protocol/EpResourceAttachRequestInfo.cs
Normal file
19
Esiur/Protocol/EpResourceAttachRequestInfo.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Esiur.Core;
|
||||
using Esiur.Resource;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
|
||||
internal class EpResourceAttachRequestInfo
|
||||
{
|
||||
public AsyncReply<EpResource> Reply { get; set; }
|
||||
public uint[] RequestSequence { get; set; }
|
||||
|
||||
public EpResourceAttachRequestInfo(AsyncReply<EpResource> reply, uint[] requestSequence)
|
||||
{
|
||||
Reply = reply;
|
||||
RequestSequence = requestSequence;
|
||||
}
|
||||
}
|
||||
33
Esiur/Protocol/EpResourceEvent.cs
Normal file
33
Esiur/Protocol/EpResourceEvent.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
|
||||
public delegate void EpResourceEvent(EpResource sender, object argument);
|
||||
71
Esiur/Protocol/EpResourceQueueItem.cs
Normal file
71
Esiur/Protocol/EpResourceQueueItem.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
public class EpResourceQueueItem
|
||||
{
|
||||
public enum DistributedResourceQueueItemType
|
||||
{
|
||||
Propery,
|
||||
Event
|
||||
}
|
||||
|
||||
DistributedResourceQueueItemType type;
|
||||
byte index;
|
||||
object value;
|
||||
EpResource resource;
|
||||
|
||||
public EpResourceQueueItem(EpResource resource, DistributedResourceQueueItemType type, object value, byte index)
|
||||
{
|
||||
this.resource = resource;
|
||||
this.index = index;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public EpResource Resource
|
||||
{
|
||||
get { return resource; }
|
||||
}
|
||||
public DistributedResourceQueueItemType Type
|
||||
{
|
||||
get { return type; }
|
||||
}
|
||||
|
||||
public byte Index
|
||||
{
|
||||
get { return index; }
|
||||
}
|
||||
|
||||
public object Value
|
||||
{
|
||||
get { return value; }
|
||||
}
|
||||
}
|
||||
184
Esiur/Protocol/EpServer.cs
Normal file
184
Esiur/Protocol/EpServer.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Esiur.Net.Sockets;
|
||||
using Esiur.Misc;
|
||||
using System.Threading;
|
||||
using Esiur.Data;
|
||||
using Esiur.Core;
|
||||
using System.Net;
|
||||
using Esiur.Resource;
|
||||
using Esiur.Security.Membership;
|
||||
using System.Threading.Tasks;
|
||||
using Esiur.Data.Types;
|
||||
using Esiur.Net;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
|
||||
public class EpServer : NetworkServer<EpConnection>, IResource
|
||||
{
|
||||
|
||||
|
||||
[Attribute]
|
||||
public string IP
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
IMembership membership;
|
||||
|
||||
[Attribute]
|
||||
public IMembership Membership
|
||||
{
|
||||
get => membership;
|
||||
set
|
||||
{
|
||||
if (membership != null)
|
||||
membership.Authorization -= Membership_Authorization;
|
||||
|
||||
membership = value;
|
||||
|
||||
if (membership != null)
|
||||
membership.Authorization += Membership_Authorization;
|
||||
}
|
||||
}
|
||||
|
||||
private void Membership_Authorization(AuthorizationIndication indication)
|
||||
{
|
||||
lock (Connections.SyncRoot)
|
||||
foreach (var connection in Connections)
|
||||
if (connection.Session == indication.Session)
|
||||
connection.ProcessAuthorization(indication.Results);
|
||||
}
|
||||
|
||||
[Attribute]
|
||||
public EntryPoint EntryPoint
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Attribute]
|
||||
public ushort Port
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = 10518;
|
||||
|
||||
|
||||
[Attribute]
|
||||
public ExceptionLevel ExceptionLevel { get; set; }
|
||||
= ExceptionLevel.Code
|
||||
| ExceptionLevel.Source
|
||||
| ExceptionLevel.Message
|
||||
| ExceptionLevel.Trace;
|
||||
|
||||
|
||||
public Instance Instance
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||
{
|
||||
if (trigger == ResourceTrigger.Initialize)
|
||||
{
|
||||
TCPSocket listener;
|
||||
|
||||
if (IP != null)
|
||||
listener = new TCPSocket(new IPEndPoint(IPAddress.Parse(IP), Port));
|
||||
else
|
||||
listener = new TCPSocket(new IPEndPoint(IPAddress.Any, Port));
|
||||
|
||||
Start(listener);
|
||||
}
|
||||
else if (trigger == ResourceTrigger.Terminate)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
else if (trigger == ResourceTrigger.SystemReload)
|
||||
{
|
||||
Trigger(ResourceTrigger.Terminate);
|
||||
Trigger(ResourceTrigger.Initialize);
|
||||
}
|
||||
|
||||
return new AsyncReply<bool>(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override void ClientConnected(EpConnection connection)
|
||||
{
|
||||
//Task.Delay(10000).ContinueWith((x) =>
|
||||
//{
|
||||
// Console.WriteLine("By bye");
|
||||
// // Remove me from here
|
||||
// connection.Close();
|
||||
// one = true;
|
||||
//});
|
||||
|
||||
}
|
||||
|
||||
public override void Add(EpConnection connection)
|
||||
{
|
||||
connection.Server = this;
|
||||
connection.ExceptionLevel = ExceptionLevel;
|
||||
base.Add(connection);
|
||||
}
|
||||
|
||||
public override void Remove(EpConnection connection)
|
||||
{
|
||||
connection.Server = null;
|
||||
base.Remove(connection);
|
||||
}
|
||||
|
||||
protected override void ClientDisconnected(EpConnection connection)
|
||||
{
|
||||
//connection.OnReady -= ConnectionReadyEventReceiver;
|
||||
//Warehouse.Remove(connection);
|
||||
}
|
||||
|
||||
public KeyList<string, CallInfo?> Calls { get; } = new KeyList<string, CallInfo?>();
|
||||
|
||||
public struct CallInfo
|
||||
{
|
||||
public FunctionDef Template;
|
||||
public Delegate Delegate;
|
||||
}
|
||||
|
||||
public EpServer MapCall(string call, Delegate handler)
|
||||
{
|
||||
var ft = FunctionDef.MakeFunctionDef(null, handler.Method, 0, call, null);
|
||||
Calls.Add(call, new CallInfo() { Delegate = handler, Template = ft });
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
37
Esiur/Protocol/EpSession.cs
Normal file
37
Esiur/Protocol/EpSession.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Esiur.Net;
|
||||
using Esiur.Net.Sockets;
|
||||
using Esiur.Security.Authority;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
public class EpSession : NetworkSession
|
||||
{
|
||||
public Source Source { get; set; }
|
||||
public Authentication Authentication { get; set; }
|
||||
}
|
||||
36
Esiur/Protocol/PropertyContext.cs
Normal file
36
Esiur/Protocol/PropertyContext.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Protocol;
|
||||
|
||||
public interface IPropertyContext
|
||||
{
|
||||
object GetValue(EpConnection connection);
|
||||
}
|
||||
|
||||
public class PropertyContext<T> : IPropertyContext
|
||||
{
|
||||
public T Value { get; private set; }
|
||||
public EpConnection Connection { get; private set; }
|
||||
public Func<EpConnection, T> Method { get; private set; }
|
||||
|
||||
public PropertyContext(EpConnection connection, T value)
|
||||
{
|
||||
this.Value = value;
|
||||
this.Connection = connection;
|
||||
}
|
||||
|
||||
public PropertyContext(Func<EpConnection, T> method)
|
||||
{
|
||||
this.Method = method;
|
||||
}
|
||||
|
||||
public static implicit operator PropertyContext<T>(Func<EpConnection, T> method)
|
||||
=> new PropertyContext<T>(method);
|
||||
|
||||
public object GetValue(EpConnection connection)
|
||||
{
|
||||
return Method.Invoke(connection);
|
||||
}
|
||||
}
|
||||
23
Esiur/Protocol/ResourcePropertyChangedEventArgs.cs
Normal file
23
Esiur/Protocol/ResourcePropertyChangedEventArgs.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Esiur.Resource;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Protocol
|
||||
{
|
||||
public class ResourcePropertyChangedEventArgs : PropertyChangedEventArgs
|
||||
{
|
||||
public ResourcePropertyChangedEventArgs(string propertyName) : base(propertyName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ResourcePropertyChangedEventArgs(PropertyModificationInfo info) : base(info.Name)
|
||||
{
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public readonly PropertyModificationInfo Info;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user