mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-09-13 12:43:17 +00:00
AsyncReply
This commit is contained in:
@@ -38,18 +38,19 @@ namespace Esiur.Core;
|
|||||||
[AsyncMethodBuilder(typeof(AsyncReplyBuilder))]
|
[AsyncMethodBuilder(typeof(AsyncReplyBuilder))]
|
||||||
public class AsyncReply
|
public class AsyncReply
|
||||||
{
|
{
|
||||||
//public bool Debug = false;
|
|
||||||
|
|
||||||
protected List<Action<object>> callbacks = new List<Action<object>>();
|
protected List<Action<object>> callbacks = new List<Action<object>>();
|
||||||
protected object result;
|
protected object result;
|
||||||
|
|
||||||
protected List<Action<AsyncException>> errorCallbacks = new List<Action<AsyncException>>();
|
protected List<Action<AsyncException>> errorCallbacks = null;
|
||||||
|
|
||||||
protected List<Action<ProgressType, int, int>> progressCallbacks = new List<Action<ProgressType, int, int>>();
|
protected List<Action<ProgressType, uint, uint>> progressCallbacks = null;
|
||||||
|
|
||||||
protected List<Action<object>> chunkCallbacks = new List<Action<object>>();
|
protected List<Action<object>> chunkCallbacks = null;
|
||||||
|
|
||||||
|
protected List<Action<object>> propagationCallbacks = null;
|
||||||
|
protected List<Action<byte, string>> warningCallbacks = null;
|
||||||
|
|
||||||
//List<AsyncAwaiter> awaiters = new List<AsyncAwaiter>();
|
|
||||||
|
|
||||||
object asyncLock = new object();
|
object asyncLock = new object();
|
||||||
|
|
||||||
@@ -77,15 +78,8 @@ public class AsyncReply
|
|||||||
if (resultReady)
|
if (resultReady)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
//if (Debug)
|
|
||||||
// Console.WriteLine($"AsyncReply: {Id} Wait");
|
|
||||||
|
|
||||||
//mutex = new AutoResetEvent(false);
|
|
||||||
mutex.WaitOne();
|
mutex.WaitOne();
|
||||||
|
|
||||||
//if (Debug)
|
|
||||||
// Console.WriteLine($"AsyncReply: {Id} Wait ended");
|
|
||||||
|
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
throw exception;
|
throw exception;
|
||||||
|
|
||||||
@@ -95,7 +89,7 @@ public class AsyncReply
|
|||||||
|
|
||||||
public AsyncReply Timeout(int milliseconds, Action callback = null)
|
public AsyncReply Timeout(int milliseconds, Action callback = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
Task.Delay(milliseconds).ContinueWith(x =>
|
Task.Delay(milliseconds).ContinueWith(x =>
|
||||||
{
|
{
|
||||||
if (!resultReady && exception == null)
|
if (!resultReady && exception == null)
|
||||||
@@ -183,34 +177,52 @@ public class AsyncReply
|
|||||||
|
|
||||||
public AsyncReply Error(Action<AsyncException> callback)
|
public AsyncReply Error(Action<AsyncException> callback)
|
||||||
{
|
{
|
||||||
// lock (callbacksLock)
|
|
||||||
// {
|
if (errorCallbacks == null)
|
||||||
|
errorCallbacks = new List<Action<AsyncException>>();
|
||||||
|
|
||||||
errorCallbacks.Add(callback);
|
errorCallbacks.Add(callback);
|
||||||
|
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
callback(exception);
|
callback(exception);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply Progress(Action<ProgressType, int, int> callback)
|
public AsyncReply Progress(Action<ProgressType, uint, uint> callback)
|
||||||
{
|
{
|
||||||
//lock (callbacksLock)
|
if (progressCallbacks == null)
|
||||||
//{
|
progressCallbacks = new List<Action<ProgressType, uint, uint>>();
|
||||||
|
|
||||||
progressCallbacks.Add(callback);
|
progressCallbacks.Add(callback);
|
||||||
return this;
|
return this;
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AsyncReply Warning(Action<byte, string> callback)
|
||||||
|
{
|
||||||
|
if (warningCallbacks == null)
|
||||||
|
warningCallbacks = new List<Action<byte, string>>();
|
||||||
|
|
||||||
|
warningCallbacks.Add(callback);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public AsyncReply Chunk(Action<object> callback)
|
public AsyncReply Chunk(Action<object> callback)
|
||||||
{
|
{
|
||||||
// lock (callbacksLock)
|
if (chunkCallbacks == null)
|
||||||
// {
|
chunkCallbacks = new List<Action<object>>();
|
||||||
|
|
||||||
chunkCallbacks.Add(callback);
|
chunkCallbacks.Add(callback);
|
||||||
return this;
|
return this;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
public AsyncReply Propagation(Action<object> callback)
|
||||||
|
{
|
||||||
|
if (propagationCallbacks == null)
|
||||||
|
propagationCallbacks = new List<Action<object>>();
|
||||||
|
|
||||||
|
propagationCallbacks.Add(callback);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply Trigger(object result)
|
public AsyncReply Trigger(object result)
|
||||||
@@ -259,32 +271,57 @@ public class AsyncReply
|
|||||||
else
|
else
|
||||||
this.exception = new AsyncException(exception);
|
this.exception = new AsyncException(exception);
|
||||||
|
|
||||||
|
if (errorCallbacks != null)
|
||||||
// lock (callbacksLock)
|
{
|
||||||
// {
|
foreach (var cb in errorCallbacks)
|
||||||
foreach (var cb in errorCallbacks)
|
cb(this.exception);
|
||||||
cb(this.exception);
|
}
|
||||||
// }
|
else
|
||||||
|
{
|
||||||
|
// no error handlers found
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
mutex?.Set();
|
mutex?.Set();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply TriggerProgress(ProgressType type, int value, int max)
|
public AsyncReply TriggerProgress(ProgressType type, uint value, uint max)
|
||||||
{
|
{
|
||||||
//timeout?.Dispose();
|
//timeout?.Dispose();
|
||||||
|
|
||||||
//lock (callbacksLock)
|
if (progressCallbacks != null)
|
||||||
//{
|
foreach (var cb in progressCallbacks)
|
||||||
foreach (var cb in progressCallbacks)
|
cb(type, value, max);
|
||||||
cb(type, value, max);
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AsyncReply TriggerWarning(byte level, string message)
|
||||||
|
{
|
||||||
|
//timeout?.Dispose();
|
||||||
|
|
||||||
|
if (warningCallbacks != null)
|
||||||
|
foreach (var cb in warningCallbacks)
|
||||||
|
cb(level, message);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AsyncReply TriggerPropagation(object value)
|
||||||
|
{
|
||||||
|
//timeout?.Dispose();
|
||||||
|
|
||||||
|
if (propagationCallbacks != null)
|
||||||
|
foreach (var cb in propagationCallbacks)
|
||||||
|
cb(value);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public AsyncReply TriggerChunk(object value)
|
public AsyncReply TriggerChunk(object value)
|
||||||
{
|
{
|
||||||
@@ -292,12 +329,10 @@ public class AsyncReply
|
|||||||
//timeout?.Dispose();
|
//timeout?.Dispose();
|
||||||
|
|
||||||
|
|
||||||
//lock (callbacksLock)
|
if (chunkCallbacks != null)
|
||||||
//{
|
foreach (var cb in chunkCallbacks)
|
||||||
foreach (var cb in chunkCallbacks)
|
cb(value);
|
||||||
cb(value);
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@@ -45,7 +45,7 @@ public class AsyncReply<T> : AsyncReply
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public new AsyncReply<T> Progress(Action<ProgressType, int, int> callback)
|
public new AsyncReply<T> Progress(Action<ProgressType, uint, uint> callback)
|
||||||
{
|
{
|
||||||
base.Progress(callback);
|
base.Progress(callback);
|
||||||
return this;
|
return this;
|
||||||
|
@@ -7,5 +7,6 @@ namespace Esiur.Core;
|
|||||||
public enum ErrorType
|
public enum ErrorType
|
||||||
{
|
{
|
||||||
Management,
|
Management,
|
||||||
Exception
|
Exception,
|
||||||
|
Warning
|
||||||
}
|
}
|
||||||
|
@@ -40,10 +40,11 @@ public enum ExceptionCode : ushort
|
|||||||
AddToStoreFailed,
|
AddToStoreFailed,
|
||||||
NotAttached,
|
NotAttached,
|
||||||
AlreadyListened,
|
AlreadyListened,
|
||||||
AlreadyUnlistened,
|
AlreadyUnsubscribed,
|
||||||
NotSubscribable,
|
NotSubscribable,
|
||||||
ParseError,
|
ParseError,
|
||||||
Timeout,
|
Timeout,
|
||||||
NotSupported,
|
NotSupported,
|
||||||
NotImplemented
|
NotImplemented,
|
||||||
|
NotAllowed
|
||||||
}
|
}
|
||||||
|
@@ -47,47 +47,110 @@ public static class Codec
|
|||||||
static AsyncParser[][] FixedAsyncParsers = new AsyncParser[][]
|
static AsyncParser[][] FixedAsyncParsers = new AsyncParser[][]
|
||||||
{
|
{
|
||||||
new AsyncParser[]{
|
new AsyncParser[]{
|
||||||
|
DataDeserializer.NullParserAsync,
|
||||||
|
DataDeserializer.BooleanFalseParserAsync,
|
||||||
|
DataDeserializer.BooleanTrueParserAsync,
|
||||||
|
DataDeserializer.NotModifiedParserAsync,
|
||||||
|
},
|
||||||
|
new AsyncParser[]{
|
||||||
|
DataDeserializer.UInt8ParserAsync,
|
||||||
|
DataDeserializer.Int8ParserAsync,
|
||||||
|
DataDeserializer.Char8ParserAsync,
|
||||||
|
DataDeserializer.LocalResourceParser8Async,
|
||||||
|
DataDeserializer.ResourceParser8Async,
|
||||||
|
},
|
||||||
|
new AsyncParser[]{
|
||||||
|
DataDeserializer.Int16ParserAsync,
|
||||||
|
DataDeserializer.UInt16ParserAsync,
|
||||||
|
DataDeserializer.Char16ParserAsync,
|
||||||
|
DataDeserializer.LocalResourceParser16Async,
|
||||||
|
DataDeserializer.ResourceParser16Async,
|
||||||
|
},
|
||||||
|
new AsyncParser[]{
|
||||||
|
DataDeserializer.Int32ParserAsync,
|
||||||
|
DataDeserializer.UInt32ParserAsync,
|
||||||
|
DataDeserializer.Float32ParserAsync,
|
||||||
|
DataDeserializer.LocalResourceParser32Async,
|
||||||
|
DataDeserializer.ResourceParser32Async,
|
||||||
|
},
|
||||||
|
new AsyncParser[]{
|
||||||
|
DataDeserializer.Int64ParserAsync,
|
||||||
|
DataDeserializer.UInt64ParserAsync,
|
||||||
|
DataDeserializer.Float64ParserAsync,
|
||||||
|
DataDeserializer.DateTimeParserAsync,
|
||||||
|
},
|
||||||
|
new AsyncParser[]
|
||||||
|
{
|
||||||
|
DataDeserializer.Int128ParserAsync, // int 128
|
||||||
|
DataDeserializer.UInt128ParserAsync, // uint 128
|
||||||
|
DataDeserializer.Float128ParserAsync,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static AsyncParser[] DynamicAsyncParsers = new AsyncParser[]
|
||||||
|
{
|
||||||
|
DataDeserializer.RawDataParserAsync,
|
||||||
|
DataDeserializer.StringParserAsync,
|
||||||
|
DataDeserializer.ListParserAsync,
|
||||||
|
DataDeserializer.ResourceListParserAsync,
|
||||||
|
DataDeserializer.RecordListParserAsync,
|
||||||
|
};
|
||||||
|
|
||||||
|
static AsyncParser[] TypedAsyncParsers = new AsyncParser[]
|
||||||
|
{
|
||||||
|
DataDeserializer.RecordParserAsync,
|
||||||
|
DataDeserializer.TypedListParserAsync,
|
||||||
|
DataDeserializer.TypedMapParserAsync,
|
||||||
|
DataDeserializer.TupleParserAsync,
|
||||||
|
DataDeserializer.EnumParserAsync,
|
||||||
|
DataDeserializer.ConstantParserAsync,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static SyncParser[][] FixedParsers = new SyncParser[][]
|
||||||
|
{
|
||||||
|
new SyncParser[]{
|
||||||
DataDeserializer.NullParser,
|
DataDeserializer.NullParser,
|
||||||
DataDeserializer.BooleanFalseParser,
|
DataDeserializer.BooleanFalseParser,
|
||||||
DataDeserializer.BooleanTrueParser,
|
DataDeserializer.BooleanTrueParser,
|
||||||
DataDeserializer.NotModifiedParser,
|
DataDeserializer.NotModifiedParser,
|
||||||
},
|
},
|
||||||
new AsyncParser[]{
|
new SyncParser[]{
|
||||||
DataDeserializer.ByteParser,
|
DataDeserializer.UInt8Parser,
|
||||||
DataDeserializer.SByteParser,
|
DataDeserializer.Int8Parser,
|
||||||
DataDeserializer.Char8Parser,
|
DataDeserializer.Char8Parser,
|
||||||
DataDeserializer.LocalResourceParser8,
|
DataDeserializer.LocalResourceParser8,
|
||||||
DataDeserializer.ResourceParser8,
|
DataDeserializer.ResourceParser8,
|
||||||
},
|
},
|
||||||
new AsyncParser[]{
|
new SyncParser[]{
|
||||||
DataDeserializer.Int16Parser,
|
DataDeserializer.Int16Parser,
|
||||||
DataDeserializer.UInt16Parser,
|
DataDeserializer.UInt16Parser,
|
||||||
DataDeserializer.Char16Parser,
|
DataDeserializer.Char16Parser,
|
||||||
DataDeserializer.LocalResourceParser16,
|
DataDeserializer.LocalResourceParser16,
|
||||||
DataDeserializer.ResourceParser16,
|
DataDeserializer.ResourceParser16,
|
||||||
},
|
},
|
||||||
new AsyncParser[]{
|
new SyncParser[]{
|
||||||
DataDeserializer.Int32Parser,
|
DataDeserializer.Int32Parser,
|
||||||
DataDeserializer.UInt32Parser,
|
DataDeserializer.UInt32Parser,
|
||||||
DataDeserializer.Float32Parser,
|
DataDeserializer.Float32Parser,
|
||||||
DataDeserializer.LocalResourceParser32,
|
DataDeserializer.LocalResourceParser32,
|
||||||
DataDeserializer.ResourceParser32,
|
DataDeserializer.ResourceParser32,
|
||||||
},
|
},
|
||||||
new AsyncParser[]{
|
new SyncParser[]{
|
||||||
DataDeserializer.Int64Parser,
|
DataDeserializer.Int64Parser,
|
||||||
DataDeserializer.UInt64Parser,
|
DataDeserializer.UInt64Parser,
|
||||||
DataDeserializer.Float64Parser,
|
DataDeserializer.Float64Parser,
|
||||||
DataDeserializer.DateTimeParser,
|
DataDeserializer.DateTimeParser,
|
||||||
},
|
},
|
||||||
new AsyncParser[]
|
new SyncParser[]
|
||||||
{
|
{
|
||||||
DataDeserializer.Int128Parser, // int 128
|
DataDeserializer.Int128Parser, // int 128
|
||||||
DataDeserializer.UInt128Parser, // uint 128
|
DataDeserializer.UInt128Parser, // uint 128
|
||||||
DataDeserializer.Float128Parser,
|
DataDeserializer.Float128Parser,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static AsyncParser[] DynamicAsyncParsers = new AsyncParser[]
|
static SyncParser[] DynamicParsers = new SyncParser[]
|
||||||
{
|
{
|
||||||
DataDeserializer.RawDataParser,
|
DataDeserializer.RawDataParser,
|
||||||
DataDeserializer.StringParser,
|
DataDeserializer.StringParser,
|
||||||
@@ -96,7 +159,7 @@ public static class Codec
|
|||||||
DataDeserializer.RecordListParser,
|
DataDeserializer.RecordListParser,
|
||||||
};
|
};
|
||||||
|
|
||||||
static AsyncParser[] TypedAsyncParsers = new AsyncParser[]
|
static SyncParser[] TypedParsers = new SyncParser[]
|
||||||
{
|
{
|
||||||
DataDeserializer.RecordParser,
|
DataDeserializer.RecordParser,
|
||||||
DataDeserializer.TypedListParser,
|
DataDeserializer.TypedListParser,
|
||||||
@@ -106,7 +169,6 @@ public static class Codec
|
|||||||
DataDeserializer.ConstantParser,
|
DataDeserializer.ConstantParser,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parse a value
|
/// Parse a value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -246,15 +308,15 @@ public static class Codec
|
|||||||
[typeof(IResource[])] = DataSerializer.ResourceListComposer,
|
[typeof(IResource[])] = DataSerializer.ResourceListComposer,
|
||||||
[typeof(IResource?[])] = DataSerializer.ResourceListComposer,
|
[typeof(IResource?[])] = DataSerializer.ResourceListComposer,
|
||||||
[typeof(List<IResource>)] = DataSerializer.ResourceListComposer,
|
[typeof(List<IResource>)] = DataSerializer.ResourceListComposer,
|
||||||
[typeof(List<IResource?>)] = DataSerializer.ResourceListComposer,
|
[typeof(List<IResource?>)] = DataSerializer.ResourceListComposer,
|
||||||
[typeof(VarList<IResource>)] = DataSerializer.ResourceListComposer,
|
[typeof(VarList<IResource>)] = DataSerializer.ResourceListComposer,
|
||||||
[typeof(VarList<IResource?>)] = DataSerializer.ResourceListComposer,
|
[typeof(VarList<IResource?>)] = DataSerializer.ResourceListComposer,
|
||||||
[typeof(IRecord[])] = DataSerializer.RecordListComposer,
|
[typeof(IRecord[])] = DataSerializer.RecordListComposer,
|
||||||
[typeof(IRecord?[])] = DataSerializer.RecordListComposer,
|
[typeof(IRecord?[])] = DataSerializer.RecordListComposer,
|
||||||
[typeof(List<IRecord>)] = DataSerializer.RecordListComposer,
|
[typeof(List<IRecord>)] = DataSerializer.RecordListComposer,
|
||||||
[typeof(List<IRecord?>)] = DataSerializer.RecordListComposer,
|
[typeof(List<IRecord?>)] = DataSerializer.RecordListComposer,
|
||||||
[typeof(VarList<IRecord>)] = DataSerializer.RecordListComposer,
|
[typeof(VarList<IRecord>)] = DataSerializer.RecordListComposer,
|
||||||
[typeof(VarList<IRecord?>)] = DataSerializer.RecordListComposer,
|
[typeof(VarList<IRecord?>)] = DataSerializer.RecordListComposer,
|
||||||
[typeof(Map<object, object>)] = DataSerializer.MapComposer,
|
[typeof(Map<object, object>)] = DataSerializer.MapComposer,
|
||||||
[typeof(Map<object?, object>)] = DataSerializer.MapComposer,
|
[typeof(Map<object?, object>)] = DataSerializer.MapComposer,
|
||||||
[typeof(Map<object, object?>)] = DataSerializer.MapComposer,
|
[typeof(Map<object, object?>)] = DataSerializer.MapComposer,
|
||||||
|
@@ -373,7 +373,7 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
var initRecord = (TypeTemplate template) =>
|
var initRecord = (TypeTemplate template) =>
|
||||||
{
|
{
|
||||||
ListParser(data, offset, length, connection, requestSequence).Then(r =>
|
ListParserAsync(data, offset, length, connection, requestSequence).Then(r =>
|
||||||
{
|
{
|
||||||
var ar = (object[])r;
|
var ar = (object[])r;
|
||||||
|
|
||||||
@@ -684,6 +684,31 @@ public static class DataDeserializer
|
|||||||
return rt.ToArray();
|
return rt.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static (uint, ulong, object[]) LimitedCountListParser(byte[] data, uint offset, ulong length, uint countLimit = uint.MaxValue)
|
||||||
|
{
|
||||||
|
var rt = new List<object>();
|
||||||
|
|
||||||
|
while (length > 0 && rt.Count < countLimit)
|
||||||
|
{
|
||||||
|
var (cs, reply) = Codec.ParseSync(data, offset);
|
||||||
|
|
||||||
|
rt.Add(reply);
|
||||||
|
|
||||||
|
if (cs > 0)
|
||||||
|
{
|
||||||
|
offset += (uint)cs;
|
||||||
|
length -= (uint)cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Error while parsing structured data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (offset, length, rt.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static AsyncReply TypedMapParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
public static AsyncReply TypedMapParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
// get key type
|
// get key type
|
||||||
@@ -826,6 +851,21 @@ public static class DataDeserializer
|
|||||||
var type = typeof(ValueTuple<,,,>).MakeGenericType(types.ToArray());
|
var type = typeof(ValueTuple<,,,>).MakeGenericType(types.ToArray());
|
||||||
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3]));
|
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3]));
|
||||||
}
|
}
|
||||||
|
else if (ar.Length == 5)
|
||||||
|
{
|
||||||
|
var type = typeof(ValueTuple<,,,,>).MakeGenericType(types.ToArray());
|
||||||
|
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4]));
|
||||||
|
}
|
||||||
|
else if (ar.Length == 6)
|
||||||
|
{
|
||||||
|
var type = typeof(ValueTuple<,,,,,>).MakeGenericType(types.ToArray());
|
||||||
|
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4], ar[5]));
|
||||||
|
}
|
||||||
|
else if (ar.Length == 7)
|
||||||
|
{
|
||||||
|
var type = typeof(ValueTuple<,,,,,,>).MakeGenericType(types.ToArray());
|
||||||
|
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4], ar[5], ar[6]));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
@@ -896,9 +936,12 @@ public static class DataDeserializer
|
|||||||
var type = typeof(ValueTuple<,,,,,,>).MakeGenericType(types.ToArray());
|
var type = typeof(ValueTuple<,,,,,,>).MakeGenericType(types.ToArray());
|
||||||
return Activator.CreateInstance(type, results[0], results[1], results[2], results[3], results[4], results[5], results[6]);
|
return Activator.CreateInstance(type, results[0], results[1], results[2], results[3], results[4], results[5], results[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new Exception("Unknown tuple length.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
public static AsyncReply TypedListParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
var rt = new AsyncBag<object>();
|
var rt = new AsyncBag<object>();
|
||||||
|
|
||||||
@@ -932,13 +975,47 @@ public static class DataDeserializer
|
|||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static object TypedListParser(byte[] data, uint offset, uint length)
|
||||||
|
{
|
||||||
|
|
||||||
public static AsyncBag<PropertyValue> PropertyValueArrayParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
|
// get the type
|
||||||
|
var (hdrCs, rep) = RepresentationType.Parse(data, offset);
|
||||||
|
|
||||||
|
offset += hdrCs;
|
||||||
|
length -= hdrCs;
|
||||||
|
|
||||||
|
var runtimeType = rep.GetRuntimeType();
|
||||||
|
|
||||||
|
var list = new List<object>();
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
var (cs, reply) = Codec.ParseSync(data, offset);
|
||||||
|
|
||||||
|
list.Add(reply);
|
||||||
|
|
||||||
|
if (cs > 0)
|
||||||
|
{
|
||||||
|
offset += (uint)cs;
|
||||||
|
length -= (uint)cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Error while parsing structured data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var rt = Array.CreateInstance(runtimeType, list.Count);
|
||||||
|
Array.Copy(list.ToArray(), rt, rt.Length);
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncBag<PropertyValue> PropertyValueArrayParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
|
||||||
{
|
{
|
||||||
var rt = new AsyncBag<PropertyValue>();
|
var rt = new AsyncBag<PropertyValue>();
|
||||||
|
|
||||||
|
|
||||||
ListParser(data, offset, length, connection, requestSequence).Then(x =>
|
ListParserAsync(data, offset, length, connection, requestSequence).Then(x =>
|
||||||
{
|
{
|
||||||
var ar = (object[])x;
|
var ar = (object[])x;
|
||||||
var pvs = new List<PropertyValue>();
|
var pvs = new List<PropertyValue>();
|
||||||
@@ -954,7 +1031,8 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (uint, AsyncReply<PropertyValue>) PropertyValueParser(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
|
|
||||||
|
public static (uint, AsyncReply<PropertyValue>) PropertyValueParserAsync(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
|
||||||
{
|
{
|
||||||
var reply = new AsyncReply<PropertyValue>();
|
var reply = new AsyncReply<PropertyValue>();
|
||||||
|
|
||||||
@@ -967,15 +1045,22 @@ public static class DataDeserializer
|
|||||||
|
|
||||||
var (valueSize, results) = Codec.ParseAsync(data, offset, connection, requestSequence);
|
var (valueSize, results) = Codec.ParseAsync(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
results.Then(value =>
|
if (results is AsyncReply)
|
||||||
{
|
{
|
||||||
reply.Trigger(new PropertyValue(value, age, date));
|
(results as AsyncReply).Then(value =>
|
||||||
});
|
{
|
||||||
|
reply.Trigger(new PropertyValue(value, age, date));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reply.Trigger(new PropertyValue(results, age, date));
|
||||||
|
}
|
||||||
|
|
||||||
return (16 + valueSize, reply);
|
return (16 + valueSize, reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParser(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence)
|
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParserAsync(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence)
|
||||||
{
|
{
|
||||||
//var count = (int)toAge - (int)fromAge;
|
//var count = (int)toAge - (int)fromAge;
|
||||||
|
|
||||||
@@ -994,7 +1079,7 @@ public static class DataDeserializer
|
|||||||
var cs = data.GetUInt32(offset, Endian.Little);
|
var cs = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
var (len, pv) = PropertyValueParser(data, offset, connection, requestSequence);
|
var (len, pv) = PropertyValueParserAsync(data, offset, connection, requestSequence);
|
||||||
|
|
||||||
bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
|
bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
|
||||||
offset += len;
|
offset += len;
|
||||||
|
@@ -102,7 +102,7 @@ public static class DataSerializer
|
|||||||
var rt = new byte[16];
|
var rt = new byte[16];
|
||||||
fixed (byte* ptr = rt)
|
fixed (byte* ptr = rt)
|
||||||
*((decimal*)ptr) = v;
|
*((decimal*)ptr) = v;
|
||||||
return (TransmissionTypeIdentifier.Float128, rt);
|
return (TransmissionTypeIdentifier.Decimal128, rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ public static class DataSerializer
|
|||||||
var intVal = Convert.ChangeType(value, (value as Enum).GetTypeCode());
|
var intVal = Convert.ChangeType(value, (value as Enum).GetTypeCode());
|
||||||
|
|
||||||
var ct = template.Constants.FirstOrDefault(x => x.Value.Equals(intVal));
|
var ct = template.Constants.FirstOrDefault(x => x.Value.Equals(intVal));
|
||||||
|
|
||||||
if (ct == null)
|
if (ct == null)
|
||||||
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ public static class DataSerializer
|
|||||||
rt.AddRange(template.ClassId.Data);
|
rt.AddRange(template.ClassId.Data);
|
||||||
rt.Add(ct.Index);
|
rt.Add(ct.Index);
|
||||||
|
|
||||||
return (TransmissionTypeIdentifier.Enum, rt.ToArray());
|
return (TransmissionTypeIdentifier.TypedEnum, rt.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (TransmissionTypeIdentifier, byte[]) UInt8Composer(object value, DistributedConnection connection)
|
public static (TransmissionTypeIdentifier, byte[]) UInt8Composer(object value, DistributedConnection connection)
|
||||||
@@ -146,7 +146,7 @@ public static class DataSerializer
|
|||||||
|
|
||||||
public static unsafe (TransmissionTypeIdentifier, byte[]) Char8Composer(object value, DistributedConnection connection)
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Char8Composer(object value, DistributedConnection connection)
|
||||||
{
|
{
|
||||||
return (TransmissionTypeIdentifier.Char8, new byte[] { (byte)(char)value });
|
return (TransmissionTypeIdentifier.Char8, new byte[] { (byte)(char)value });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe (TransmissionTypeIdentifier, byte[]) Char16Composer(object value, DistributedConnection connection)
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Char16Composer(object value, DistributedConnection connection)
|
||||||
@@ -241,7 +241,7 @@ public static class DataSerializer
|
|||||||
// .ToArray();
|
// .ToArray();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public static (TransmissionTypeIdentifier, byte[]) PropertyValueArrayComposer(object value, DistributedConnection connection)
|
public static (TransmissionTypeIdentifier, byte[]) PropertyValueArrayComposer(object value, DistributedConnection connection)
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
@@ -274,9 +274,9 @@ public static class DataSerializer
|
|||||||
|
|
||||||
var map = (IMap)value;
|
var map = (IMap)value;
|
||||||
|
|
||||||
foreach(var el in map.Serialize())
|
foreach (var el in map.Serialize())
|
||||||
rt.AddRange(Codec.Compose(el, connection));
|
rt.AddRange(Codec.Compose(el, connection));
|
||||||
|
|
||||||
return (TransmissionTypeIdentifier.TypedMap, rt.ToArray());
|
return (TransmissionTypeIdentifier.TypedMap, rt.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,32 +315,59 @@ public static class DataSerializer
|
|||||||
public static unsafe (TransmissionTypeIdentifier, byte[]) ResourceComposer(object value, DistributedConnection connection)
|
public static unsafe (TransmissionTypeIdentifier, byte[]) ResourceComposer(object value, DistributedConnection connection)
|
||||||
{
|
{
|
||||||
var resource = (IResource)value;
|
var resource = (IResource)value;
|
||||||
var rt = new byte[4];
|
|
||||||
|
|
||||||
if (resource.Instance == null || resource.Instance.IsDestroyed)
|
if (resource.Instance == null || resource.Instance.IsDestroyed)
|
||||||
{
|
{
|
||||||
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Codec.IsLocalResource(resource, connection))
|
if (Codec.IsLocalResource(resource, connection))
|
||||||
{
|
{
|
||||||
|
var rid = (resource as DistributedResource).DistributedResourceInstanceId;
|
||||||
|
|
||||||
fixed (byte* ptr = rt)
|
if (rid <= 0xFF)
|
||||||
*((uint*)ptr) = (resource as DistributedResource).DistributedResourceInstanceId;
|
return (TransmissionTypeIdentifier.LocalResource8, new byte[] { (byte)rid });
|
||||||
|
else if (rid <= 0xFFFF)
|
||||||
|
{
|
||||||
|
var rt = new byte[2];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((ushort*)ptr) = (ushort)rid;
|
||||||
|
|
||||||
return (TransmissionTypeIdentifier.ResourceLocal, rt);
|
return (TransmissionTypeIdentifier.LocalResource16, rt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var rt = new byte[4];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((uint*)ptr) = rid;
|
||||||
|
return (TransmissionTypeIdentifier.LocalResource32, rt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
//rt.Append((value as IResource).Instance.Template.ClassId, (value as IResource).Instance.Id);
|
//rt.Append((value as IResource).Instance.Template.ClassId, (value as IResource).Instance.Id);
|
||||||
connection.cache.Add(value as IResource, DateTime.UtcNow);
|
connection.cache.Add(value as IResource, DateTime.UtcNow);
|
||||||
|
|
||||||
|
var rid = resource.Instance.Id;
|
||||||
fixed (byte* ptr = rt)
|
|
||||||
*((uint*)ptr) = resource.Instance.Id;
|
|
||||||
|
|
||||||
return (TransmissionTypeIdentifier.Resource, rt);
|
if (rid <= 0xFF)
|
||||||
|
return (TransmissionTypeIdentifier.RemoteResource8, new byte[] { (byte)rid });
|
||||||
|
else if (rid <= 0xFFFF)
|
||||||
|
{
|
||||||
|
var rt = new byte[2];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((ushort*)ptr) = (ushort)rid;
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.RemoteResource16, rt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var rt = new byte[4];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((uint*)ptr) = rid;
|
||||||
|
return (TransmissionTypeIdentifier.RemoteResource32, rt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,7 +427,7 @@ public static class DataSerializer
|
|||||||
var rt = new List<byte>();
|
var rt = new List<byte>();
|
||||||
|
|
||||||
var fields = value.GetType().GetFields();
|
var fields = value.GetType().GetFields();
|
||||||
var list = fields.Select(x => x.GetValue(value)).ToArray();
|
var list = fields.Select(x => x.GetValue(value)).ToArray();
|
||||||
var types = fields.Select(x => RepresentationType.FromType(x.FieldType).Compose()).ToArray();
|
var types = fields.Select(x => RepresentationType.FromType(x.FieldType).Compose()).ToArray();
|
||||||
|
|
||||||
rt.Add((byte)list.Length);
|
rt.Add((byte)list.Length);
|
||||||
@@ -415,7 +442,7 @@ public static class DataSerializer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt.AddRange(composed);
|
rt.AddRange(composed);
|
||||||
return (TransmissionTypeIdentifier.Tuple, rt.ToArray());
|
return (TransmissionTypeIdentifier.TypedTuple, rt.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,7 @@ using Esiur.Resource;
|
|||||||
using Esiur.Resource.Template;
|
using Esiur.Resource.Template;
|
||||||
using Esiur.Security.Authority;
|
using Esiur.Security.Authority;
|
||||||
using Esiur.Security.Membership;
|
using Esiur.Security.Membership;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
@@ -49,6 +50,39 @@ namespace Esiur.Net.IIP;
|
|||||||
public partial class DistributedConnection : NetworkConnection, IStore
|
public partial class DistributedConnection : NetworkConnection, IStore
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public delegate void ProtocolGeneralHandler(DistributedConnection connection, TransmissionType dataType, byte[] data);
|
||||||
|
|
||||||
|
public delegate void ProtocolRequestReplyHandler(DistributedConnection connection, uint callbackId, TransmissionType dataType, byte[] data);
|
||||||
|
|
||||||
|
//ProtocolGeneralHandler[] NotificationHandlers = new ProtocolGeneralHandler[]
|
||||||
|
//{
|
||||||
|
// IIPNotificationResourceDestroyed,
|
||||||
|
// IIPNotificationResourceReassigned,
|
||||||
|
// IIPNotificationResourceMoved,
|
||||||
|
// IIPNotificationSystemFailure,
|
||||||
|
// IIPNotificationPropertyModified
|
||||||
|
//};
|
||||||
|
|
||||||
|
//ProtocolRequestReplyHandler[] RequestHandlers = new ProtocolRequestReplyHandler[]
|
||||||
|
//{
|
||||||
|
// IIPRequestAttachResource,
|
||||||
|
// IIPRequest
|
||||||
|
|
||||||
|
//};
|
||||||
|
|
||||||
|
//ProtocolRequestReplyHandler[] ReplyHandlers = new ProtocolRequestReplyHandler[]
|
||||||
|
//{
|
||||||
|
|
||||||
|
//};
|
||||||
|
|
||||||
|
//ProtocolGeneralHandler[] ExtensionHandler = new ProtocolGeneralHandler[]
|
||||||
|
//{
|
||||||
|
|
||||||
|
//};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Delegates
|
// Delegates
|
||||||
public delegate void ReadyEvent(DistributedConnection sender);
|
public delegate void ReadyEvent(DistributedConnection sender);
|
||||||
public delegate void ErrorEvent(DistributedConnection sender, byte errorCode, string errorMessage);
|
public delegate void ErrorEvent(DistributedConnection sender, byte errorCode, string errorMessage);
|
||||||
@@ -112,10 +146,10 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Session Session => session;
|
public Session Session => session;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public virtual ConnectionStatus Status { get; private set; }
|
public virtual ConnectionStatus Status { get; private set; }
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public virtual uint Jitter { get; private set; }
|
public virtual uint Jitter { get; private set; }
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
@@ -164,6 +198,9 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send data to the other end as parameters
|
/// Send data to the other end as parameters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -373,16 +410,11 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
lastKeepAliveSent = now;
|
lastKeepAliveSent = now;
|
||||||
|
|
||||||
SendRequest(IIPPacketRequest.KeepAlive)
|
SendRequest(IIPPacketRequest.KeepAlive, now, interval)
|
||||||
.AddDateTime(now)
|
|
||||||
.AddUInt32(interval)
|
|
||||||
.Done()
|
|
||||||
.Then(x =>
|
.Then(x =>
|
||||||
{
|
{
|
||||||
|
Jitter = (uint)x;
|
||||||
Jitter = (uint)x[1];
|
|
||||||
keepAliveTimer.Start();
|
keepAliveTimer.Start();
|
||||||
//Console.WriteLine($"Keep Alive Received {Jitter}");
|
|
||||||
}).Error(ex =>
|
}).Error(ex =>
|
||||||
{
|
{
|
||||||
keepAliveTimer.Stop();
|
keepAliveTimer.Stop();
|
||||||
@@ -393,9 +425,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
Close();
|
Close();
|
||||||
});
|
});
|
||||||
|
|
||||||
//Console.WriteLine("Keep Alive sent");
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint KeepAliveInterval { get; set; } = 30;
|
public uint KeepAliveInterval { get; set; } = 30;
|
||||||
@@ -417,7 +446,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
if (rt <= 0)
|
if (rt <= 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
var size = ends - offset;
|
var size = ends - offset;
|
||||||
data.HoldFor(msg, offset, size, size + (uint)(-rt));
|
data.HoldFor(msg, offset, size, size + (uint)(-rt));
|
||||||
return ends;
|
return ends;
|
||||||
@@ -427,311 +455,153 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
offset += (uint)rt;
|
offset += (uint)rt;
|
||||||
|
|
||||||
if (packet.DataType != null)
|
if (packet.DataType == null)
|
||||||
{
|
return offset;
|
||||||
var dt = packet.DataType.Value;
|
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(msg, dt.Offset, this, null, dt);
|
|
||||||
|
|
||||||
parsed.Then(value =>
|
|
||||||
{
|
|
||||||
if (packet.Method == IIPPacketMethod.Notification)
|
|
||||||
{
|
|
||||||
switch (packet.Notification)
|
|
||||||
{
|
|
||||||
case IIPPacketNotification.ResourceDestroyed:
|
|
||||||
IIPNotificationResourceDestroyed(value);
|
|
||||||
break;
|
|
||||||
case IIPPacketNotification.ResourceReassigned:
|
|
||||||
IIPNotificationResourceReassigned(value);
|
|
||||||
break;
|
|
||||||
case IIPPacketNotification.ResourceMoved:
|
|
||||||
IIPNotificationResourceMoved(value);
|
|
||||||
break;
|
|
||||||
case IIPPacketNotification.SystemFailure:
|
|
||||||
IIPNotificationSystemFailure(value);
|
|
||||||
break;
|
|
||||||
case IIPPacketNotification.PropertyModified:
|
|
||||||
IIPNotificationPropertyModified()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packet.Method == IIPPacketMethod.Notification)
|
if (packet.Method == IIPPacketMethod.Notification)
|
||||||
{
|
{
|
||||||
|
var dt = packet.DataType.Value;
|
||||||
|
|
||||||
switch (packet.Notification)
|
switch (packet.Notification)
|
||||||
{
|
{
|
||||||
|
// Invoke
|
||||||
|
case IIPPacketNotification.PropertyModified:
|
||||||
|
IIPNotificationPropertyModified(dt, msg);
|
||||||
|
break;
|
||||||
|
case IIPPacketNotification.EventOccurred:
|
||||||
|
IIPNotificationEventOccurred(dt, msg);
|
||||||
|
break;
|
||||||
|
// Manage
|
||||||
case IIPPacketNotification.ResourceDestroyed:
|
case IIPPacketNotification.ResourceDestroyed:
|
||||||
|
IIPNotificationResourceDestroyed(dt, msg);
|
||||||
case IIPPacketEvent.ResourceReassigned:
|
|
||||||
IIPEventResourceReassigned(packet.ResourceId, packet.NewResourceId);
|
|
||||||
break;
|
break;
|
||||||
case IIPPacketEvent.ResourceDestroyed:
|
case IIPPacketNotification.ResourceReassigned:
|
||||||
IIPEventResourceDestroyed(packet.ResourceId);
|
IIPNotificationResourceReassigned(dt, msg);
|
||||||
break;
|
break;
|
||||||
case IIPPacketEvent.PropertyUpdated:
|
case IIPPacketNotification.ResourceMoved:
|
||||||
IIPEventPropertyUpdated(packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
IIPNotificationResourceMoved(dt, msg);
|
||||||
break;
|
break;
|
||||||
case IIPPacketEvent.EventOccurred:
|
case IIPPacketNotification.SystemFailure:
|
||||||
IIPEventEventOccurred(packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
IIPNotificationSystemFailure(dt, msg);
|
||||||
break;
|
|
||||||
|
|
||||||
case IIPPacketEvent.ChildAdded:
|
|
||||||
IIPEventChildAdded(packet.ResourceId, packet.ChildId);
|
|
||||||
break;
|
|
||||||
case IIPPacketEvent.ChildRemoved:
|
|
||||||
IIPEventChildRemoved(packet.ResourceId, packet.ChildId);
|
|
||||||
break;
|
|
||||||
case IIPPacketEvent.Renamed:
|
|
||||||
IIPEventRenamed(packet.ResourceId, packet.ResourceLink);
|
|
||||||
break;
|
|
||||||
case IIPPacketEvent.AttributesUpdated:
|
|
||||||
// @TODO: fix this
|
|
||||||
//IIPEventAttributesUpdated(packet.ResourceId, packet.Content);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (packet.Command == IIPPacketCommand.Request)
|
else if (packet.Method == IIPPacketMethod.Request)
|
||||||
{
|
{
|
||||||
switch (packet.Action)
|
var dt = packet.DataType.Value;
|
||||||
|
|
||||||
|
switch (packet.Request)
|
||||||
{
|
{
|
||||||
// Manage
|
|
||||||
case IIPPacketRequest.AttachResource:
|
|
||||||
IIPRequestAttachResource(packet.CallbackId, packet.ResourceId);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.ReattachResource:
|
|
||||||
IIPRequestReattachResource(packet.CallbackId, packet.ResourceId, packet.ResourceAge);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.DetachResource:
|
|
||||||
IIPRequestDetachResource(packet.CallbackId, packet.ResourceId);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.CreateResource:
|
|
||||||
//@TODO : fix this
|
|
||||||
//IIPRequestCreateResource(packet.CallbackId, packet.StoreId, packet.ResourceId, packet.Content);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.DeleteResource:
|
|
||||||
IIPRequestDeleteResource(packet.CallbackId, packet.ResourceId);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.AddChild:
|
|
||||||
IIPRequestAddChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.RemoveChild:
|
|
||||||
IIPRequestRemoveChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.RenameResource:
|
|
||||||
IIPRequestRenameResource(packet.CallbackId, packet.ResourceId, packet.ResourceName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Inquire
|
|
||||||
case IIPPacketRequest.TemplateFromClassName:
|
|
||||||
IIPRequestTemplateFromClassName(packet.CallbackId, packet.ClassName);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.TemplateFromClassId:
|
|
||||||
IIPRequestTemplateFromClassId(packet.CallbackId, packet.ClassId);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.TemplateFromResourceId:
|
|
||||||
IIPRequestTemplateFromResourceId(packet.CallbackId, packet.ResourceId);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.QueryLink:
|
|
||||||
IIPRequestQueryResources(packet.CallbackId, packet.ResourceLink);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.ResourceChildren:
|
|
||||||
IIPRequestResourceChildren(packet.CallbackId, packet.ResourceId);
|
|
||||||
break;
|
|
||||||
case IIPPacketRequest.ResourceParents:
|
|
||||||
IIPRequestResourceParents(packet.CallbackId, packet.ResourceId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.ResourceHistory:
|
|
||||||
IIPRequestInquireResourceHistory(packet.CallbackId, packet.ResourceId, packet.FromDate, packet.ToDate);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.LinkTemplates:
|
|
||||||
IIPRequestLinkTemplates(packet.CallbackId, packet.ResourceLink);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Invoke
|
// Invoke
|
||||||
case IIPPacketRequest.InvokeFunction:
|
case IIPPacketRequest.InvokeFunction:
|
||||||
IIPRequestInvokeFunction(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
IIPRequestInvokeFunction(packet.CallbackId, dt, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//case IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments:
|
|
||||||
// IIPRequestInvokeFunctionNamedArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
//case IIPPacket.IIPPacketAction.GetProperty:
|
|
||||||
// IIPRequestGetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
|
||||||
// break;
|
|
||||||
//case IIPPacket.IIPPacketAction.GetPropertyIfModified:
|
|
||||||
// IIPRequestGetPropertyIfModifiedSince(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.ResourceAge);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.Listen:
|
|
||||||
IIPRequestListen(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.Unlisten:
|
|
||||||
IIPRequestUnlisten(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.SetProperty:
|
case IIPPacketRequest.SetProperty:
|
||||||
IIPRequestSetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
IIPRequestSetProperty(packet.CallbackId, dt, msg);
|
||||||
break;
|
break;
|
||||||
|
case IIPPacketRequest.Subscribe:
|
||||||
// Attribute
|
IIPRequestSubscribe(packet.CallbackId, dt, msg);
|
||||||
case IIPPacketRequest.GetAllAttributes:
|
|
||||||
// @TODO : fix this
|
|
||||||
//IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
|
||||||
break;
|
break;
|
||||||
case IIPPacketRequest.UpdateAllAttributes:
|
case IIPPacketRequest.Unsubscribe:
|
||||||
// @TODO : fix this
|
IIPRequestUnsubscribe(packet.CallbackId, dt, msg);
|
||||||
//IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
|
||||||
break;
|
break;
|
||||||
case IIPPacketRequest.ClearAllAttributes:
|
// Inquire
|
||||||
// @TODO : fix this
|
case IIPPacketRequest.TemplateFromClassName:
|
||||||
//IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
IIPRequestTemplateFromClassName(packet.CallbackId, dt, msg);
|
||||||
break;
|
break;
|
||||||
case IIPPacketRequest.GetAttributes:
|
case IIPPacketRequest.TemplateFromClassId:
|
||||||
// @TODO : fix this
|
IIPRequestTemplateFromClassId(packet.CallbackId, dt, msg);
|
||||||
//IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
|
||||||
break;
|
break;
|
||||||
case IIPPacketRequest.UpdateAttributes:
|
case IIPPacketRequest.TemplateFromResourceId:
|
||||||
// @TODO : fix this
|
IIPRequestTemplateFromResourceId(packet.CallbackId, dt, msg);
|
||||||
//IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
|
||||||
break;
|
break;
|
||||||
case IIPPacketRequest.ClearAttributes:
|
case IIPPacketRequest.Query:
|
||||||
// @TODO : fix this
|
IIPRequestQueryResources(packet.CallbackId, dt, msg);
|
||||||
//IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
|
||||||
break;
|
break;
|
||||||
|
case IIPPacketRequest.LinkTemplates:
|
||||||
case IIPPacketRequest.KeepAlive:
|
IIPRequestLinkTemplates(packet.CallbackId, dt, msg);
|
||||||
IIPRequestKeepAlive(packet.CallbackId, packet.CurrentTime, packet.Interval);
|
|
||||||
break;
|
break;
|
||||||
|
case IIPPacketRequest.Token:
|
||||||
case IIPPacketRequest.ProcedureCall:
|
IIPRequestToken(packet.CallbackId, dt, msg);
|
||||||
IIPRequestProcedureCall(packet.CallbackId, packet.Procedure, (TransmissionType)packet.DataType, msg);
|
|
||||||
break;
|
break;
|
||||||
|
case IIPPacketRequest.GetResourceIdByLink:
|
||||||
case IIPPacketRequest.StaticCall:
|
IIPRequestGetResourceIdByLink(packet.CallbackId, dt, msg);
|
||||||
IIPRequestStaticCall(packet.CallbackId, packet.ClassId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (packet.Command == IIPPacketCommand.Reply)
|
|
||||||
{
|
|
||||||
switch (packet.Action)
|
|
||||||
{
|
|
||||||
// Manage
|
// Manage
|
||||||
case IIPPacketRequest.AttachResource:
|
case IIPPacketRequest.AttachResource:
|
||||||
IIPReply(packet.CallbackId, packet.ClassId, packet.ResourceAge, packet.ResourceLink, packet.DataType, msg);
|
IIPRequestAttachResource(packet.CallbackId, dt, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacketRequest.ReattachResource:
|
case IIPPacketRequest.ReattachResource:
|
||||||
IIPReply(packet.CallbackId, packet.ResourceAge, packet.DataType, msg);
|
IIPRequestReattachResource(packet.CallbackId, dt, msg);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IIPPacketRequest.DetachResource:
|
case IIPPacketRequest.DetachResource:
|
||||||
IIPReply(packet.CallbackId);
|
IIPRequestDetachResource(packet.CallbackId, dt, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacketRequest.CreateResource:
|
case IIPPacketRequest.CreateResource:
|
||||||
IIPReply(packet.CallbackId, packet.ResourceId);
|
IIPRequestCreateResource(packet.CallbackId, dt, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacketRequest.DeleteResource:
|
case IIPPacketRequest.DeleteResource:
|
||||||
case IIPPacketRequest.AddChild:
|
IIPRequestDeleteResource(packet.CallbackId, dt, msg);
|
||||||
case IIPPacketRequest.RemoveChild:
|
|
||||||
case IIPPacketRequest.RenameResource:
|
|
||||||
IIPReply(packet.CallbackId);
|
|
||||||
break;
|
break;
|
||||||
|
case IIPPacketRequest.MoveResource:
|
||||||
// Inquire
|
IIPRequestMoveResource(packet.CallbackId, dt, msg);
|
||||||
|
|
||||||
case IIPPacketRequest.TemplateFromClassName:
|
|
||||||
case IIPPacketRequest.TemplateFromClassId:
|
|
||||||
case IIPPacketRequest.TemplateFromResourceId:
|
|
||||||
|
|
||||||
var content = msg.Clip(packet.DataType.Value.Offset, (uint)packet.DataType.Value.ContentLength);
|
|
||||||
IIPReply(packet.CallbackId, TypeTemplate.Parse(content));
|
|
||||||
break;
|
break;
|
||||||
|
// Static
|
||||||
case IIPPacketRequest.QueryLink:
|
|
||||||
case IIPPacketRequest.ResourceChildren:
|
|
||||||
case IIPPacketRequest.ResourceParents:
|
|
||||||
case IIPPacketRequest.ResourceHistory:
|
|
||||||
case IIPPacketRequest.LinkTemplates:
|
|
||||||
IIPReply(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Invoke
|
|
||||||
case IIPPacketRequest.InvokeFunction:
|
|
||||||
case IIPPacketRequest.StaticCall:
|
|
||||||
case IIPPacketRequest.ProcedureCall:
|
|
||||||
IIPReplyInvoke(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//case IIPPacket.IIPPacketAction.GetProperty:
|
|
||||||
// IIPReply(packet.CallbackId, packet.Content);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
//case IIPPacket.IIPPacketAction.GetPropertyIfModified:
|
|
||||||
// IIPReply(packet.CallbackId, packet.Content);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.Listen:
|
|
||||||
case IIPPacketRequest.Unlisten:
|
|
||||||
case IIPPacketRequest.SetProperty:
|
|
||||||
IIPReply(packet.CallbackId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Attribute
|
|
||||||
case IIPPacketRequest.GetAllAttributes:
|
|
||||||
case IIPPacketRequest.GetAttributes:
|
|
||||||
IIPReply(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.UpdateAllAttributes:
|
|
||||||
case IIPPacketRequest.UpdateAttributes:
|
|
||||||
case IIPPacketRequest.ClearAllAttributes:
|
|
||||||
case IIPPacketRequest.ClearAttributes:
|
|
||||||
IIPReply(packet.CallbackId);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IIPPacketRequest.KeepAlive:
|
case IIPPacketRequest.KeepAlive:
|
||||||
IIPReply(packet.CallbackId, packet.CurrentTime, packet.Jitter);
|
IIPRequestKeepAlive(packet.CallbackId, dt, msg);
|
||||||
|
break;
|
||||||
|
case IIPPacketRequest.ProcedureCall:
|
||||||
|
IIPRequestProcedureCall(packet.CallbackId, dt, msg);
|
||||||
|
break;
|
||||||
|
case IIPPacketRequest.StaticCall:
|
||||||
|
IIPRequestStaticCall(packet.CallbackId, dt, msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (packet.Command == IIPPacketCommand.Report)
|
else if (packet.Method == IIPPacketMethod.Reply)
|
||||||
{
|
{
|
||||||
switch (packet.Report)
|
var dt = packet.DataType.Value;
|
||||||
{
|
|
||||||
case IIPPacketReport.ManagementError:
|
|
||||||
IIPReportError(packet.CallbackId, ErrorType.Management, packet.ErrorCode, null);
|
|
||||||
break;
|
|
||||||
case IIPPacketReport.ExecutionError:
|
|
||||||
IIPReportError(packet.CallbackId, ErrorType.Exception, packet.ErrorCode, packet.ErrorMessage);
|
|
||||||
break;
|
|
||||||
case IIPPacketReport.ProgressReport:
|
|
||||||
IIPReportProgress(packet.CallbackId, ProgressType.Execution, packet.ProgressValue, packet.ProgressMax);
|
|
||||||
break;
|
|
||||||
case IIPPacketReport.ChunkStream:
|
|
||||||
IIPReportChunk(packet.CallbackId, (TransmissionType)packet.DataType, msg);
|
|
||||||
|
|
||||||
|
switch (packet.Reply)
|
||||||
|
{
|
||||||
|
case IIPPacketReply.Completed:
|
||||||
|
IIPReplyCompleted(packet.CallbackId, dt, msg);
|
||||||
break;
|
break;
|
||||||
|
case IIPPacketReply.Propagated:
|
||||||
|
IIPReplyPropagated(packet.CallbackId, dt, msg);
|
||||||
|
break;
|
||||||
|
case IIPPacketReply.PermissionError:
|
||||||
|
IIPReplyError(packet.CallbackId, dt, msg, ErrorType.Management);
|
||||||
|
break;
|
||||||
|
case IIPPacketReply.ExecutionError:
|
||||||
|
IIPReplyError(packet.CallbackId, dt, msg, ErrorType.Exception);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IIPPacketReply.Progress:
|
||||||
|
IIPReplyProgress(packet.CallbackId, dt, msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IIPPacketReply.Chunk:
|
||||||
|
IIPReplyChunk(packet.CallbackId, dt, msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IIPPacketReply.Warning:
|
||||||
|
IIPReplyWarning(packet.Extension, dt, msg);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (packet.Method == IIPPacketMethod.Extension)
|
||||||
|
{
|
||||||
|
IIPExtensionAction(packet.Extension, packet.DataType, msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// check if the reqeust through websockets
|
// check if the request through Websockets
|
||||||
|
|
||||||
if (initialPacket)
|
if (initialPacket)
|
||||||
{
|
{
|
||||||
@@ -755,7 +625,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
HTTPConnection.Upgrade(req, res);
|
HTTPConnection.Upgrade(req, res);
|
||||||
|
|
||||||
|
|
||||||
res.Compose(HTTPComposeOption.AllCalculateLength);
|
res.Compose(HTTPComposeOption.AllCalculateLength);
|
||||||
Send(res.Data);
|
Send(res.Data);
|
||||||
// replace my socket with websockets
|
// replace my socket with websockets
|
||||||
@@ -784,11 +653,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var rt = authPacket.Parse(msg, offset, ends);
|
var rt = authPacket.Parse(msg, offset, ends);
|
||||||
|
|
||||||
|
|
||||||
if (rt <= 0)
|
if (rt <= 0)
|
||||||
{
|
{
|
||||||
data.HoldFor(msg, ends + (uint)(-rt));
|
data.HoldFor(msg, ends + (uint)(-rt));
|
||||||
@@ -810,9 +676,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
|
|
||||||
//if (offset < ends)
|
|
||||||
// processPacket(msg, offset, ends, data, chunkId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessClientAuth(byte[] data)
|
private void ProcessClientAuth(byte[] data)
|
||||||
@@ -831,9 +694,9 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
var dataType = authPacket.DataType.Value;
|
var dataType = authPacket.DataType.Value;
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
var (_, parsed) = Codec.ParseSync(data, dataType.Offset, dataType);
|
||||||
|
|
||||||
var rt = (Map<byte, object>)parsed.Wait();
|
var rt = (Map<byte, object>)parsed;
|
||||||
|
|
||||||
session.RemoteHeaders = rt.Select(x => new KeyValuePair<IIPAuthPacketHeader, object>((IIPAuthPacketHeader)x.Key, x.Value));
|
session.RemoteHeaders = rt.Select(x => new KeyValuePair<IIPAuthPacketHeader, object>((IIPAuthPacketHeader)x.Key, x.Value));
|
||||||
|
|
||||||
@@ -924,7 +787,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
ready = true;
|
ready = true;
|
||||||
Status = ConnectionStatus.Connected;
|
Status = ConnectionStatus.Connected;
|
||||||
|
|
||||||
|
|
||||||
// put it in the warehouse
|
// put it in the warehouse
|
||||||
|
|
||||||
if (this.Instance == null)
|
if (this.Instance == null)
|
||||||
@@ -957,8 +820,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
else if (authPacket.Event == IIPAuthPacketEvent.IAuthPlain)
|
else if (authPacket.Event == IIPAuthPacketEvent.IAuthPlain)
|
||||||
{
|
{
|
||||||
var dataType = authPacket.DataType.Value;
|
var dataType = authPacket.DataType.Value;
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
var (_, parsed) = Codec.ParseSync(data, dataType.Offset, dataType);
|
||||||
var rt = (Map<byte, object>)parsed.Wait();
|
var rt = (Map<byte, object>)parsed;
|
||||||
|
|
||||||
var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value));
|
var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value));
|
||||||
var iAuthRequest = new AuthorizationRequest(headers);
|
var iAuthRequest = new AuthorizationRequest(headers);
|
||||||
@@ -983,7 +846,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
.Done();
|
.Done();
|
||||||
})
|
})
|
||||||
.Timeout(iAuthRequest.Timeout * 1000,
|
.Timeout(iAuthRequest.Timeout * 1000,
|
||||||
() => {
|
() =>
|
||||||
|
{
|
||||||
SendParams()
|
SendParams()
|
||||||
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
|
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
|
||||||
.AddUInt8((byte)ExceptionCode.Timeout)
|
.AddUInt8((byte)ExceptionCode.Timeout)
|
||||||
@@ -996,8 +860,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
else if (authPacket.Event == IIPAuthPacketEvent.IAuthHashed)
|
else if (authPacket.Event == IIPAuthPacketEvent.IAuthHashed)
|
||||||
{
|
{
|
||||||
var dataType = authPacket.DataType.Value;
|
var dataType = authPacket.DataType.Value;
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
var (_, parsed) = Codec.ParseSync(data, dataType.Offset, dataType);
|
||||||
var rt = (Map<byte, object>)parsed.Wait();
|
var rt = (Map<byte, object>)parsed;
|
||||||
|
|
||||||
|
|
||||||
var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value));
|
var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value));
|
||||||
@@ -1033,14 +897,15 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
.Done();
|
.Done();
|
||||||
})
|
})
|
||||||
.Timeout(iAuthRequest.Timeout * 1000,
|
.Timeout(iAuthRequest.Timeout * 1000,
|
||||||
() => {
|
() =>
|
||||||
SendParams()
|
{
|
||||||
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
|
SendParams()
|
||||||
.AddUInt8((byte)ExceptionCode.Timeout)
|
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
|
||||||
.AddUInt16(7)
|
.AddUInt8((byte)ExceptionCode.Timeout)
|
||||||
.AddString("Timeout")
|
.AddUInt16(7)
|
||||||
.Done();
|
.AddString("Timeout")
|
||||||
});
|
.Done();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (authPacket.Event == IIPAuthPacketEvent.IAuthEncrypted)
|
else if (authPacket.Event == IIPAuthPacketEvent.IAuthEncrypted)
|
||||||
@@ -1058,10 +923,9 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
var dataType = authPacket.DataType.Value;
|
var dataType = authPacket.DataType.Value;
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
var (_, parsed) = Codec.ParseSync(data, dataType.Offset, dataType);
|
||||||
|
|
||||||
var rt = (Map<byte, object>)parsed.Wait();
|
|
||||||
|
|
||||||
|
var rt = (Map<byte, object>)parsed;
|
||||||
|
|
||||||
session.RemoteHeaders = rt.Select(x => new KeyValuePair<IIPAuthPacketHeader, object>((IIPAuthPacketHeader)x.Key, x.Value));
|
session.RemoteHeaders = rt.Select(x => new KeyValuePair<IIPAuthPacketHeader, object>((IIPAuthPacketHeader)x.Key, x.Value));
|
||||||
|
|
||||||
@@ -1250,7 +1114,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
reply = Server.Membership.GetToken((ulong)session.RemoteHeaders[IIPAuthPacketHeader.TokenIndex],
|
reply = Server.Membership.GetToken((ulong)session.RemoteHeaders[IIPAuthPacketHeader.TokenIndex],
|
||||||
(string)session.RemoteHeaders[IIPAuthPacketHeader.Domain]);
|
(string)session.RemoteHeaders[IIPAuthPacketHeader.Domain]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Authentication method unsupported.");
|
throw new NotImplementedException("Authentication method unsupported.");
|
||||||
}
|
}
|
||||||
@@ -1317,9 +1181,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
var reference = authPacket.Reference;
|
var reference = authPacket.Reference;
|
||||||
var dataType = authPacket.DataType.Value;
|
var dataType = authPacket.DataType.Value;
|
||||||
|
|
||||||
var (_, parsed) = Codec.Parse(data, dataType.Offset, this, null, dataType);
|
var (_, value) = Codec.ParseSync(data, dataType.Offset, dataType);
|
||||||
|
|
||||||
var value = parsed.Wait();
|
|
||||||
|
|
||||||
Server.Membership.AuthorizePlain(session, reference, value)
|
Server.Membership.AuthorizePlain(session, reference, value)
|
||||||
.Then(x => ProcessAuthorization(x));
|
.Then(x => ProcessAuthorization(x));
|
||||||
@@ -1386,7 +1248,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
session.Id = new byte[32];
|
session.Id = new byte[32];
|
||||||
r.NextBytes(session.Id);
|
r.NextBytes(session.Id);
|
||||||
var accountId = session.AuthorizedAccount.ToBytes();
|
var accountId = session.AuthorizedAccount.ToBytes();
|
||||||
|
|
||||||
SendParams()
|
SendParams()
|
||||||
.AddUInt8((byte)IIPAuthPacketEvent.IndicationEstablished)
|
.AddUInt8((byte)IIPAuthPacketEvent.IndicationEstablished)
|
||||||
.AddUInt8((byte)session.Id.Length)
|
.AddUInt8((byte)session.Id.Length)
|
||||||
@@ -1687,33 +1549,22 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var ar = await SendRequest(IIPPacketRequest.QueryLink)
|
var id = (uint)await SendRequest(IIPPacketRequest.GetResourceIdByLink, link);
|
||||||
.AddUInt16((ushort)link.Length)
|
|
||||||
.AddUInt8Array(link)
|
|
||||||
.Done();
|
|
||||||
|
|
||||||
var dataType = (TransmissionType)ar[0];
|
|
||||||
var data = ar[1] as byte[];
|
|
||||||
|
|
||||||
if (dataType.Identifier == TransmissionTypeIdentifier.ResourceList)
|
// remove from suspended.
|
||||||
{
|
suspendedResources.Remove(r.DistributedResourceInstanceId);
|
||||||
|
|
||||||
// remove from suspended.
|
// id changed ?
|
||||||
suspendedResources.Remove(r.DistributedResourceInstanceId);
|
if (id != r.DistributedResourceInstanceId)
|
||||||
|
r.DistributedResourceInstanceId = id;
|
||||||
|
|
||||||
// parse them as int
|
neededResources[id] = r;
|
||||||
var id = data.GetUInt32(8, Endian.Little);
|
|
||||||
|
|
||||||
// id changed ?
|
await Fetch(id, null);
|
||||||
if (id != r.DistributedResourceInstanceId)
|
|
||||||
r.DistributedResourceInstanceId = id;
|
|
||||||
|
|
||||||
neededResources[id] = r;
|
Global.Log("DistributedConnection", LogType.Debug, "Restored " + id);
|
||||||
|
|
||||||
await Fetch(id, null);
|
|
||||||
|
|
||||||
Global.Log("DistributedConnection", LogType.Debug, "Restored " + id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (AsyncException ex)
|
catch (AsyncException ex)
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
|||||||
|
|
||||||
string link;
|
string link;
|
||||||
//ulong age;
|
//ulong age;
|
||||||
//ulong[] ages;
|
|
||||||
protected object[] properties;
|
protected object[] properties;
|
||||||
internal List<DistributedResource> parents = new List<DistributedResource>();
|
internal List<DistributedResource> parents = new List<DistributedResource>();
|
||||||
internal List<DistributedResource> children = new List<DistributedResource>();
|
internal List<DistributedResource> children = new List<DistributedResource>();
|
||||||
@@ -174,16 +174,31 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal PropertyValue[] _Serialize()
|
internal PropertyValue[] _Serialize()
|
||||||
{
|
{
|
||||||
|
|
||||||
var props = new PropertyValue[properties.Length];
|
var props = new PropertyValue[properties.Length];
|
||||||
|
|
||||||
|
|
||||||
for (byte i = 0; i < properties.Length; i++)
|
for (byte i = 0; i < properties.Length; i++)
|
||||||
props[i] = new PropertyValue(properties[i], Instance.GetAge(i), Instance.GetModificationDate(i));
|
props[i] = new PropertyValue(properties[i],
|
||||||
|
Instance.GetAge(i),
|
||||||
|
Instance.GetModificationDate(i));
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal Map<byte, PropertyValue> _SerializeAfter(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
internal bool _Attach(PropertyValue[] properties)
|
internal bool _Attach(PropertyValue[] properties)
|
||||||
{
|
{
|
||||||
if (attached)
|
if (attached)
|
||||||
@@ -568,7 +583,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
|||||||
|
|
||||||
protected virtual void EmitPropertyChanged(string name)
|
protected virtual void EmitPropertyChanged(string name)
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
~DistributedResource()
|
~DistributedResource()
|
||||||
|
@@ -6,13 +6,14 @@ namespace Esiur.Net.Packets
|
|||||||
{
|
{
|
||||||
public enum IIPPacketNotification : byte
|
public enum IIPPacketNotification : byte
|
||||||
{
|
{
|
||||||
// Event Manage
|
// Notification Invoke
|
||||||
ResourceDestroyed = 0,
|
PropertyModified = 0x0,
|
||||||
ResourceReassigned,
|
EventOccurred = 0x1,
|
||||||
ResourceMoved,
|
|
||||||
SystemFailure,
|
// Notification Manage
|
||||||
// Event Invoke
|
ResourceDestroyed = 0x8,
|
||||||
PropertyModified = 0x8,
|
ResourceReassigned = 0x9,
|
||||||
EventOccurred,
|
ResourceMoved = 0xA,
|
||||||
|
SystemFailure = 0xB,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,8 +11,8 @@ namespace Esiur.Net.Packets
|
|||||||
Propagated = 0x1,
|
Propagated = 0x1,
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
Permission = 0x81,
|
PermissionError = 0x81,
|
||||||
Execution = 0x82,
|
ExecutionError = 0x82,
|
||||||
|
|
||||||
// Partial
|
// Partial
|
||||||
Progress = 0x10,
|
Progress = 0x10,
|
||||||
|
@@ -6,29 +6,30 @@ namespace Esiur.Net.Packets
|
|||||||
{
|
{
|
||||||
public enum IIPPacketRequest : byte
|
public enum IIPPacketRequest : byte
|
||||||
{
|
{
|
||||||
// Request Manage
|
// Request Invoke
|
||||||
AttachResource = 0x0,
|
InvokeFunction = 0x0,
|
||||||
ReattachResource = 0x1,
|
SetProperty = 0x1,
|
||||||
DetachResource = 0x2,
|
Subscribe = 0x2,
|
||||||
CreateResource = 0x3,
|
Unsubscribe = 0x3,
|
||||||
DeleteResource = 0x4,
|
|
||||||
MoveResource = 0x5,
|
|
||||||
|
|
||||||
// Request Inquire
|
// Request Inquire
|
||||||
TemplateFromClassName = 0x8,
|
TemplateFromClassName = 0x8,
|
||||||
TemplateFromClassId = 0x9,
|
TemplateFromClassId = 0x9,
|
||||||
TemplateFromResourceId = 0xA,
|
TemplateFromResourceId = 0xA,
|
||||||
QueryLink = 0xB,
|
Query = 0xB,
|
||||||
LinkTemplates = 0xC,
|
LinkTemplates = 0xC,
|
||||||
Token = 0xD,
|
Token = 0xD,
|
||||||
|
GetResourceIdByLink = 0xE,
|
||||||
|
|
||||||
// Request Invoke
|
// Request Manage
|
||||||
InvokeFunction = 0x10,
|
AttachResource = 0x10,
|
||||||
Subscribe = 0x11,
|
ReattachResource = 0x11,
|
||||||
Unsubscribe = 0x12,
|
DetachResource = 0x12,
|
||||||
SetProperty = 0x13,
|
CreateResource = 0x13,
|
||||||
|
DeleteResource = 0x14,
|
||||||
|
MoveResource = 0x15,
|
||||||
|
|
||||||
// Static calling
|
// Request Static
|
||||||
KeepAlive = 0x18,
|
KeepAlive = 0x18,
|
||||||
ProcedureCall = 0x19,
|
ProcedureCall = 0x19,
|
||||||
StaticCall = 0x1A
|
StaticCall = 0x1A
|
||||||
|
@@ -48,6 +48,7 @@ public class Instance
|
|||||||
List<ulong?> ages = new();
|
List<ulong?> ages = new();
|
||||||
List<DateTime?> modificationDates = new();
|
List<DateTime?> modificationDates = new();
|
||||||
private ulong instanceAge;
|
private ulong instanceAge;
|
||||||
|
private byte hops;
|
||||||
private DateTime instanceModificationDate;
|
private DateTime instanceModificationDate;
|
||||||
|
|
||||||
uint id;
|
uint id;
|
||||||
@@ -389,6 +390,16 @@ public class Instance
|
|||||||
internal set { instanceAge = value; }
|
internal set { instanceAge = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of nodes to reach the original resource.
|
||||||
|
/// </summary>
|
||||||
|
public ulong Hops
|
||||||
|
{
|
||||||
|
get { return hops; }
|
||||||
|
internal set { hops = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Last modification date.
|
/// Last modification date.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -443,7 +454,7 @@ public class Instance
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public PropertyValue[] Serialize()
|
public PropertyValue[] Serialize()
|
||||||
{
|
{
|
||||||
List<PropertyValue> props = new List<PropertyValue>();
|
var props = new List<PropertyValue>();
|
||||||
|
|
||||||
foreach (var pt in template.Properties)
|
foreach (var pt in template.Properties)
|
||||||
{
|
{
|
||||||
@@ -459,6 +470,33 @@ public class Instance
|
|||||||
return props.ToArray();
|
return props.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Export all properties with ResourceProperty attributed as bytes array after a specific age.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Map<byte, PropertyValue> SerializeAfter(ulong age = 0)
|
||||||
|
{
|
||||||
|
var props = new Map<byte, PropertyValue>();
|
||||||
|
|
||||||
|
foreach (var pt in template.Properties)
|
||||||
|
{
|
||||||
|
IResource res;
|
||||||
|
if (resource.TryGetTarget(out res))
|
||||||
|
{
|
||||||
|
if (res.Instance.GetAge(pt.Index) > age)
|
||||||
|
{
|
||||||
|
var rt = pt.PropertyInfo.GetValue(res, null);
|
||||||
|
props.Add(pt.Index,
|
||||||
|
new PropertyValue(rt,
|
||||||
|
ages[pt.Index],
|
||||||
|
modificationDates[pt.Index]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public bool Deserialize(byte[] data, uint offset, uint length)
|
public bool Deserialize(byte[] data, uint offset, uint length)
|
||||||
{
|
{
|
||||||
@@ -588,7 +626,7 @@ public class Instance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// internal void EmitResourceEvent(string name, string[] users, DistributedConnection[] connections, object[] args)
|
// internal void EmitResourceEvent(string name, string[] users, DistributedConnection[] connections, object[] args)
|
||||||
|
|
||||||
|
@@ -652,75 +652,51 @@ public static class Warehouse
|
|||||||
|
|
||||||
type = ResourceProxy.GetProxy(type);
|
type = ResourceProxy.GetProxy(type);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (arguments != null)
|
|
||||||
{
|
|
||||||
var constructors = type.GetConstructors(System.Reflection.BindingFlags.Public);
|
|
||||||
|
|
||||||
foreach(var constructor in constructors)
|
|
||||||
{
|
|
||||||
var pi = constructor.GetParameters();
|
|
||||||
if (pi.Length == constructor.le)
|
|
||||||
}
|
|
||||||
|
|
||||||
// cast arguments
|
|
||||||
ParameterInfo[] pi = fi.GetParameters();
|
|
||||||
|
|
||||||
object[] args = new object[pi.Length];
|
|
||||||
|
|
||||||
for (var i = 0; i < pi.Length; i++)
|
|
||||||
{
|
|
||||||
if (pi[i].ParameterType == typeof(DistributedConnection))
|
|
||||||
{
|
|
||||||
args[i] = this;
|
|
||||||
}
|
|
||||||
else if (namedArgs.ContainsKey(pi[i].Name))
|
|
||||||
{
|
|
||||||
args[i] = DC.CastConvert(namedArgs[pi[i].Name], pi[i].ParameterType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructors[0].
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
var res = Activator.CreateInstance(type) as IResource;
|
var res = Activator.CreateInstance(type) as IResource;
|
||||||
|
|
||||||
|
|
||||||
if (properties != null)
|
if (properties != null)
|
||||||
{
|
{
|
||||||
var ps = Map<string, object>.FromObject(properties);
|
if (properties is Map<byte, object> map)
|
||||||
|
|
||||||
foreach (var p in ps)
|
|
||||||
{
|
{
|
||||||
|
var template = GetTemplateByType(type);
|
||||||
|
foreach(var kvp in map)
|
||||||
|
template.GetPropertyTemplateByIndex(kvp.Key).PropertyInfo.SetValue(res, kvp.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var ps = Map<string, object>.FromObject(properties);
|
||||||
|
|
||||||
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
foreach (var p in ps)
|
||||||
if (pi != null)
|
|
||||||
{
|
{
|
||||||
if (pi.CanWrite)
|
var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||||
|
if (pi != null)
|
||||||
{
|
{
|
||||||
try
|
if (pi.CanWrite)
|
||||||
{
|
{
|
||||||
pi.SetValue(res, p.Value);
|
try
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
pi.SetValue(res, p.Value);
|
||||||
{
|
}
|
||||||
Global.Log(ex);
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Global.Log(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
var fi = type.GetField(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
|
||||||
if (fi != null)
|
|
||||||
{
|
{
|
||||||
try
|
var fi = type.GetField(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||||
|
if (fi != null)
|
||||||
{
|
{
|
||||||
fi.SetValue(res, p.Value);
|
try
|
||||||
}
|
{
|
||||||
catch (Exception ex)
|
fi.SetValue(res, p.Value);
|
||||||
{
|
}
|
||||||
Global.Log(ex);
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Global.Log(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -729,9 +705,6 @@ public static class Warehouse
|
|||||||
|
|
||||||
if (store != null || parent != null || res is IStore)
|
if (store != null || parent != null || res is IStore)
|
||||||
{
|
{
|
||||||
//if (!await Put(name, res, store, parent, null, 0, manager, attributes))
|
|
||||||
// return null;
|
|
||||||
|
|
||||||
await Put(name, res, store, parent, null, 0, manager, attributes);
|
await Put(name, res, store, parent, null, 0, manager, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user