public void Read(out ObjectNotificationRequest notificationRequest) { TraceCurrentPos(); long beginPos = _source.BaseStream.CanSeek ? _source.BaseStream.Position : -1; SerializableType type; Read(out type); int length = _source.ReadInt32(); var ids = new int[length]; for (int i = 0; i < length; i++) { ids[i] = _source.ReadInt32(); } notificationRequest = new ObjectNotificationRequest() { Type = type, IDs = ids }; long endPos = _source.BaseStream.CanSeek ? _source.BaseStream.Position : -1; SerializerTrace("read ObjectNotificationRequest ({0} IDs, {1} bytes)", ids.Length, endPos - beginPos); }
public void Write(ObjectNotificationRequest notificationRequest) { if (notificationRequest == null) { throw new ArgumentNullException("notificationRequest"); } TraceCurrentPos(); SerializerTrace("Writing ObjectNotificationRequest for {0} with {1} IDs", notificationRequest.Type, notificationRequest.IDs.Length); long beginPos = _dest.BaseStream.CanSeek ? _dest.BaseStream.Position : -1; Write(notificationRequest.Type); _dest.Write(notificationRequest.IDs.Length); foreach (var id in notificationRequest.IDs) { _dest.Write(id); } long endPos = _dest.BaseStream.CanSeek ? _dest.BaseStream.Position : -1; SerializerTrace("({0} bytes)", endPos - beginPos); }
/// <summary> /// Puts a number of changed objects into the database. The resultant objects are sent back to the client. /// </summary> /// <param name="version">Current version of generated Zetbox.Objects assembly</param> /// <param name="msgArray">a streamable list of <see cref="IPersistenceObject"/>s</param> /// <param name="notificationRequests">A list of objects the client wants to be notified about, if they change.</param> /// <returns>a streamable list of <see cref="IPersistenceObject"/>s</returns> public byte[] SetObjects(Guid version, byte[] msgArray, ObjectNotificationRequest[] notificationRequests) { using (Logging.Facade.DebugTraceMethodCall("SetObjects")) { DebugLogIdentity(); int resultCount = 0; var ticks = _perfCounter.IncrementSetObjects(); try { if (msgArray == null) { throw new ArgumentNullException("msgArray"); } MemoryStream msg = new MemoryStream(msgArray); msg.Seek(0, SeekOrigin.Begin); using (IZetboxContext ctx = _ctxFactory()) { var objects = ReadObjects(msg, ctx); // Set Operation var changedObjects = _sohFactory .GetServerObjectSetHandler() .SetObjects(version, ctx, objects, notificationRequests ?? new ObjectNotificationRequest[0]) .Cast<IStreamable>(); resultCount = objects.Count; return SendObjects(changedObjects, true).ToArray(); } } catch (Exception ex) { Helper.ThrowFaultException(ex); // Never called, Handle errors throws an Exception return null; } finally { _perfCounter.DecrementSetObjects(resultCount, ticks); } } }
public byte[] InvokeServerMethod(Guid version, SerializableType type, int ID, string method, SerializableType[] parameterTypes, byte[] parameterArray, byte[] changedObjectsArray, ObjectNotificationRequest[] notificationRequests, out byte[] retChangedObjects) { using (Logging.Facade.DebugTraceMethodCallFormat("InvokeServerMethod:" + method, "method={0}, ID={1}", method, ID)) { if (type == null) throw new ArgumentNullException("type"); if (string.IsNullOrEmpty(method)) throw new ArgumentNullException("method"); if (parameterTypes == null) throw new ArgumentNullException("parameterTypes"); if (parameterArray == null) throw new ArgumentNullException("parameterArray"); if (changedObjectsArray == null) throw new ArgumentNullException("changedObjectsArray"); _perfCounter.IncrementServerMethodInvocation(); retChangedObjects = null; try { DebugLogIdentity(); using (IZetboxContext ctx = _ctxFactory()) { var parameter = new MemoryStream(parameterArray); parameter.Seek(0, SeekOrigin.Begin); List<object> parameterList = new List<object>(); using (var parameterReader = _readerFactory.Invoke(new BinaryReader(parameter))) { foreach (var t in parameterTypes) { object val; var systemType = t.GetSystemType(); parameterReader.Read(out val, systemType.IsICompoundObject() // IDataObjects are serialized as proxy, only ICompoundObject are serialized directoy ? ctx.ToImplementationType(ctx.GetInterfaceType(systemType)).Type : systemType); parameterList.Add(val); } } var changedObjects = new MemoryStream(changedObjectsArray); changedObjects.Seek(0, SeekOrigin.Begin); var readObjects = ReadObjects(changedObjects, ctx); // Context is ready, translate IDataObjectParameter for(int i=0;i<parameterList.Count;i++) { var p = parameterList[i] as ZetboxStreamReader.IDataObjectProxy; if(p != null) { parameterList[i] = ctx.Find(_iftFactory(p.Type.GetSystemType()), p.ID); } } IEnumerable<IPersistenceObject> changedObjectsList; var result = _sohFactory .GetServerObjectHandler(_iftFactory(type.GetSystemType())) .InvokeServerMethod(version, ctx, ID, method, parameterTypes.Select(t => t.GetSystemType()), parameterList, readObjects, notificationRequests ?? new ObjectNotificationRequest[0], out changedObjectsList); retChangedObjects = SendObjects(changedObjectsList.Cast<IStreamable>(), true).ToArray(); if (Logging.Facade.IsDebugEnabled && result != null) { Logging.Facade.DebugFormat("Serializing method result type is '{0}'", result.GetType().FullName); } if (result != null && result.GetType() == typeof(string)) { Logging.Facade.Debug("Serializing method result as string"); // string is also a IEnumerable, but FindElementTypes returns nothing MemoryStream resultStream = new MemoryStream(); new BinaryFormatter().Serialize(resultStream, result); return resultStream.ToArray(); } else if (result != null && result.GetType().IsIStreamable()) { Logging.Facade.Debug("Serializing method result as IStreamable"); IStreamable resultObj = (IStreamable)result; return SendObjects(new IStreamable[] { resultObj }, true).ToArray(); } else if (result != null && result.GetType().IsIEnumerable() && result.GetType().FindElementTypes().Any(t => t.IsIStreamable())) { Logging.Facade.Debug("Serializing method result as IEnumerable<IStreamable>"); var lst = ((IEnumerable)result).AsQueryable().Cast<IStreamable>().Take(Zetbox.API.Helper.MAXLISTCOUNT); return SendObjects(lst, true).ToArray(); } else if (result != null) { Logging.Facade.Debug("Serializing method result as object with BinaryFormatter"); MemoryStream resultStream = new MemoryStream(); new BinaryFormatter().Serialize(resultStream, result); return resultStream.ToArray(); } else { Logging.Facade.Debug("Serializing empty method"); return new byte[] { }; } } } catch (Exception ex) { Helper.ThrowFaultException(ex); // Never called, Handle errors throws an Exception return null; } } }