Beispiel #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;

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

                // clear collections
                base.RemoveAttributes();
                _ownerMessage.Events.Clear();
            }
            _initialSyncReceived = false;
        }
Beispiel #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);
				}
			}
		}
		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;
		}
Beispiel #5
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);
 }
Beispiel #6
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);
 }
Beispiel #7
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);
                }
            }
        }