Esempio n. 1
0
        /// <summary>
        /// Connects to a remote shared object on the server through the specified connection. Use this method after
        /// issuing SharedObject.GetRemote(...). After a successful connection, the sync event is dispatched.
        /// </summary>
        /// <param name="connection">A NetConnection object (such as one used to communicate with Flash Media Server) that is using the Real-Time Messaging Protocol (RTMP).</param>
        /// <param name="parameters">Parameters.</param>
        public void Connect(NetConnection connection, string parameters)
        {
            if (_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");
            _connection          = connection;
            _initialSyncReceived = false;

            GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectMessage message;
            if (connection.ObjectEncoding == ObjectEncoding.AMF0)
            {
                message = new GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectMessage(_name, _version, _persistentSO);
            }
            else
            {
                message = new GodLesZ.Library.Amf.Messaging.Rtmp.SO.FlexSharedObjectMessage(_name, _version, _persistentSO);
            }
            GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectEvent evt = new GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectEvent(GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectEventType.SERVER_CONNECT, null, null);
            message.AddEvent(evt);
            _connection.NetConnectionClient.Write(message);
        }
Esempio n. 2
0
        /// <summary>
        /// Closes the connection between a remote shared object and the server.
        /// </summary>
        public void Close()
        {
            if (_initialSyncReceived && _connection != null && _connection.Connected)
            {
                GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectMessage message;
                if (_connection.ObjectEncoding == ObjectEncoding.AMF0)
                {
                    message = new GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectMessage(_name, _version, _persistentSO);
                }
                else
                {
                    message = new GodLesZ.Library.Amf.Messaging.Rtmp.SO.FlexSharedObjectMessage(_name, _version, _persistentSO);
                }
                GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectEvent evt = new GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectEvent(GodLesZ.Library.Amf.Messaging.Rtmp.SO.SharedObjectEventType.SERVER_DISCONNECT, null, null);
                message.AddEvent(evt);
                _connection.NetConnectionClient.Write(message);

                // clear collections
                base.RemoveAttributes();
                _ownerMessage.Events.Clear();
            }
            _initialSyncReceived = false;
        }
Esempio n. 3
0
        /// <summary>
        /// Send update notification over data channel of RTMP connection
        /// </summary>
        private void SendUpdates()
        {
            int  currentVersion = _version.Value;
            bool persist        = this.IsPersistentObject;
            //Get read-only version of events
            ConcurrentLinkedQueue <ISharedObjectEvent> events = new ConcurrentLinkedQueue <ISharedObjectEvent>(_ownerMessage.Events);

            //clear out previous events
            _ownerMessage.Events.Clear();

            if (events.Count != 0)
            {
                //Send update to "owner" of this update request
                if (_source != null)
                {
                    RtmpConnection connection = _source 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, currentVersion, persist);
                    }
                    else
                    {
                        syncOwner = new FlexSharedObjectMessage(null, _name, currentVersion, persist);
                    }
                    syncOwner.AddEvents(events);

                    if (channel != null)
                    {
                        channel.Write(syncOwner);
                    }
                    else
                    {
                        log.Warn(__Res.GetString(__Res.Channel_NotFound));
                    }
                }
            }
            //Clear owner events
            events.Clear();
            //Get read-only version of sync events
            events.AddRange(_syncEvents);
            //Clear out previous events
            _syncEvents.Clear();
            if (events.Count != 0)
            {
                // Synchronize updates with all registered clients of this shared
                foreach (IEventListener listener in _listeners)
                {
                    if (listener == _source)
                    {
                        // Don't re-send update to active client
                        continue;
                    }
                    if (!(listener is RtmpConnection))
                    {
                        log.Warn(__Res.GetString(__Res.SharedObject_SyncConnError));
                        continue;
                    }
                    // Create a new sync message for every client to avoid
                    // concurrent access through multiple threads
                    // TODO: perhaps we could cache the generated message
                    RtmpConnection      connection = listener as RtmpConnection;
                    SharedObjectMessage syncMessage;
                    if (connection.ObjectEncoding == ObjectEncoding.AMF0)
                    {
                        syncMessage = new SharedObjectMessage(null, _name, currentVersion, persist);
                    }
                    else
                    {
                        syncMessage = new FlexSharedObjectMessage(null, _name, currentVersion, persist);
                    }
                    syncMessage.AddEvents(events);

                    RtmpChannel channel = connection.GetChannel((byte)3);
                    log.Debug(__Res.GetString(__Res.SharedObject_Sync, channel));
                    channel.Write(syncMessage);
                }
            }
        }
Esempio n. 4
0
		/// <summary>
		/// Send update notification over data channel of RTMP connection
		/// </summary>
		private void SendUpdates() {
			int currentVersion = _version.Value;
			bool persist = this.IsPersistentObject;
			//Get read-only version of events
			ConcurrentLinkedQueue<ISharedObjectEvent> events = new ConcurrentLinkedQueue<ISharedObjectEvent>(_ownerMessage.Events);
			//clear out previous events
			_ownerMessage.Events.Clear();

			if (events.Count != 0) {
				//Send update to "owner" of this update request
				if (_source != null) {
					RtmpConnection connection = _source 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, currentVersion, persist);
					else
						syncOwner = new FlexSharedObjectMessage(null, _name, currentVersion, persist);
					syncOwner.AddEvents(events);

					if (channel != null) {
						channel.Write(syncOwner);
					} else {
						log.Warn(__Res.GetString(__Res.Channel_NotFound));
					}
				}
			}
			//Clear owner events
			events.Clear();
			//Get read-only version of sync events
			events.AddRange(_syncEvents);
			//Clear out previous events
			_syncEvents.Clear();
			if (events.Count != 0) {
				// Synchronize updates with all registered clients of this shared
				foreach (IEventListener listener in _listeners) {
					if (listener == _source) {
						// Don't re-send update to active client
						continue;
					}
					if (!(listener is RtmpConnection)) {
						log.Warn(__Res.GetString(__Res.SharedObject_SyncConnError));
						continue;
					}
					// Create a new sync message for every client to avoid
					// concurrent access through multiple threads
					// TODO: perhaps we could cache the generated message
					RtmpConnection connection = listener as RtmpConnection;
					SharedObjectMessage syncMessage;
					if (connection.ObjectEncoding == ObjectEncoding.AMF0)
						syncMessage = new SharedObjectMessage(null, _name, currentVersion, persist);
					else
						syncMessage = new FlexSharedObjectMessage(null, _name, currentVersion, persist);
					syncMessage.AddEvents(events);

					RtmpChannel channel = connection.GetChannel((byte)3);
					log.Debug(__Res.GetString(__Res.SharedObject_Sync, channel));
					channel.Write(syncMessage);
				}
			}
		}
Esempio n. 5
0
		static ISharedObjectMessage DecodeFlexSharedObject(ByteBuffer stream) {
			// Unknown byte, always 0?
			stream.Skip(1);
			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
			reader.ReadInt32();

			SharedObjectMessage so = new FlexSharedObjectMessage(null, name, version, persistent);
			DecodeSharedObject(so, stream, reader);
			return so;
		}
Esempio n. 6
0
		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);
		}
Esempio n. 7
0
		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);
		}