diff --git a/Esiur/Core/AsyncReplyGeneric.cs b/Esiur/Core/AsyncReplyGeneric.cs
index 7bd9070..fc6a311 100644
--- a/Esiur/Core/AsyncReplyGeneric.cs
+++ b/Esiur/Core/AsyncReplyGeneric.cs
@@ -57,7 +57,7 @@ namespace Esiur.Core
//public Timer timeout;// = new Timer()
protected bool resultReady = false;
AsyncException exception;
- StackTrace trace;
+ // StackTrace trace;
AutoResetEvent mutex = new AutoResetEvent(false);
public static int MaxId;
@@ -103,7 +103,7 @@ namespace Esiur.Core
//{
lock (asyncLock)
{
- trace = new StackTrace();
+ // trace = new StackTrace();
if (resultReady)
{
diff --git a/Esiur/Data/Codec.cs b/Esiur/Data/Codec.cs
index 2e63327..49d825c 100644
--- a/Esiur/Data/Codec.cs
+++ b/Esiur/Data/Codec.cs
@@ -546,7 +546,7 @@ namespace Esiur.Data
/// Resource
public static AsyncReply ParseResource(byte[] data, uint offset)
{
- return Warehouse.Get(data.GetUInt32(offset));
+ return Warehouse.GetById(data.GetUInt32(offset));
}
///
@@ -703,7 +703,7 @@ namespace Esiur.Data
previous = new AsyncReply(null);
else if (result == ResourceComparisonResult.Local)
{
- previous = Warehouse.Get(data.GetUInt32(offset));
+ previous = Warehouse.GetById(data.GetUInt32(offset));
offset += 4;
}
else if (result == ResourceComparisonResult.Distributed)
@@ -731,7 +731,7 @@ namespace Esiur.Data
}
else if (result == ResourceComparisonResult.Local)
{
- current = Warehouse.Get(data.GetUInt32(offset));
+ current = Warehouse.GetById(data.GetUInt32(offset));
offset += 4;
}
else if (result == ResourceComparisonResult.Distributed)
diff --git a/Esiur/Data/StringKeyList.cs b/Esiur/Data/StringKeyList.cs
index fd48a99..9e76af8 100644
--- a/Esiur/Data/StringKeyList.cs
+++ b/Esiur/Data/StringKeyList.cs
@@ -89,7 +89,7 @@ namespace Esiur.Data
{
var key = Key.ToLower();
- var toRemove = m_Variables.Where(x => x.Key.ToLower() == key);
+ var toRemove = m_Variables.Where(x => x.Key.ToLower() == key).ToArray();
foreach (var item in toRemove)
m_Variables.Remove(item);
diff --git a/Esiur/Esiur.csproj b/Esiur/Esiur.csproj
index 92e44f1..afe1279 100644
--- a/Esiur/Esiur.csproj
+++ b/Esiur/Esiur.csproj
@@ -7,7 +7,7 @@
https://github.com/esiur/esiur-dotnet/blob/master/LICENSE
http://www.esiur.com
true
- 1.4.0
+ 1.4.1
https://github.com/esiur/esiur-dotnet
Ahmed Kh. Zamil
1.3.1.0
diff --git a/Esiur/Net/HTTP/HTTPConnection.cs b/Esiur/Net/HTTP/HTTPConnection.cs
index 77375f8..9770923 100644
--- a/Esiur/Net/HTTP/HTTPConnection.cs
+++ b/Esiur/Net/HTTP/HTTPConnection.cs
@@ -39,59 +39,25 @@ using System.Security.Cryptography;
namespace Esiur.Net.HTTP
{
- //[Serializable]
public class HTTPConnection : NetworkConnection
{
- /*
- public enum SendOptions : int
- {
- AllCalculateLength,
- AllDontCalculateLength,
- SpecifiedHeadersOnly,
- DataOnly
- }
- */
-
- public HTTPConnection()
- {
- Response = new HTTPResponsePacket();
- variables = new KeyList();
- }
public void SetParent(HTTPServer Parent)
{
Server = Parent;
}
- //public bool HeadersSent;
-
-
- private KeyList variables;
- private bool Busy = false;
- private DateTime RequestTime = DateTime.MinValue;
-
- public bool WSMode;
+ public bool WSMode { get; internal set; }
private HTTPServer Server;
- public WebsocketPacket WSRequest;
- public HTTPRequestPacket Request;
- public HTTPResponsePacket Response;
+ public WebsocketPacket WSRequest { get; set; }
+ public HTTPRequestPacket Request { get; set; }
+ public HTTPResponsePacket Response { get; } = new HTTPResponsePacket();
HTTPSession session;
- public KeyList Variables
- {
- get
- {
- return variables;
- }
- }
+ public KeyList Variables { get; } = new KeyList();
- public bool IsBusy()
- {
- return Busy;
- }
-
internal long Parse(byte[] data)
{
@@ -115,7 +81,7 @@ namespace Esiur.Net.HTTP
}
else
{
- HTTPRequestPacket rp = new HTTPRequestPacket();
+ var rp = new HTTPRequestPacket();
var pSize = rp.Parse(data, 0, (uint)data.Length);
if (pSize > 0)
{
@@ -130,31 +96,6 @@ namespace Esiur.Net.HTTP
}
- /*
- public override void Send(string Response)
- {
- Send(Response, SendOptions.AllCalculateLength);
- }
-
- public void Send(string Message, SendOptions Options)
- {
-
- if (Response.Handled)
- return;
-
- if (Response != null)
- Send(Encoding.Default.GetBytes(Response), Options);
- else
- Send((byte[])null, Options);
- }
-
- public void Send(MemoryStream ms)
- {
- Send(ms.ToArray(), SendOptions.AllCalculateLength);
- }
-
- */
-
public void Flush()
{
// close the connection
@@ -171,21 +112,18 @@ namespace Esiur.Net.HTTP
// Compute the SHA1 hash
SHA1 sha = SHA1.Create();
byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));
- Response.Headers["Upgrade"] = Request.Headers["Upgrade"];
+ Response.Headers["Upgrade"] = Request.Headers["Upgrade"];
Response.Headers["Connection"] = Request.Headers["Connection"];// "Upgrade";
Response.Headers["Sec-WebSocket-Accept"] = Convert.ToBase64String(sha1Hash);
if (Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
Response.Headers["Sec-WebSocket-Protocol"] = Request.Headers["Sec-WebSocket-Protocol"];
- //Response.Headers["Sec-WebSocket-Protocol"] = Request.Headers["Sec-WebSocket-Protocol"];
- //Response.Headers["Origin"] = Request.Headers["Origin"];
Response.Number = HTTPResponsePacket.ResponseCode.HTTP_SWITCHING;
Response.Text = "Switching Protocols";
WSMode = true;
- //Send((byte[])null, SendOptions.AllDontCalculateLength);
Send();
return true;
@@ -208,6 +146,12 @@ namespace Esiur.Net.HTTP
Send();
}
+ public override void Send(byte[] msg, int offset, int length)
+ {
+ Response.Message = DC.Clip(msg, (uint)offset, (uint)length);
+ Send();
+ }
+
public override void Send(byte[] message)
{
Response.Message = message;
@@ -219,7 +163,6 @@ namespace Esiur.Net.HTTP
if (Response.Handled)
return;
- Busy = true;
try
{
@@ -235,17 +178,17 @@ namespace Esiur.Net.HTTP
{
try
{
- Close();// Server.CloseClient(Connection);
+ Close();
}
finally { }
}
finally
{
- Busy = false;
+
}
}
-
+
public void CreateNewSession()
{
if (session == null)
@@ -272,7 +215,7 @@ namespace Esiur.Net.HTTP
&& Request.Headers.ContainsKey("Sec-WebSocket-Version")
&& Request.Headers["Sec-WebSocket-Version"] == "13"
&& Request.Headers.ContainsKey("Sec-WebSocket-Key"))
- //&& Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
+ //&& Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
{
return true;
}
@@ -282,11 +225,14 @@ namespace Esiur.Net.HTTP
}
}
+ bool bb;
+
public void SendFile(string filename)
{
if (Response.Handled == true)
return;
+
try
{
@@ -302,22 +248,22 @@ namespace Esiur.Net.HTTP
if (!File.Exists(filename))
{
Response.Number = HTTPResponsePacket.ResponseCode.HTTP_NOTFOUND;
- Send("File Not Found");//, SendOptions.AllCalculateLength);
+ Send("File Not Found");
return;
}
- Busy = true;
- System.DateTime FWD = File.GetLastWriteTime(filename);
- if (Request.Headers.ContainsKey("if-modified-since"))// != DateTime.Parse("12:00:00 AM"))
+ var fileEditTime = File.GetLastWriteTime(filename).ToUniversalTime();
+ if (Request.Headers.ContainsKey("if-modified-since"))
{
try
{
- DateTime IMS = DateTime.Parse(Request.Headers["if-modified-since"]);
- if (FWD <= IMS)
+ var ims = DateTime.Parse(Request.Headers["if-modified-since"]);
+ if (Math.Abs((fileEditTime - ims).TotalSeconds) < 0)
{
Response.Number = HTTPResponsePacket.ResponseCode.HTTP_NOTMODIFIED;
Response.Text = "Not Modified";
+ Send((byte[])null);
}
}
catch
@@ -327,38 +273,42 @@ namespace Esiur.Net.HTTP
}
- if (Response.Number == HTTPResponsePacket.ResponseCode.HTTP_NOTMODIFIED)
+
+ Response.Number = HTTPResponsePacket.ResponseCode.HTTP_OK;
+ // Fri, 30 Oct 2007 14:19:41 GMT
+ Response.Headers["Last-Modified"] = fileEditTime.ToString("ddd, dd MMM yyyy HH:mm:ss");
+ FileInfo fi = new FileInfo(filename);
+ Response.Headers["Content-Length"] = fi.Length.ToString();
+ Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly);
+
+ //var fd = File.ReadAllBytes(filename);
+
+ //base.Send(fd);
+
+
+ using (var fs = new FileStream(filename, FileMode.Open))
{
- Send((byte[])null);
- }
- else
- {
- // Fri, 30 Oct 2007 14:19:41 GMT
- Response.Headers["Last-Modified"] = FWD.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss");
- FileInfo fi = new FileInfo(filename);
- Response.Headers["Content-Length"] = fi.Length.ToString();
- Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly);
- using (var fs = new FileStream(filename, FileMode.Open))
+
+ var buffer = new byte[5000];
+
+
+ while (true)
{
- var buffer = new byte[5000];
- var offset = 0;
- while (offset < fs.Length)
- {
- var n = fs.Read(buffer, offset, buffer.Length);
- offset += n;
- base.Send(buffer);
- }
+ var n = fs.Read(buffer, 0, 5000);
+
+ if (n <= 0)
+ break;
+
+
+ base.Send(buffer, 0, n);
+
}
}
+
- Busy = false;
-
- return;
}
catch
{
- Busy = false;
-
try
{
Close();
diff --git a/Esiur/Net/HTTP/HTTPServer.cs b/Esiur/Net/HTTP/HTTPServer.cs
index 5b6299a..8907193 100644
--- a/Esiur/Net/HTTP/HTTPServer.cs
+++ b/Esiur/Net/HTTP/HTTPServer.cs
@@ -192,17 +192,9 @@ namespace Esiur.Net.HTTP
protected override void DataReceived(HTTPConnection sender, NetworkBuffer data)
{
- //Console.WriteLine(Data);
- // Initialize a new session
- //HTTPConnection HTTP = (HTTPConnection)sender.ExtraObject;
-
- //string Data = System.Text.Encoding.Default.GetString(ReceivedData);
-
+
byte[] msg = data.Read();
-
-
-
-
+
var BL = sender.Parse(msg);
if (BL == 0)
@@ -265,7 +257,8 @@ namespace Esiur.Net.HTTP
try
{
foreach (var resource in filters)
- resource.Execute(sender);
+ if (resource.Execute(sender))
+ return;
sender.Send("Bad Request");
diff --git a/Esiur/Net/IIP/DistributedConnection.cs b/Esiur/Net/IIP/DistributedConnection.cs
index 33b6627..cec7838 100644
--- a/Esiur/Net/IIP/DistributedConnection.cs
+++ b/Esiur/Net/IIP/DistributedConnection.cs
@@ -62,6 +62,9 @@ namespace Esiur.Net.IIP
Session session;
+
+ List attachedResources = new List();
+
AsyncReply openReply;
byte[] localPassword;
@@ -304,7 +307,7 @@ namespace Esiur.Net.IIP
private uint processPacket(byte[] msg, uint offset, uint ends, NetworkBuffer data, int chunkId)
{
- var packet = new IIPPacket();
+ //var packet = new IIPPacket();
@@ -771,14 +774,17 @@ namespace Esiur.Net.IIP
var chunkId = (new Random()).Next(1000, 1000000);
-
+ var list = new List();// double, IIPPacketCommand>();
+
+ this.Socket.Hold();
while (offset < ends)
{
- offset = processPacket(msg, offset, ends, data, chunkId);
- }
+ offset = processPacket(msg, offset, ends, data, chunkId);
+ }
- }
+ this.Socket.Unhold();
+ }
///
/// Resource interface
diff --git a/Esiur/Net/IIP/DistributedConnectionProtocol.cs b/Esiur/Net/IIP/DistributedConnectionProtocol.cs
index 758ca0e..9d3adc0 100644
--- a/Esiur/Net/IIP/DistributedConnectionProtocol.cs
+++ b/Esiur/Net/IIP/DistributedConnectionProtocol.cs
@@ -433,7 +433,7 @@ namespace Esiur.Net.IIP
void IIPRequestAttachResource(uint callback, uint resourceId)
{
- Warehouse.Get(resourceId).Then((res) =>
+ Warehouse.GetById(resourceId).Then((res) =>
{
if (res != null)
{
@@ -461,6 +461,9 @@ namespace Esiur.Net.IIP
//r.Instance.Children.OnRemoved += Children_OnRemoved;
r.Instance.Attributes.OnModified += Attributes_OnModified;
+ // add it to attached resources so GC won't remove it from memory
+ attachedResources.Add(r);
+
var link = DC.ToBytes(r.Instance.Link);
if (r is DistributedResource)
@@ -550,7 +553,7 @@ namespace Esiur.Net.IIP
void IIPRequestReattachResource(uint callback, uint resourceId, ulong resourceAge)
{
- Warehouse.Get(resourceId).Then((res) =>
+ Warehouse.GetById(resourceId).Then((res) =>
{
if (res != null)
{
@@ -587,7 +590,7 @@ namespace Esiur.Net.IIP
void IIPRequestDetachResource(uint callback, uint resourceId)
{
- Warehouse.Get(resourceId).Then((res) =>
+ Warehouse.GetById(resourceId).Then((res) =>
{
if (res != null)
{
@@ -595,6 +598,10 @@ namespace Esiur.Net.IIP
r.Instance.ResourceEventOccurred -= Instance_EventOccurred;
r.Instance.ResourceModified -= Instance_PropertyModified;
r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed;
+
+ // remove from attached resources
+ attachedResources.Remove(res);
+
// reply ok
SendReply(IIPPacket.IIPPacketAction.DetachResource, callback).Done();
}
@@ -609,7 +616,7 @@ namespace Esiur.Net.IIP
void IIPRequestCreateResource(uint callback, uint storeId, uint parentId, byte[] content)
{
- Warehouse.Get(storeId).Then(store =>
+ Warehouse.GetById(storeId).Then(store =>
{
if (store == null)
{
@@ -630,7 +637,7 @@ namespace Esiur.Net.IIP
return;
}
- Warehouse.Get(parentId).Then(parent =>
+ Warehouse.GetById(parentId).Then(parent =>
{
// check security
@@ -733,7 +740,7 @@ namespace Esiur.Net.IIP
void IIPRequestDeleteResource(uint callback, uint resourceId)
{
- Warehouse.Get(resourceId).Then(r =>
+ Warehouse.GetById(resourceId).Then(r =>
{
if (r == null)
{
@@ -757,7 +764,7 @@ namespace Esiur.Net.IIP
void IIPRequestGetAttributes(uint callback, uint resourceId, byte[] attributes, bool all = false)
{
- Warehouse.Get(resourceId).Then(r =>
+ Warehouse.GetById(resourceId).Then(r =>
{
if (r == null)
{
@@ -791,7 +798,7 @@ namespace Esiur.Net.IIP
void IIPRequestAddChild(uint callback, uint parentId, uint childId)
{
- Warehouse.Get(parentId).Then(parent =>
+ Warehouse.GetById(parentId).Then(parent =>
{
if (parent == null)
{
@@ -799,7 +806,7 @@ namespace Esiur.Net.IIP
return;
}
- Warehouse.Get(childId).Then(child =>
+ Warehouse.GetById(childId).Then(child =>
{
if (child == null)
{
@@ -830,7 +837,7 @@ namespace Esiur.Net.IIP
void IIPRequestRemoveChild(uint callback, uint parentId, uint childId)
{
- Warehouse.Get(parentId).Then(parent =>
+ Warehouse.GetById(parentId).Then(parent =>
{
if (parent == null)
{
@@ -838,7 +845,7 @@ namespace Esiur.Net.IIP
return;
}
- Warehouse.Get(childId).Then(child =>
+ Warehouse.GetById(childId).Then(child =>
{
if (child == null)
{
@@ -869,7 +876,7 @@ namespace Esiur.Net.IIP
void IIPRequestRenameResource(uint callback, uint resourceId, byte[] name)
{
- Warehouse.Get(resourceId).Then(resource =>
+ Warehouse.GetById(resourceId).Then(resource =>
{
if (resource == null)
{
@@ -891,7 +898,7 @@ namespace Esiur.Net.IIP
void IIPRequestResourceChildren(uint callback, uint resourceId)
{
- Warehouse.Get(resourceId).Then(resource =>
+ Warehouse.GetById(resourceId).Then(resource =>
{
if (resource == null)
{
@@ -913,7 +920,7 @@ namespace Esiur.Net.IIP
void IIPRequestResourceParents(uint callback, uint resourceId)
{
- Warehouse.Get(resourceId).Then(resource =>
+ Warehouse.GetById(resourceId).Then(resource =>
{
if (resource == null)
{
@@ -934,7 +941,7 @@ namespace Esiur.Net.IIP
void IIPRequestClearAttributes(uint callback, uint resourceId, byte[] attributes, bool all = false)
{
- Warehouse.Get(resourceId).Then(r =>
+ Warehouse.GetById(resourceId).Then(r =>
{
if (r == null)
{
@@ -963,7 +970,7 @@ namespace Esiur.Net.IIP
void IIPRequestUpdateAttributes(uint callback, uint resourceId, byte[] attributes, bool clearAttributes = false)
{
- Warehouse.Get(resourceId).Then(r =>
+ Warehouse.GetById(resourceId).Then(r =>
{
if (r == null)
{
@@ -1028,7 +1035,7 @@ namespace Esiur.Net.IIP
void IIPRequestTemplateFromResourceId(uint callback, uint resourceId)
{
- Warehouse.Get(resourceId).Then((r) =>
+ Warehouse.GetById(resourceId).Then((r) =>
{
if (r != null)
SendReply(IIPPacket.IIPPacketAction.TemplateFromResourceId, callback)
@@ -1078,7 +1085,7 @@ namespace Esiur.Net.IIP
{
//Console.WriteLine("IIPRequestInvokeFunction " + callback + " " + resourceId + " " + index);
- Warehouse.Get(resourceId).Then((r) =>
+ Warehouse.GetById(resourceId).Then((r) =>
{
if (r != null)
{
@@ -1235,7 +1242,7 @@ namespace Esiur.Net.IIP
void IIPRequestInvokeFunctionNamedArguments(uint callback, uint resourceId, byte index, byte[] content)
{
- Warehouse.Get(resourceId).Then((r) =>
+ Warehouse.GetById(resourceId).Then((r) =>
{
if (r != null)
{
@@ -1382,7 +1389,7 @@ namespace Esiur.Net.IIP
void IIPRequestGetProperty(uint callback, uint resourceId, byte index)
{
- Warehouse.Get(resourceId).Then((r) =>
+ Warehouse.GetById(resourceId).Then((r) =>
{
if (r != null)
{
@@ -1429,7 +1436,7 @@ namespace Esiur.Net.IIP
void IIPRequestInquireResourceHistory(uint callback, uint resourceId, DateTime fromDate, DateTime toDate)
{
- Warehouse.Get(resourceId).Then((r) =>
+ Warehouse.GetById(resourceId).Then((r) =>
{
if (r != null)
{
@@ -1465,7 +1472,7 @@ namespace Esiur.Net.IIP
void IIPRequestGetPropertyIfModifiedSince(uint callback, uint resourceId, byte index, ulong age)
{
- Warehouse.Get(resourceId).Then((r) =>
+ Warehouse.GetById(resourceId).Then((r) =>
{
if (r != null)
{
@@ -1511,7 +1518,7 @@ namespace Esiur.Net.IIP
void IIPRequestSetProperty(uint callback, uint resourceId, byte index, byte[] content)
{
- Warehouse.Get(resourceId).Then((r) =>
+ Warehouse.GetById(resourceId).Then((r) =>
{
if (r != null)
{
diff --git a/Esiur/Net/NetworkConnection.cs b/Esiur/Net/NetworkConnection.cs
index bf81c23..4cbd70f 100644
--- a/Esiur/Net/NetworkConnection.cs
+++ b/Esiur/Net/NetworkConnection.cs
@@ -259,25 +259,33 @@ namespace Esiur.Net
public virtual void Send(byte[] msg)
{
- //Console.WriteLine("TXX " + msg.Length);
-
try
{
- //if (!connected)
- //{
- //Console.WriteLine("not connected");
- // return;
- //}
-
if (sock != null)
{
lastAction = DateTime.Now;
sock.Send(msg);
}
}
- catch (Exception ex)
+ catch
{
- Console.WriteLine(ex.ToString());
+
+ }
+ }
+
+ public virtual void Send(byte[] msg, int offset, int length)
+ {
+ try
+ {
+ if (sock != null)
+ {
+ lastAction = DateTime.Now;
+ sock.Send(msg, offset, length);
+ }
+ }
+ catch
+ {
+
}
}
diff --git a/Esiur/Net/Packets/HTTPResponsePacket.cs b/Esiur/Net/Packets/HTTPResponsePacket.cs
index 3aeaec3..2a97ab9 100644
--- a/Esiur/Net/Packets/HTTPResponsePacket.cs
+++ b/Esiur/Net/Packets/HTTPResponsePacket.cs
@@ -175,7 +175,7 @@ namespace Esiur.Net.Packets
{
if (Message != null)
msg.AddRange(Message);
- }
+ }
Data = msg.ToArray();
diff --git a/Esiur/Net/Packets/IIPPacket.cs b/Esiur/Net/Packets/IIPPacket.cs
index ade655a..ef73135 100644
--- a/Esiur/Net/Packets/IIPPacket.cs
+++ b/Esiur/Net/Packets/IIPPacket.cs
@@ -150,6 +150,12 @@ namespace Esiur.Net.Packets
set;
}
+ public bool Bulk
+ {
+ get;
+ set;
+ }
+
public IIPPacketEvent Event
{
get;
@@ -174,6 +180,13 @@ namespace Esiur.Net.Packets
}
+ public uint[] ResourcesIds { get; set; }
+ public uint NewResourcesIds { get; set; }
+ public uint ChildrenIds { get; set; }
+ public uint StoresIds { get; set; }
+
+ public IIPPacketAttachInfo[] AttachReply { get; set; }
+
public uint ResourceId { get; set; }
public uint NewResourceId { get; set; }
//public uint ParentId { get; set; }
@@ -249,11 +262,11 @@ namespace Esiur.Net.Packets
CallbackId = data.GetUInt32(offset);
offset += 4;
}
- else
+ else // response or reply
{
PreviousAction = Action;
- Action = (IIPPacketAction)(data[offset++] & 0x3f);
-
+ Action = (IIPPacketAction)(data[offset] & 0x1f);
+ Bulk = (data[offset++] & 0x20) == 0x20;
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
@@ -371,8 +384,21 @@ namespace Esiur.Net.Packets
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
- ResourceId = data.GetUInt32(offset);
- offset += 4;
+ if (Bulk)
+ {
+ var cl = data.GetUInt32(offset);
+ offset += 4;
+
+ if (NotEnough(offset, ends, cl))
+ return -dataLengthNeeded;
+
+ ResourcesIds = data.GetUInt32Array(offset, cl);
+ }
+ else
+ {
+ ResourceId = data.GetUInt32(offset);
+ offset += 4;
+ }
}
else if (Action == IIPPacketAction.ReattachResource)
{
@@ -628,35 +654,74 @@ namespace Esiur.Net.Packets
|| Action == IIPPacketAction.ReattachResource)
{
- if (NotEnough(offset, ends, 26))
- return -dataLengthNeeded;
+ if (Bulk)
+ {
+ if (NotEnough(offset, ends, 26))
+ return -dataLengthNeeded;
- ClassId = data.GetGuid(offset);
- offset += 16;
+ ClassId = data.GetGuid(offset);
+ offset += 16;
- ResourceAge = data.GetUInt64(offset);
- offset += 8;
+ ResourceAge = data.GetUInt64(offset);
+ offset += 8;
- uint cl = data.GetUInt16(offset);
- offset += 2;
+ uint cl = data.GetUInt16(offset);
+ offset += 2;
- if (NotEnough(offset, ends, cl))
- return -dataLengthNeeded;
+ if (NotEnough(offset, ends, cl))
+ return -dataLengthNeeded;
- ResourceLink = data.GetString(offset, cl);
- offset += cl;
+ ResourceLink = data.GetString(offset, cl);
+ offset += cl;
- if (NotEnough(offset, ends, 4))
- return -dataLengthNeeded;
+ if (NotEnough(offset, ends, 4))
+ return -dataLengthNeeded;
- cl = data.GetUInt32(offset);
- offset += 4;
+ cl = data.GetUInt32(offset);
+ offset += 4;
- if (NotEnough(offset, ends, cl))
- return -dataLengthNeeded;
+ if (NotEnough(offset, ends, cl))
+ return -dataLengthNeeded;
- Content = data.Clip(offset, cl);
- offset += cl;
+ Content = data.Clip(offset, cl);
+ offset += cl;
+ }
+ else
+ {
+ // length
+ if (NotEnough(offset, ends, 4))
+ return -dataLengthNeeded;
+
+ var cl = data.GetUInt32(offset);
+ offset += 4;
+
+ if (NotEnough(offset, ends, cl))
+ return -dataLengthNeeded;
+
+ // Content = data.Clip(offset, cl);
+ //offset += cl;
+ cl += offset;
+
+ var list = new List();
+
+ while(offset < cl)
+ {
+ Guid classId = data.GetGuid(offset);
+ offset += 16;
+ ulong age = data.GetUInt64(offset);
+ offset += 8;
+ var len = data.GetUInt16(offset);
+ offset += 2;
+ var link = data.GetString(offset, len);
+ offset += len;
+ var cc = data.GetUInt32(offset);
+ list.Add(new IIPPacketAttachInfo(classId, age, link, data.Clip(offset, cc)));
+ offset += cc;
+ }
+
+ AttachReply = list.ToArray();
+
+ }
}
else if (Action == IIPPacketAction.DetachResource)
{
diff --git a/Esiur/Net/Packets/IIPPacketAttachInfo.cs b/Esiur/Net/Packets/IIPPacketAttachInfo.cs
new file mode 100644
index 0000000..53723e7
--- /dev/null
+++ b/Esiur/Net/Packets/IIPPacketAttachInfo.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Esiur.Net.Packets
+{
+ struct IIPPacketAttachInfo
+ {
+ public string Link;
+ public ulong Age;
+ public byte[] Content;
+ public Guid ClassId;
+
+ public IIPPacketAttachInfo(Guid classId, ulong age, string link, byte[] content)
+ {
+ ClassId = classId;
+ Age = age;
+ Content = content;
+ Link = link;
+ }
+ }
+}
diff --git a/Esiur/Net/Sockets/ISocket.cs b/Esiur/Net/Sockets/ISocket.cs
index 25c20cf..6686da7 100644
--- a/Esiur/Net/Sockets/ISocket.cs
+++ b/Esiur/Net/Sockets/ISocket.cs
@@ -59,5 +59,9 @@ namespace Esiur.Net.Sockets
AsyncReply Accept();
IPEndPoint RemoteEndPoint { get; }
IPEndPoint LocalEndPoint { get; }
+
+ void Hold();
+
+ void Unhold();
}
}
diff --git a/Esiur/Net/Sockets/SSLSocket.cs b/Esiur/Net/Sockets/SSLSocket.cs
index c98836b..37decef 100644
--- a/Esiur/Net/Sockets/SSLSocket.cs
+++ b/Esiur/Net/Sockets/SSLSocket.cs
@@ -339,5 +339,15 @@ namespace Esiur.Net.Sockets
return reply;
}
+
+ public void Hold()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Unhold()
+ {
+ throw new NotImplementedException();
+ }
}
}
\ No newline at end of file
diff --git a/Esiur/Net/Sockets/TCPSocket.cs b/Esiur/Net/Sockets/TCPSocket.cs
index 75b58f1..a697e10 100644
--- a/Esiur/Net/Sockets/TCPSocket.cs
+++ b/Esiur/Net/Sockets/TCPSocket.cs
@@ -42,6 +42,8 @@ namespace Esiur.Net.Sockets
Socket sock;
byte[] receiveBuffer;
+ bool held;
+
ArraySegment receiveBufferSegment;
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
@@ -241,9 +243,12 @@ namespace Esiur.Net.Sockets
if (sendBufferQueue.Count > 0)
{
- byte[] data = sendBufferQueue.Dequeue();
lock (sendLock)
+ {
+ byte[] data = sendBufferQueue.Dequeue();
+ //Console.WriteLine(Encoding.UTF8.GetString(data));
sock.SendAsync(new ArraySegment(data), SocketFlags.None).ContinueWith(DataSent);
+ }
}
else
{
@@ -340,22 +345,57 @@ namespace Esiur.Net.Sockets
public void Send(byte[] message, int offset, int size)
{
+ //sock.Blocking =
+ //sock.Send(message, offset, size, SocketFlags.None);
+ //return;
if (sock.Connected)
lock (sendLock)
{
- if (asyncSending)
+
+ if (asyncSending || held)
{
sendBufferQueue.Enqueue(message.Clip((uint)offset, (uint)size));
}
else
{
asyncSending = true;
- sock.SendAsync(new ArraySegment(message, offset, size), SocketFlags.None).ContinueWith(DataSent);
+ sock.BeginSend(message, offset, size, SocketFlags.None, PacketSent, null);
+ //sock.SendAsync(new ArraySegment(msg), SocketFlags.None).ContinueWith(DataSent);
}
}
}
+ private void PacketSent(IAsyncResult ar)
+ {
+ try
+ {
+ if (sendBufferQueue.Count > 0)
+ {
+ lock (sendLock)
+ {
+ byte[] data = sendBufferQueue.Dequeue();
+ sock.BeginSend(data, 0, data.Length, SocketFlags.None, PacketSent, null);
+ }
+ }
+ else
+ {
+ asyncSending = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ if (state != SocketState.Closed && !sock.Connected)
+ {
+ state = SocketState.Terminated;
+ Close();
+ }
+
+ asyncSending = false;
+
+ Global.Log("TCPSocket", LogType.Error, ex.ToString());
+ }
+ }
public bool Trigger(ResourceTrigger trigger)
{
@@ -394,5 +434,16 @@ namespace Esiur.Net.Sockets
return reply;
}
+
+ public void Hold()
+ {
+ held = true;
+ }
+
+ public void Unhold()
+ {
+ DataSent(null);
+ held = false;
+ }
}
}
\ No newline at end of file
diff --git a/Esiur/Net/Sockets/WSSocket.cs b/Esiur/Net/Sockets/WSSocket.cs
index b462a7c..c4ae409 100644
--- a/Esiur/Net/Sockets/WSSocket.cs
+++ b/Esiur/Net/Sockets/WSSocket.cs
@@ -44,7 +44,10 @@ namespace Esiur.Net.Sockets
ISocket sock;
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
+ NetworkBuffer sendNetworkBuffer = new NetworkBuffer();
+
object sendLock = new object();
+ bool held;
public event ISocketReceiveEvent OnReceive;
public event ISocketConnectEvent OnConnect;
@@ -206,12 +209,19 @@ namespace Esiur.Net.Sockets
{
lock(sendLock)
{
- totalSent += message.Length;
- //Console.WriteLine("TX " + message.Length +"/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size));
+ if (held)
+ {
+ sendNetworkBuffer.Write(message);
+ }
+ else
+ {
+ totalSent += message.Length;
+ //Console.WriteLine("TX " + message.Length +"/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size));
- pkt_send.Message = message;
- if (pkt_send.Compose())
- sock.Send(pkt_send.Data);
+ pkt_send.Message = message;
+ if (pkt_send.Compose())
+ sock.Send(pkt_send.Data);
+ }
}
}
@@ -220,13 +230,20 @@ namespace Esiur.Net.Sockets
{
lock (sendLock)
{
- totalSent += size;
- //Console.WriteLine("TX " + size + "/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size));
+ if (held)
+ {
+ sendNetworkBuffer.Write(message, (uint)offset, (uint)size);
+ }
+ else
+ {
+ totalSent += size;
+ //Console.WriteLine("TX " + size + "/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size));
- pkt_send.Message = new byte[size];
- Buffer.BlockCopy(message, offset, pkt_send.Message, 0, size);
- if (pkt_send.Compose())
- sock.Send(pkt_send.Data);
+ pkt_send.Message = new byte[size];
+ Buffer.BlockCopy(message, offset, pkt_send.Message, 0, size);
+ if (pkt_send.Compose())
+ sock.Send(pkt_send.Data);
+ }
}
}
@@ -262,5 +279,35 @@ namespace Esiur.Net.Sockets
{
throw new NotImplementedException();
}
+
+ public void Hold()
+ {
+ //Console.WriteLine("WS Hold ");
+ held = true;
+ }
+
+ public void Unhold()
+ {
+ lock(sendLock)
+ {
+ held = false;
+
+ var message = sendNetworkBuffer.Read();
+
+ //Console.WriteLine("WS Unhold {0}", message == null ? 0 : message.Length);
+
+ if (message == null)
+ return;
+
+ totalSent += message.Length;
+
+ pkt_send.Message = message;
+ if (pkt_send.Compose())
+ sock.Send(pkt_send.Data);
+
+
+
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Esiur/Proxy/ResourceProxy.cs b/Esiur/Proxy/ResourceProxy.cs
index 050aff0..095e443 100644
--- a/Esiur/Proxy/ResourceProxy.cs
+++ b/Esiur/Proxy/ResourceProxy.cs
@@ -12,6 +12,7 @@ namespace Esiur.Proxy
{
static Dictionary cache = new Dictionary();
+
#if NETSTANDARD
static MethodInfo modifyMethod = typeof(Instance).GetTypeInfo().GetMethod("Modified");
static MethodInfo instanceGet = typeof(IResource).GetTypeInfo().GetProperty("Instance").GetGetMethod();
@@ -74,7 +75,7 @@ namespace Esiur.Proxy
TypeAttributes.Public | TypeAttributes.Class, type);
foreach (PropertyInfo propertyInfo in props)
- CreateProperty(propertyInfo, typeBuilder);
+ CreateProperty(propertyInfo, typeBuilder, type);
@@ -98,7 +99,8 @@ namespace Esiur.Proxy
- private static void CreateProperty(PropertyInfo pi, TypeBuilder typeBuilder)
+ //private static void C
+ private static void CreateProperty(PropertyInfo pi, TypeBuilder typeBuilder, Type resourceType)
{
var propertyBuilder = typeBuilder.DefineProperty(pi.Name, PropertyAttributes.None, pi.PropertyType, null);
@@ -108,24 +110,51 @@ namespace Esiur.Proxy
builder.DefineParameter(1, ParameterAttributes.None, "value");
ILGenerator g = builder.GetILGenerator();
+ var getInstance = resourceType.GetTypeInfo().GetProperty("Instance").GetGetMethod();
+
+ g.Emit(OpCodes.Nop);
+ g.Emit(OpCodes.Ldarg_0);
+ g.Emit(OpCodes.Call, getInstance);
+ g.Emit(OpCodes.Ldstr, pi.Name);
+ g.Emit(OpCodes.Callvirt, modifyMethod);
+
+ g.Emit(OpCodes.Nop);
+ g.Emit(OpCodes.Ldarg_0);
+ g.Emit(OpCodes.Ldarg_1);
+ g.Emit(OpCodes.Call, pi.GetSetMethod());
+ g.Emit(OpCodes.Nop);
+ g.Emit(OpCodes.Ret);
+ propertyBuilder.SetSetMethod(builder);
+
+
+ // builder = typeBuilder.DefineMethod("get_" + pi.Name, MethodAttributes.Public | MethodAttributes.Virtual, pi.PropertyType, null);
+ // g = builder.GetILGenerator();
+ // g.Emit(OpCodes.Ldarg_0);
+ // g.Emit(OpCodes.Call, pi.GetGetMethod());
+ // g.Emit(OpCodes.Ret);
+
+ // propertyBuilder.SetGetMethod(builder);
+
+
+ /*
Label callModified = g.DefineLabel();
Label exitMethod = g.DefineLabel();
- /*
- IL_0000: ldarg.0
- IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance()
- // (no C# code)
- IL_0006: dup
- IL_0007: brtrue.s IL_000c
- IL_0009: pop
- // }
- IL_000a: br.s IL_0017
- // (no C# code)
- IL_000c: ldstr "Level3"
- IL_0011: call instance void [Esiur]Esiur.Resource.Instance::Modified(string)
- IL_0016: nop
- IL_0017: ret
- */
+
+ // IL_0000: ldarg.0
+ //IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance()
+ //// (no C# code)
+ //IL_0006: dup
+ //IL_0007: brtrue.s IL_000c
+ //IL_0009: pop
+ //// }
+ //IL_000a: br.s IL_0017
+ //// (no C# code)
+ //IL_000c: ldstr "Level3"
+ //IL_0011: call instance void [Esiur]Esiur.Resource.Instance::Modified(string)
+ //IL_0016: nop
+ //IL_0017: ret
+
// Add IL code for set method
g.Emit(OpCodes.Nop);
@@ -133,13 +162,13 @@ namespace Esiur.Proxy
g.Emit(OpCodes.Ldarg_1);
g.Emit(OpCodes.Call, pi.GetSetMethod());
- /*
- IL_0000: ldarg.0
- IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance()
- IL_0006: ldstr "Level3"
- IL_000b: callvirt instance void [Esiur]Esiur.Resource.Instance::Modified(string)
- IL_0010: ret
- */
+
+ // IL_0000: ldarg.0
+ // IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance()
+ // IL_0006: ldstr "Level3"
+ //IL_000b: callvirt instance void [Esiur]Esiur.Resource.Instance::Modified(string)
+ //IL_0010: ret
+
// Call property changed for object
g.Emit(OpCodes.Nop);
@@ -158,6 +187,11 @@ namespace Esiur.Proxy
g.MarkLabel(exitMethod);
g.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(builder);
+
+
+ // create get method
+
+ */
}
}
diff --git a/Esiur/Resource/Instance.cs b/Esiur/Resource/Instance.cs
index f4cd329..28391e9 100644
--- a/Esiur/Resource/Instance.cs
+++ b/Esiur/Resource/Instance.cs
@@ -388,12 +388,15 @@ namespace Esiur.Resource
#endif
*/
- IResource res;
- if (resource.TryGetTarget(out res))
- {
- var rt = pt.Info.GetValue(res, null);
- props.Add(new PropertyValue(rt, ages[pt.Index], modificationDates[pt.Index]));
- }
+ //if (pt.Serilize)
+ //{
+ IResource res;
+ if (resource.TryGetTarget(out res))
+ {
+ var rt = pt.Serilize ? pt.Info.GetValue(res, null) : null;
+ props.Add(new PropertyValue(rt, ages[pt.Index], modificationDates[pt.Index]));
+ }
+ //}
}
return props.ToArray();
diff --git a/Esiur/Resource/ResourceProperty.cs b/Esiur/Resource/ResourceProperty.cs
index 82fb3f4..3234025 100644
--- a/Esiur/Resource/ResourceProperty.cs
+++ b/Esiur/Resource/ResourceProperty.cs
@@ -35,6 +35,7 @@ namespace Esiur.Resource
[AttributeUsage(AttributeTargets.Property)]
public class ResourceProperty : System.Attribute
{
+ bool serialize;
string readExpansion;
string writeExpansion;
// bool recordable;
@@ -47,6 +48,8 @@ namespace Esiur.Resource
public StorageMode Storage => storage;
+ public bool Serialize => serialize;
+
public string ReadExpansion
{
get
@@ -63,11 +66,12 @@ namespace Esiur.Resource
}
}
- public ResourceProperty(StorageMode storage = StorageMode.NonVolatile, string readExpansion = null, string writeExpansion = null)
+ public ResourceProperty(StorageMode storage = StorageMode.NonVolatile, bool serialize = true, string readExpansion = null, string writeExpansion = null)
{
this.readExpansion = readExpansion;
this.writeExpansion = writeExpansion;
this.storage = storage;
+ this.serialize = serialize;
}
}
}
diff --git a/Esiur/Resource/Template/PropertyTemplate.cs b/Esiur/Resource/Template/PropertyTemplate.cs
index 99876c4..5fb29d8 100644
--- a/Esiur/Resource/Template/PropertyTemplate.cs
+++ b/Esiur/Resource/Template/PropertyTemplate.cs
@@ -24,6 +24,10 @@ namespace Esiur.Resource.Template
set;
}
+ public bool Serilize
+ {
+ get;set;
+ }
//bool ReadOnly;
//IIPTypes::DataType ReturnType;
public PropertyPermission Permission {
diff --git a/Esiur/Resource/Template/ResourceTemplate.cs b/Esiur/Resource/Template/ResourceTemplate.cs
index 6b7e1f1..e105fab 100644
--- a/Esiur/Resource/Template/ResourceTemplate.cs
+++ b/Esiur/Resource/Template/ResourceTemplate.cs
@@ -161,6 +161,7 @@ namespace Esiur.Resource.Template
{
var pt = new PropertyTemplate(this, i++, pi.Name, ps[0].ReadExpansion, ps[0].WriteExpansion, ps[0].Storage);
pt.Info = pi;
+ pt.Serilize = ps[0].Serialize;
properties.Add(pt);
}
}
diff --git a/Esiur/Resource/Warehouse.cs b/Esiur/Resource/Warehouse.cs
index 4275553..25f1eea 100644
--- a/Esiur/Resource/Warehouse.cs
+++ b/Esiur/Resource/Warehouse.cs
@@ -84,7 +84,7 @@ namespace Esiur.Resource
///
/// Instance Id
///
- public static AsyncReply Get(uint id)
+ public static AsyncReply GetById(uint id)
{
if (resources.ContainsKey(id))
{
@@ -317,9 +317,6 @@ namespace Esiur.Resource
/// Resource instance.
public static AsyncReply Get(string path, object attributes = null, IResource parent = null, IPermissionsManager manager = null)
{
-
-
-
var rt = new AsyncReply();
// Should we create a new store ?
@@ -528,7 +525,7 @@ namespace Esiur.Resource
var toBeRemoved = resources.Values.Where(x => {
IResource r;
return x.TryGetTarget(out r) && r.Instance.Store == resource;
- });
+ }).ToArray();
foreach (var o in toBeRemoved)
{