private void SendUpdates() { if (this._ownerMessage.Events.Count != 0) { if (this._connection.NetConnectionClient.Connection != null) { SharedObjectMessage message; RtmpConnection connection = this._connection.NetConnectionClient.Connection as RtmpConnection; RtmpChannel channel = connection.GetChannel(3); if (connection.ObjectEncoding == FluorineFx.ObjectEncoding.AMF0) { message = new SharedObjectMessage(null, this._name, this._version, this.IsPersistentObject); } else { message = new FlexSharedObjectMessage(null, this._name, this._version, this.IsPersistentObject); } message.AddEvents(this._ownerMessage.Events); if (channel != null) { channel.Write(message); } else { log.Warn(__Res.GetString("Channel_NotFound")); } } this._ownerMessage.Events.Clear(); } }
public void Connect(NetConnection connection, string parameters) { SharedObjectMessage message; if (this._initialSyncReceived) { throw new InvalidOperationException("SharedObject already connected"); } ValidationUtils.ArgumentNotNull(connection, "connection"); ValidationUtils.ArgumentNotNull(connection.Uri, "connection"); ValidationUtils.ArgumentConditionTrue(connection.Uri.Scheme == "rtmp", "connection", "NetConnection object must use the Real-Time Messaging Protocol (RTMP)"); ValidationUtils.ArgumentConditionTrue(connection.Connected, "connection", "NetConnection object must be connected"); this._connection = connection; this._initialSyncReceived = false; if (connection.ObjectEncoding == FluorineFx.ObjectEncoding.AMF0) { message = new SharedObjectMessage(this._name, this._version, this._persistentSO); } else { message = new FlexSharedObjectMessage(this._name, this._version, this._persistentSO); } SharedObjectEvent sharedObjectEvent = new SharedObjectEvent(SharedObjectEventType.SERVER_CONNECT, null, null); message.AddEvent(sharedObjectEvent); this._connection.NetConnectionClient.Write(message); }
protected override void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message) { ISharedObject sharedObject = null; string name = message.Name; IScope scope = connection.Scope; bool isPersistent = message.IsPersistent; if (scope == null) { SharedObjectMessage message2; if (connection.ObjectEncoding == ObjectEncoding.AMF0) { message2 = new SharedObjectMessage(name, 0, isPersistent); } else { message2 = new FlexSharedObjectMessage(name, 0, isPersistent); } message2.AddEvent(new SharedObjectEvent(SharedObjectEventType.CLIENT_STATUS, "SharedObject.NoObjectFound", "error")); connection.GetChannel(3).Write(message2); } else { ISharedObjectService scopeService = ScopeUtils.GetScopeService(scope, typeof(ISharedObjectService)) as ISharedObjectService; if (!scopeService.HasSharedObject(scope, name)) { ISharedObjectSecurityService service2 = ScopeUtils.GetScopeService(scope, typeof(ISharedObjectSecurityService)) as ISharedObjectSecurityService; if (service2 != null) { IEnumerator sharedObjectSecurity = service2.GetSharedObjectSecurity(); while (sharedObjectSecurity.MoveNext()) { ISharedObjectSecurity current = sharedObjectSecurity.Current as ISharedObjectSecurity; if (!current.IsCreationAllowed(scope, name, isPersistent)) { SendSOCreationFailed(connection, name, isPersistent); return; } } } if (!scopeService.CreateSharedObject(scope, name, isPersistent)) { SendSOCreationFailed(connection, name, isPersistent); return; } } sharedObject = scopeService.GetSharedObject(scope, name); if (sharedObject.IsPersistentObject != isPersistent) { log.Debug(string.Format("Shared object '{0}' persistence mismatch", name)); SendSOPersistenceMismatch(connection, name, isPersistent); } else { sharedObject.DispatchEvent(message); } } }
private RemoteSharedObject(string name, string remotePath, object persistence, bool secure) { _name = name; _path = remotePath; _persistentSO = !false.Equals(persistence); _secure = secure; _objectEncoding = ObjectEncoding.AMF0; _initialSyncReceived = false; _ownerMessage = new SharedObjectMessage(null, null, -1, false); }
private static ISharedObjectMessage DecodeSharedObject(ByteBuffer stream) { RtmpReader reader = new RtmpReader(stream); string name = reader.ReadString(); int version = reader.ReadInt32(); bool persistent = reader.ReadInt32() == 2; reader.ReadInt32(); SharedObjectMessage so = new SharedObjectMessage(null, name, version, persistent); DecodeSharedObject(so, stream, reader); return(so); }
private static void DecodeSharedObject(SharedObjectMessage so, ByteBuffer stream, RtmpReader reader) { while (stream.HasRemaining) { SharedObjectEventType type = SharedObjectTypeMapping.ToType(reader.ReadByte()); string key = null; object obj2 = null; int @int = stream.GetInt(); switch (type) { case SharedObjectEventType.CLIENT_STATUS: key = reader.ReadString(); obj2 = reader.ReadString(); break; case SharedObjectEventType.CLIENT_UPDATE_DATA: key = reader.ReadString(); obj2 = reader.ReadData(); break; default: if ((type != SharedObjectEventType.SERVER_SEND_MESSAGE) && (type != SharedObjectEventType.CLIENT_SEND_MESSAGE)) { if (@int > 0) { key = reader.ReadString(); if (@int > (key.Length + 2)) { obj2 = reader.ReadData(); } } } else { int position = (int)stream.Position; key = reader.ReadData() as string; List <object> list = new List <object>(); while ((stream.Position - position) < @int) { object item = reader.ReadData(); list.Add(item); } obj2 = list; } break; } so.AddEvent(type, key, obj2); } }
private static void SendSOCreationFailed(RtmpConnection connection, string name, bool persistent) { SharedObjectMessage msg; if (connection.ObjectEncoding == ObjectEncoding.AMF0) { msg = new SharedObjectMessage(name, 0, persistent); } else { msg = new FlexSharedObjectMessage(name, 0, persistent); } msg.AddEvent(new SharedObjectEvent(SharedObjectEventType.CLIENT_STATUS, StatusASO.SO_CREATION_FAILED, "error")); connection.GetChannel((byte)3).Write(msg); }
private static void SendSOPersistenceMismatch(RtmpConnection connection, string name, bool persistent) { SharedObjectMessage msg; if (connection.ObjectEncoding == ObjectEncoding.AMF0) { msg = new SharedObjectMessage(name, 0, persistent); } else { msg = new FlexSharedObjectMessage(name, 0, persistent); } msg.AddEvent(new SharedObjectEvent(SharedObjectEventType.CLIENT_STATUS, StatusASO.SO_PERSISTENCE_MISMATCH, "error")); connection.GetChannel((byte)3).Write(msg); }
private static void SendSOPersistenceMismatch(RtmpConnection connection, string name, bool persistent) { SharedObjectMessage message; if (connection.ObjectEncoding == ObjectEncoding.AMF0) { message = new SharedObjectMessage(name, 0, persistent); } else { message = new FlexSharedObjectMessage(name, 0, persistent); } message.AddEvent(new SharedObjectEvent(SharedObjectEventType.CLIENT_STATUS, "SharedObject.BadPersistence", "error")); connection.GetChannel(3).Write(message); }
static ISharedObjectMessage DecodeSharedObject(ByteBuffer stream) { RtmpReader reader = new RtmpReader(stream); string name = reader.ReadString(); // Read version of SO to modify int version = reader.ReadInt32(); // Read persistence informations bool persistent = reader.ReadInt32() == 2; // Skip unknown bytes //skip(4); reader.ReadInt32(); SharedObjectMessage so = new SharedObjectMessage(null, name, version, persistent); DecodeSharedObject(so, stream, reader); return(so); }
internal static void Dispatch(SharedObjectMessage message) { RemoteSharedObject rso = null; lock ((SharedObjects as ICollection).SyncRoot) { if (SharedObjects.ContainsKey(message.Name)) { rso = SharedObjects[message.Name] as RemoteSharedObject; } } if (rso != null) { try { rso.DispatchSharedObjectMessage(message); } catch (Exception ex) { rso.RaiseNetStatus(ex); } } }
private RemoteSharedObject(string name, string remotePath, object persistence, bool secure) { this._name = string.Empty; this._path = string.Empty; this._persistentSO = false; this._version = 1; this._updateCounter = 0; this._modified = false; this._lastModified = -1L; this._source = null; this._name = name; this._path = remotePath; bool flag = false; this._persistentSO = !flag.Equals(persistence); this._secure = secure; this._objectEncoding = FluorineFx.ObjectEncoding.AMF0; this._initialSyncReceived = false; this._ownerMessage = new SharedObjectMessage(null, null, -1, false); }
public void Close() { if ((this._initialSyncReceived && (this._connection != null)) && this._connection.Connected) { SharedObjectMessage message; if (this._connection.ObjectEncoding == FluorineFx.ObjectEncoding.AMF0) { message = new SharedObjectMessage(this._name, this._version, this._persistentSO); } else { message = new FlexSharedObjectMessage(this._name, this._version, this._persistentSO); } SharedObjectEvent sharedObjectEvent = new SharedObjectEvent(SharedObjectEventType.SERVER_DISCONNECT, null, null); message.AddEvent(sharedObjectEvent); this._connection.NetConnectionClient.Write(message); base.RemoveAttributes(); this._ownerMessage.Events.Clear(); } this._initialSyncReceived = false; }
internal static void Dispatch(SharedObjectMessage message) { RemoteSharedObject obj2 = null; lock (((ICollection)SharedObjects).SyncRoot) { if (SharedObjects.ContainsKey(message.Name)) { obj2 = SharedObjects[message.Name]; } } if (obj2 != null) { try { obj2.DispatchSharedObjectMessage(message); } catch (Exception exception) { obj2.RaiseNetStatus(exception); } } }
/// <summary> /// Send update notification over data channel of RTMP connection /// </summary> private void SendUpdates() { if (_ownerMessage.Events.Count != 0) { if (_connection.NetConnectionClient.Connection != null) { RtmpConnection connection = _connection.NetConnectionClient.Connection as RtmpConnection; // Only send updates when issued through RTMP request RtmpChannel channel = connection.GetChannel((byte)3); // Send update to "owner" of this update request SharedObjectMessage syncOwner; if (connection.ObjectEncoding == ObjectEncoding.AMF0) { syncOwner = new SharedObjectMessage(null, _name, _version, this.IsPersistentObject); } else { syncOwner = new FlexSharedObjectMessage(null, _name, _version, this.IsPersistentObject); } syncOwner.AddEvents(_ownerMessage.Events); if (channel != null) { channel.Write(syncOwner); } else { #if !SILVERLIGHT log.Warn(__Res.GetString(__Res.Channel_NotFound)); #endif } } _ownerMessage.Events.Clear(); } }
static void DecodeSharedObject(SharedObjectMessage so, ByteBuffer stream, RtmpReader reader) { // Parse request body while (stream.HasRemaining) { byte typeCode = reader.ReadByte(); SharedObjectEventType type = SharedObjectTypeMapping.ToType(typeCode); string key = null; object value = null; int length = stream.GetInt(); //reader.ReadInt32(); switch (type) { case SharedObjectEventType.CLIENT_STATUS: // Status code key = reader.ReadString(); // Status level value = reader.ReadString(); break; case SharedObjectEventType.CLIENT_UPDATE_DATA: { key = reader.ReadString(); value = reader.ReadData(); /* * key = null; * // Map containing new attribute values * Hashtable map = new Hashtable(); * int start = (int)stream.Position; * while((int)stream.Position - start < length) * { * string tmp = reader.ReadString(); * map[tmp] = reader.ReadData(); * } * value = map; */ } break; default: if (type != SharedObjectEventType.SERVER_SEND_MESSAGE && type != SharedObjectEventType.CLIENT_SEND_MESSAGE) { if (length > 0) { key = reader.ReadString(); if (length > key.Length + 2) { value = reader.ReadData(); } } } else { int start = (int)stream.Position; // the "send" event seems to encode the handler name // as complete AMF string including the string type byte key = reader.ReadData() as string; // read parameters #if !(NET_1_1) List <object> paramList = new List <object>(); #else ArrayList paramList = new ArrayList(); #endif while (stream.Position - start < length) { object tmp = reader.ReadData(); paramList.Add(tmp); } value = paramList; } break; } so.AddEvent(type, key, value); } }
protected override void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message) { ISharedObject so = null; string name = message.Name; IScope scope = connection.Scope; bool persistent = message.IsPersistent; if (scope == null) { // The scope already has been deleted. SendSOCreationFailed(connection, name, persistent); return; } ISharedObjectService sharedObjectService = ScopeUtils.GetScopeService(scope, typeof(ISharedObjectService)) as ISharedObjectService; if (!sharedObjectService.HasSharedObject(scope, name)) { ISharedObjectSecurityService securityService = ScopeUtils.GetScopeService(scope, typeof(ISharedObjectSecurityService)) as ISharedObjectSecurityService; if (securityService != null) { // Check handlers to see if creation is allowed IEnumerator enumerator = securityService.GetSharedObjectSecurity(); while (enumerator.MoveNext()) { ISharedObjectSecurity handler = enumerator.Current as ISharedObjectSecurity; if (!handler.IsCreationAllowed(scope, name, persistent)) { SendSOCreationFailed(connection, name, persistent); return; } } } if (!sharedObjectService.CreateSharedObject(scope, name, persistent)) { SendSOCreationFailed(connection, name, persistent); return; } } so = sharedObjectService.GetSharedObject(scope, name); if (so.IsPersistentObject != persistent) { log.Debug(string.Format("Shared object '{0}' persistence mismatch", name)); SendSOPersistenceMismatch(connection, name, persistent); return; } so.DispatchEvent(message); }
internal void DispatchSharedObjectMessage(SharedObjectMessage message) { #if !(NET_1_1) List <ASObject> changeList = null; List <ASObject> notifications = null; List <SendMessageEventArgs> messages = null; #else ArrayList changeList = null; ArrayList notifications = null; ArrayList messages = null; #endif bool raiseOnConnect = false; foreach (ISharedObjectEvent sharedObjectEvent in message.Events) { switch (sharedObjectEvent.Type) { case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_INITIAL_DATA: if (message.Version > 0) { _version = message.Version; } _attributes.Clear(); _initialSyncReceived = true; //Delay the connection notification until the attribute store has been populated //RaiseOnConnect(); raiseOnConnect = true; break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_UPDATE_DATA: case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_UPDATE_ATTRIBUTE: { ASObject infoObject = new ASObject(); infoObject["code"] = "change"; infoObject["name"] = sharedObjectEvent.Key; infoObject["oldValue"] = this.GetAttribute(sharedObjectEvent.Key); //Do not update the attribute store if this is a notification that the SetAttribute is accepted if (sharedObjectEvent.Type != FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_UPDATE_ATTRIBUTE) { _attributes[sharedObjectEvent.Key] = sharedObjectEvent.Value; } if (changeList == null) #if !(NET_1_1) { changeList = new List <ASObject>(); } #else { changeList = new ArrayList(); } #endif changeList.Add(infoObject); } break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_CLEAR_DATA: { ASObject infoObject = new ASObject(); infoObject["code"] = "clear"; if (changeList == null) #if !(NET_1_1) { changeList = new List <ASObject>(); } #else { changeList = new ArrayList(); } #endif changeList.Add(infoObject); _attributes.Clear(); } break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_DELETE_ATTRIBUTE: case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_DELETE_DATA: { _attributes.Remove(sharedObjectEvent.Key); ASObject infoObject = new ASObject(); infoObject["code"] = "delete"; infoObject["name"] = sharedObjectEvent.Key; if (changeList == null) #if !(NET_1_1) { changeList = new List <ASObject>(); } #else { changeList = new ArrayList(); } #endif changeList.Add(infoObject); } break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_STATUS: { ASObject infoObject = new ASObject(); infoObject["level"] = sharedObjectEvent.Value; infoObject["code"] = sharedObjectEvent.Key; if (notifications == null) #if !(NET_1_1) { notifications = new List <ASObject>(); } #else { notifications = new ArrayList(); } #endif notifications.Add(infoObject); } break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_SEND_MESSAGE: case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.SERVER_SEND_MESSAGE: { string handler = sharedObjectEvent.Key; IList arguments = sharedObjectEvent.Value as IList; MethodInfo mi = MethodHandler.GetMethod(this.GetType(), handler, arguments); if (mi != null) { ParameterInfo[] parameterInfos = mi.GetParameters(); object[] args = new object[parameterInfos.Length]; arguments.CopyTo(args, 0); TypeHelper.NarrowValues(args, parameterInfos); try { InvocationHandler invocationHandler = new InvocationHandler(mi); object result = invocationHandler.Invoke(this, args); } catch (Exception exception) { #if !SILVERLIGHT log.Error("Error while invoking method " + handler + " on shared object", exception); #endif } } else { if (messages == null) #if !(NET_1_1) { messages = new List <SendMessageEventArgs>(); } #else { messages = new ArrayList(); } #endif messages.Add(new SendMessageEventArgs(handler, arguments)); } } break; default: break; } } if (raiseOnConnect) { RaiseOnConnect(); } if (changeList != null && changeList.Count > 0) { #if !(NET_1_1) RaiseSync(changeList.ToArray()); #else RaiseSync(changeList.ToArray(typeof(ASObject)) as ASObject[]); #endif } if (notifications != null) { foreach (ASObject infoObject in notifications) { RaiseNetStatus(infoObject); } } if (messages != null) { foreach (SendMessageEventArgs e in messages) { RaiseSendMessage(e); } } }
internal void DispatchSharedObjectMessage(SharedObjectMessage message) { List <ASObject> list = null; List <ASObject> list2 = null; foreach (ISharedObjectEvent event2 in message.Events) { ASObject obj2; switch (event2.Type) { case SharedObjectEventType.SERVER_SEND_MESSAGE: case SharedObjectEventType.CLIENT_SEND_MESSAGE: { string key = event2.Key; IList arguments = event2.Value as IList; MethodInfo methodInfo = MethodHandler.GetMethod(base.GetType(), key, arguments); if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; arguments.CopyTo(array, 0); TypeHelper.NarrowValues(array, parameters); try { object obj3 = new InvocationHandler(methodInfo).Invoke(this, array); } catch (Exception exception) { log.Error("Error while invoking method " + key + " on shared object", exception); } } break; } case SharedObjectEventType.CLIENT_CLEAR_DATA: obj2 = new ASObject(); obj2["code"] = "clear"; if (list == null) { list = new List <ASObject>(); } list.Add(obj2); base._attributes.Clear(); break; case SharedObjectEventType.CLIENT_DELETE_ATTRIBUTE: case SharedObjectEventType.CLIENT_DELETE_DATA: base._attributes.Remove(event2.Key); obj2 = new ASObject(); obj2["code"] = "delete"; obj2["name"] = event2.Key; if (list == null) { list = new List <ASObject>(); } list.Add(obj2); break; case SharedObjectEventType.CLIENT_INITIAL_DATA: if (message.Version > 0) { this._version = message.Version; } base._attributes.Clear(); this._initialSyncReceived = true; this.RaiseOnConnect(); break; case SharedObjectEventType.CLIENT_STATUS: obj2 = new ASObject(); obj2["level"] = event2.Value; obj2["code"] = event2.Key; if (list2 == null) { list2 = new List <ASObject>(); } list2.Add(obj2); break; case SharedObjectEventType.CLIENT_UPDATE_DATA: case SharedObjectEventType.CLIENT_UPDATE_ATTRIBUTE: obj2 = new ASObject(); obj2["code"] = "change"; obj2["name"] = event2.Key; obj2["oldValue"] = this.GetAttribute(event2.Key); base._attributes[event2.Key] = event2.Value; if (list == null) { list = new List <ASObject>(); } list.Add(obj2); break; } } if ((list != null) && (list.Count > 0)) { this.RaiseSync(list.ToArray()); } if (list2 != null) { foreach (ASObject obj2 in list2) { this.RaiseNetStatus(obj2); } } }
/// <summary> /// This method supports the infrastructure and is not intended to be used directly from your code. /// </summary> /// <param name="connection"></param> /// <param name="channel"></param> /// <param name="header"></param> /// <param name="message"></param> protected abstract void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message);
protected override void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message) { _netConnection.OnSharedObject(connection, channel, header, message); }
internal void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message) { RemoteSharedObject.Dispatch(message); }