Example #1
0
		public ConnectionConsumer(RtmpConnection connection, int videoChannel, int audioChannel, int dataChannel) {
#if !SILVERLIGHT
			if (log.IsDebugEnabled)
				log.Debug(string.Format("Channel ids - video: {0} audio: {1} data: {2}", videoChannel, audioChannel, dataChannel));
#endif
			_connection = connection;
			_video = connection.GetChannel(videoChannel);
			_audio = connection.GetChannel(audioChannel);
			_data = connection.GetChannel(dataChannel);
			_timeStamper = new TimeStamper();
		}
Example #2
0
 public override void ConnectionOpened(RtmpConnection connection)
 {
     try
     {
         // Send "connect" call to the server
         RtmpChannel channel     = connection.GetChannel(3);
         PendingCall pendingCall = new PendingCall("connect", _connectArguments);
         Invoke      invoke      = new Invoke(pendingCall);
         invoke.ConnectionParameters = _connectionParameters;
         invoke.InvokeId             = connection.InvokeId;
         pendingCall.RegisterCallback(this);
         connection.RegisterPendingCall(invoke.InvokeId, pendingCall);
         channel.Write(invoke);
     }
     catch (Exception ex)
     {
         _netConnection.RaiseNetStatus(ex);
     }
 }
Example #3
0
 public override void ConnectionOpened(RtmpConnection connection)
 {
     try
     {
         RtmpChannel channel     = connection.GetChannel(3);
         PendingCall serviceCall = new PendingCall("connect", this._connectArguments);
         FluorineFx.Messaging.Rtmp.Event.Invoke message = new FluorineFx.Messaging.Rtmp.Event.Invoke(serviceCall)
         {
             ConnectionParameters = this._connectionParameters,
             InvokeId             = connection.InvokeId
         };
         serviceCall.RegisterCallback(this);
         connection.RegisterPendingCall(message.InvokeId, serviceCall);
         channel.Write(message);
     }
     catch (Exception exception)
     {
         this._netConnection.RaiseNetStatus(exception);
     }
 }
Example #4
0
        /// <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();
            }
        }
 protected override void OnFlexInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, FlexInvoke invoke)
 {
     OnInvoke(connection, channel, header, invoke);
 }
        protected override void OnInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, Notify invoke)
        {
            IServiceCall call = invoke.ServiceCall;

            if (invoke.EventType == EventType.STREAM_DATA)
            {
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(string.Format("Ignoring stream data notify with header {0}", header));
                }
#endif
                return;
            }

            if (call.ServiceMethodName == "_result" || call.ServiceMethodName == "_error")
            {
                if (call.ServiceMethodName == "_error")
                {
                    call.Status = Messaging.Rtmp.Service.Call.STATUS_INVOCATION_EXCEPTION;
                }
                if (call.ServiceMethodName == "_result")
                {
                    call.Status = Messaging.Rtmp.Service.Call.STATUS_SUCCESS_RESULT;
                }
                //Get the panding call, if any, as HandlePendingCallResult will remove it
                IPendingServiceCall pendingCall = connection.GetPendingCall(invoke.InvokeId);
                HandlePendingCallResult(connection, invoke);

                if (call.IsSuccess && invoke.InvokeId == 1)
                {
                    // Should keep this as an Object to stay compatible with FMS3 etc
                    IDictionary aso = call.Arguments[0] as IDictionary;
                    if (aso != null)
                    {
                        object clientId = null;
                        if (aso.Contains("clientid"))
                        {
                            clientId = aso["clientid"];
                        }
#if !SILVERLIGHT
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug(string.Format("Client id: {0}", clientId));
                        }
#endif
                        _netConnection.SetClientId(clientId != null ? clientId.ToString() : null);
                    }
                }

                //Notify via NetConnection if no IPendingServiceCallback was defined but the call failed
                if (call.ServiceMethodName == "_error")
                {
                    object[] args      = call.Arguments;
                    ASObject statusAso = null;
                    if ((args != null) && (args.Length > 0))
                    {
                        statusAso = args[0] as ASObject;
                    }
                    bool raiseError = false;
                    if (pendingCall != null)
                    {
                        IPendingServiceCallback[] callbacks = pendingCall.GetCallbacks();
                        if (callbacks == null || callbacks.Length == 0)
                        {
                            raiseError = true;
                        }
                    }
                    else
                    {
                        raiseError = true;
                    }
                    if (raiseError)
                    {
                        if (statusAso != null)
                        {
                            _netConnection.RaiseNetStatus(statusAso);
                        }
                        else
                        {
                            string msg = __Res.GetString(__Res.Invocation_Failed, pendingCall != null ? pendingCall.ServiceMethodName : string.Empty, "Invocation failed");
                            _netConnection.RaiseNetStatus(msg);
                        }
                    }
                }
                return;
            }

            bool onStatus = call.ServiceMethodName.Equals("onStatus") || call.ServiceMethodName.Equals("onMetaData") ||
                            call.ServiceMethodName.Equals("onPlayStatus");
            if (onStatus)
            {
                /*
                 * IDictionary aso = call.Arguments[0] as IDictionary;
                 * // Should keep this as an Object to stay compatible with FMS3 etc
                 * object clientId = null;
                 * if( aso.Contains("clientid") )
                 *  clientId = aso["clientid"];
                 * if (clientId == null)
                 *  clientId = header.StreamId;
                 #if !SILVERLIGHT
                 * if (log.IsDebugEnabled)
                 *  log.Debug(string.Format("Client id: {0}", clientId));
                 #endif
                 * if (clientId != null)
                 * {
                 *  NetStream stream = _connection.GetStreamById((int)clientId) as NetStream;
                 *  if (stream != null)
                 *  {
                 *      stream.OnStreamEvent(invoke);
                 *  }
                 * }
                 */
                NetStream stream = _connection.GetStreamById(header.StreamId) as NetStream;
                if (stream != null)
                {
                    stream.OnStreamEvent(invoke);
                }
                return;
            }

            if (call is IPendingServiceCall)
            {
                IPendingServiceCall psc = call as IPendingServiceCall;

                /*
                 * object result = psc.Result;
                 * object result = psc.Result;
                 * if (result is DeferredResult)
                 * {
                 *  DeferredResult dr = result as DeferredResult;
                 *  dr.InvokeId = invoke.InvokeId;
                 *  dr.ServiceCall = psc;
                 *  dr.Channel = channel;
                 *  connection.RegisterDeferredResult(dr);
                 * }
                 * else
                 * {
                 *  Invoke reply = new Invoke();
                 *  reply.ServiceCall = call;
                 *  reply.InvokeId = invoke.InvokeId;
                 *  channel.Write(reply);
                 * }
                 */
                MethodInfo mi = MethodHandler.GetMethod(_netConnection.Client.GetType(), call.ServiceMethodName, call.Arguments, false, false);
                if (mi != null)
                {
                    ParameterInfo[] parameterInfos = mi.GetParameters();
                    object[]        args           = new object[parameterInfos.Length];
                    call.Arguments.CopyTo(args, 0);
                    TypeHelper.NarrowValues(args, parameterInfos);
                    try
                    {
                        InvocationHandler invocationHandler = new InvocationHandler(mi);
                        object            result            = invocationHandler.Invoke(_netConnection.Client, args);
                        if (mi.ReturnType == typeof(void))
                        {
                            call.Status = Messaging.Rtmp.Service.Call.STATUS_SUCCESS_VOID;
                        }
                        else
                        {
                            call.Status = result == null ? Messaging.Rtmp.Service.Call.STATUS_SUCCESS_NULL : Messaging.Rtmp.Service.Call.STATUS_SUCCESS_RESULT;
                            psc.Result  = result;
                        }
                    }
                    catch (Exception exception)
                    {
                        call.Exception = exception;
                        call.Status    = Messaging.Rtmp.Service.Call.STATUS_INVOCATION_EXCEPTION;
                        //log.Error("Error while invoking method " + call.ServiceMethodName + " on client", exception);
                    }
                }
                else// if (!onStatus)
                {
                    string msg = __Res.GetString(__Res.Invocation_NoSuitableMethod, call.ServiceMethodName);
                    call.Status    = Messaging.Rtmp.Service.Call.STATUS_METHOD_NOT_FOUND;
                    call.Exception = new FluorineException(msg);
                    _netConnection.RaiseNetStatus(call.Exception);

                    //log.Error(msg, call.Exception);
                }
                if (call.Status == Messaging.Rtmp.Service.Call.STATUS_SUCCESS_VOID || call.Status == Messaging.Rtmp.Service.Call.STATUS_SUCCESS_NULL)
                {
#if !SILVERLIGHT
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug("Method does not have return value, do not reply");
                    }
#endif
                    return;
                }
                Invoke reply = new Invoke();
                reply.ServiceCall = call;
                reply.InvokeId    = invoke.InvokeId;
                channel.Write(reply);
            }
            else
            {
                IPendingServiceCall pendingCall = connection.RetrievePendingCall(invoke.InvokeId);
                Unreferenced.Parameter(pendingCall);
            }
        }
 protected override void OnServerBW(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ServerBW serverBw)
 {
 }
 protected override void OnChunkSize(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ChunkSize chunkSize)
 {
     //ChunkSize is not implemented yet
 }
Example #9
0
 /// <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="source"></param>
 /// <param name="clientBW"></param>
 protected abstract void OnClientBW(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ClientBW clientBW);
Example #10
0
 /// <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="invoke"></param>
 protected abstract void OnFlexInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, FlexInvoke invoke);
Example #11
0
 /// <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="invoke"></param>
 protected abstract void OnInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, Notify invoke);
Example #12
0
        public static RtmptRequest DecodeBuffer(RtmpConnection connection, ByteBuffer stream)
        {
            RtmpContext context  = connection.Context;
            int         position = (int)stream.Position;

            try {
                BufferStreamReader sr      = new BufferStreamReader(stream);
                string             request = sr.ReadLine();
                string[]           tokens  = request.Split(new char[] { ' ' });
                string             method  = tokens[0];
                string             url     = tokens[1];
                // Decode all encoded parts of the URL using the built in URI processing class
                int i = 0;
                while ((i = url.IndexOf("%", i)) != -1)
                {
                    url = url.Substring(0, i) + Uri.HexUnescape(url, ref i) + url.Substring(i);
                }
                // Lets just make sure we are using HTTP, thats about all I care about
                string protocol = tokens[2];                // "HTTP/"
                //Read headers
                Hashtable headers = new Hashtable();
                string    line;
                string    name = null;
                while ((line = sr.ReadLine()) != null && line != string.Empty)
                {
                    // If the value begins with a space or a hard tab then this
                    // is an extension of the value of the previous header and
                    // should be appended
                    if (name != null && Char.IsWhiteSpace(line[0]))
                    {
                        headers[name] += line;
                        continue;
                    }
                    // Headers consist of [NAME]: [VALUE] + possible extension lines
                    int firstColon = line.IndexOf(":");
                    if (firstColon != -1)
                    {
                        name = line.Substring(0, firstColon);
                        string value = line.Substring(firstColon + 1).Trim();
                        headers[name] = value;
                    }
                    else
                    {
                        //400, "Bad header: " + line
                        break;
                    }
                }
                RtmptRequest rtmptRequest = new RtmptRequest(connection, url, protocol, method, headers);
                if (stream.Remaining == rtmptRequest.ContentLength)
                {
                    stream.Compact();
                    rtmptRequest.Data = ByteBuffer.Wrap(stream.ToArray());
                    stream.Flip();
                    return(rtmptRequest);
                }
                else
                {
                    // Move the position back to the start
                    stream.Position = position;
                }
            } catch {
                // Move the position back to the start
                stream.Position = position;
                throw;
            }
            return(null);
        }
 private void SendNSFailed(RtmpConnection connection, string description, string name, int streamId)
 {
     StatusASO failed = new StatusASO(StatusASO.NS_FAILED);
     failed.clientid = streamId;
     failed.description = description;
     failed.details = name;
     failed.level = "error";
     // FIXME: there should be a direct way to send the status
     RtmpChannel channel = connection.GetChannel((byte)(4 + ((streamId - 1) * 5)));
     channel.SendStatus(failed);
 }
Example #14
0
 internal void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message)
 {
     RemoteSharedObject.Dispatch(message);
 }
Example #15
0
 public override void ConnectionClosed(RtmpConnection connection)
 {
     base.ConnectionClosed(connection);
     this._netConnection.RaiseDisconnect();
 }
Example #16
0
        protected override void OnInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, Notify invoke)
        {
            IServiceCall serviceCall = invoke.ServiceCall;

            if ((serviceCall.ServiceMethodName == "_result") || (serviceCall.ServiceMethodName == "_error"))
            {
                if (serviceCall.ServiceMethodName == "_error")
                {
                    serviceCall.Status = 0x13;
                }
                if (serviceCall.ServiceMethodName == "_result")
                {
                    serviceCall.Status = 2;
                }
                base.HandlePendingCallResult(connection, invoke);
            }
            else if (serviceCall is IPendingServiceCall)
            {
                IPendingServiceCall call2      = serviceCall as IPendingServiceCall;
                MethodInfo          methodInfo = MethodHandler.GetMethod(this._netConnection.Client.GetType(), serviceCall.ServiceMethodName, serviceCall.Arguments, false, false);
                if (methodInfo != null)
                {
                    ParameterInfo[] parameters = methodInfo.GetParameters();
                    object[]        array      = new object[parameters.Length];
                    serviceCall.Arguments.CopyTo(array, 0);
                    TypeHelper.NarrowValues(array, parameters);
                    try
                    {
                        object obj2 = new InvocationHandler(methodInfo).Invoke(this._netConnection.Client, array);
                        if (methodInfo.ReturnType == typeof(void))
                        {
                            serviceCall.Status = 4;
                        }
                        else
                        {
                            serviceCall.Status = (obj2 == null) ? ((byte)3) : ((byte)2);
                            call2.Result       = obj2;
                        }
                    }
                    catch (Exception exception)
                    {
                        serviceCall.Exception = exception;
                        serviceCall.Status    = 0x13;
                    }
                }
                else
                {
                    string message = __Res.GetString("Invocation_NoSuitableMethod", new object[] { serviceCall.ServiceMethodName });
                    serviceCall.Status    = 0x11;
                    serviceCall.Exception = new FluorineException(message);
                }
                if ((serviceCall.Status == 4) || (serviceCall.Status == 3))
                {
                    if (log.get_IsDebugEnabled())
                    {
                        log.Debug("Method does not have return value, do not reply");
                    }
                }
                else
                {
                    FluorineFx.Messaging.Rtmp.Event.Invoke invoke2 = new FluorineFx.Messaging.Rtmp.Event.Invoke {
                        ServiceCall = serviceCall,
                        InvokeId    = invoke.InvokeId
                    };
                    channel.Write(invoke2);
                }
            }
        }
Example #17
0
 /// <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="source"></param>
 /// <param name="ping"></param>
 protected abstract void OnPing(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, Ping ping);
Example #18
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);
                }
            }
        }
Example #19
0
 /// <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);
Example #20
0
 protected override void OnClientBW(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ClientBW clientBW)
 {
 }
Example #21
0
 /// <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="source"></param>
 /// <param name="serverBW"></param>
 protected abstract void OnServerBW(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ServerBW serverBW);
Example #22
0
        protected override void OnInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, Notify invoke)
        {
            IServiceCall serviceCall = invoke.ServiceCall;

            // If it's a callback for server remote call then pass it over to callbacks handler
            // and return
            if (serviceCall.ServiceMethodName.Equals("_result") || serviceCall.ServiceMethodName.Equals("_error"))
            {
                HandlePendingCallResult(connection, invoke);
                return;
            }

            bool   disconnectOnReturn = false;
            string action             = null;

            if (serviceCall.ServiceName == null)
            {
                action = serviceCall.ServiceMethodName;
                switch (action)
                {
                case ACTION_CONNECT:
                {
                    if (!connection.IsConnected)
                    {
                        IDictionary parameters = invoke.ConnectionParameters;
                        string      host       = null;
                        if (parameters.Contains("tcUrl"))
                        {
                            host = GetHostname(parameters["tcUrl"] as string);
                        }
                        if (host != null && host.IndexOf(":") != -1)
                        {
                            // Remove default port from connection string
                            host = host.Substring(0, host.IndexOf(":"));
                        }
                        string app  = parameters["app"] as string;
                        string path = parameters["app"] as string;
                        // App name as path, but without query string if there is one
                        if (path != null && path.IndexOf("?") != -1)
                        {
                            int idx = path.IndexOf("?");
                            parameters["queryString"] = path.Substring(idx);
                            path = path.Substring(0, idx);
                        }
                        parameters["path"] = path;

                        connection.Setup(host, path, parameters);
                        try
                        {
                            //IGlobalScope global = this.Endpoint.LookupGlobal(host, path);
                            IGlobalScope global = this.Endpoint.GetMessageBroker().GlobalScope;
                            if (global == null)
                            {
                                serviceCall.Status = Call.STATUS_SERVICE_NOT_FOUND;
                                if (serviceCall is IPendingServiceCall)
                                {
                                    StatusASO status = StatusASO.GetStatusObject(StatusASO.NC_CONNECT_INVALID_APPLICATION, connection.ObjectEncoding);
                                    status.description = "No global scope on this server.";
                                    (serviceCall as IPendingServiceCall).Result = status;
                                }
                                log.Info(string.Format("No application scope found for {0} on host {1}. Misspelled or missing application folder?", path, host));
                                disconnectOnReturn = true;
                            }
                            else
                            {
                                IScopeContext context = global.Context;
                                IScope        scope   = null;
                                try
                                {
                                    scope = context.ResolveScope(global, path);
                                }
                                catch (ScopeNotFoundException /*exception*/)
                                {
                                    if (log.IsErrorEnabled)
                                    {
                                        log.Error(__Res.GetString(__Res.Scope_NotFound, path));
                                    }

                                    serviceCall.Status = Call.STATUS_SERVICE_NOT_FOUND;
                                    if (serviceCall is IPendingServiceCall)
                                    {
                                        StatusASO status = StatusASO.GetStatusObject(StatusASO.NC_CONNECT_REJECTED, connection.ObjectEncoding);
                                        status.description = "No scope \"" + path + "\" on this server.";
                                        (serviceCall as IPendingServiceCall).Result = status;
                                    }
                                    disconnectOnReturn = true;
                                }
                                catch (ScopeShuttingDownException)
                                {
                                    serviceCall.Status = Call.STATUS_APP_SHUTTING_DOWN;
                                    if (serviceCall is IPendingServiceCall)
                                    {
                                        StatusASO status = StatusASO.GetStatusObject(StatusASO.NC_CONNECT_APPSHUTDOWN, connection.ObjectEncoding);
                                        status.description = "Application at \"" + path + "\" is currently shutting down.";
                                        (serviceCall as IPendingServiceCall).Result = status;
                                    }
                                    log.Info(string.Format("Application at {0} currently shutting down on {1}", path, host));
                                    disconnectOnReturn = true;
                                }
                                if (scope != null)
                                {
                                    if (log.IsInfoEnabled)
                                    {
                                        log.Info(__Res.GetString(__Res.Scope_Connect, scope.Name));
                                    }
                                    bool okayToConnect;
                                    try
                                    {
                                        //The only way to differentiate NetConnection.connect() and Consumer.subscribe() seems to be the app name
                                        if (app == string.Empty)
                                        {
                                            connection.SetIsFlexClient(true);
                                            okayToConnect = connection.Connect(scope, serviceCall.Arguments);
                                            if (okayToConnect)
                                            {
                                                if (serviceCall.Arguments != null && serviceCall.Arguments.Length >= 3)
                                                {
                                                    string credentials = serviceCall.Arguments[2] as string;
                                                    if (credentials != null && credentials != string.Empty)
                                                    {
                                                        MessageBroker         messageBroker         = this.Endpoint.GetMessageBroker();
                                                        AuthenticationService authenticationService = messageBroker.GetService(AuthenticationService.ServiceId) as AuthenticationService;
                                                        authenticationService.Authenticate(credentials);
                                                    }
                                                }
                                                //FDS 2.0.1 fds.swc
                                                if (serviceCall.Arguments != null && serviceCall.Arguments.Length == 1)
                                                {
                                                    string credentials = serviceCall.Arguments[0] as string;
                                                    if (credentials != null && credentials != string.Empty)
                                                    {
                                                        MessageBroker         messageBroker         = this.Endpoint.GetMessageBroker();
                                                        AuthenticationService authenticationService = messageBroker.GetService(AuthenticationService.ServiceId) as AuthenticationService;
                                                        authenticationService.Authenticate(credentials);
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            connection.SetIsFlexClient(false);
                                            okayToConnect = connection.Connect(scope, serviceCall.Arguments);
                                        }
                                        if (okayToConnect)
                                        {
                                            if (log.IsDebugEnabled)
                                            {
                                                log.Debug("Connected RtmpClient: " + connection.Client.Id);
                                            }
                                            serviceCall.Status = Call.STATUS_SUCCESS_RESULT;
                                            if (serviceCall is IPendingServiceCall)
                                            {
                                                StatusASO statusASO = StatusASO.GetStatusObject(StatusASO.NC_CONNECT_SUCCESS, connection.ObjectEncoding);
                                                statusASO.Add("id", connection.Client.Id);
                                                (serviceCall as IPendingServiceCall).Result = statusASO;
                                            }
                                            // Measure initial roundtrip time after connecting
                                            connection.GetChannel((byte)2).Write(new Ping(Ping.StreamBegin, 0, -1));
                                            connection.StartRoundTripMeasurement();
                                        }
                                        else
                                        {
                                            if (log.IsDebugEnabled)
                                            {
                                                log.Debug("Connect failed");
                                            }
                                            serviceCall.Status = Call.STATUS_ACCESS_DENIED;
                                            if (serviceCall is IPendingServiceCall)
                                            {
                                                (serviceCall as IPendingServiceCall).Result = StatusASO.GetStatusObject(StatusASO.NC_CONNECT_REJECTED, connection.ObjectEncoding);
                                            }
                                            disconnectOnReturn = true;
                                        }
                                    }
                                    catch (ClientRejectedException rejected)
                                    {
                                        if (log.IsDebugEnabled)
                                        {
                                            log.Debug("Connect rejected");
                                        }
                                        serviceCall.Status = Call.STATUS_ACCESS_DENIED;
                                        if (serviceCall is IPendingServiceCall)
                                        {
                                            StatusASO statusASO = StatusASO.GetStatusObject(StatusASO.NC_CONNECT_REJECTED, connection.ObjectEncoding);
                                            statusASO.Application = rejected.Reason;
                                            (serviceCall as IPendingServiceCall).Result = statusASO;
                                        }
                                        disconnectOnReturn = true;
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            if (log.IsErrorEnabled)
                            {
                                log.Error("Error connecting", ex);
                            }

                            serviceCall.Status = Call.STATUS_GENERAL_EXCEPTION;
                            if (serviceCall is IPendingServiceCall)
                            {
                                (serviceCall as IPendingServiceCall).Result = StatusASO.GetStatusObject(StatusASO.NC_CONNECT_FAILED, connection.ObjectEncoding);
                            }
                            disconnectOnReturn = true;
                        }
                    }
                    else
                    {
                        // Service calls, must be connected.
                        InvokeCall(connection, serviceCall);
                    }
                }
                break;

                case ACTION_DISCONNECT:
                    connection.Close();
                    break;

                case ACTION_CREATE_STREAM:
                case ACTION_DELETE_STREAM:
                case ACTION_RELEASE_STREAM:
                case ACTION_PUBLISH:
                case ACTION_PLAY:
                case ACTION_SEEK:
                case ACTION_PAUSE:
                case ACTION_CLOSE_STREAM:
                case ACTION_RECEIVE_VIDEO:
                case ACTION_RECEIVE_AUDIO:
                {
                    IStreamService streamService = ScopeUtils.GetScopeService(connection.Scope, typeof(IStreamService)) as IStreamService;
                    StatusASO      status        = null;
                    try
                    {
                        if (!InvokeCall(connection, serviceCall, streamService))
                        {
                            status             = StatusASO.GetStatusObject(StatusASO.NS_INVALID_ARGUMENT, connection.ObjectEncoding);
                            status.description = "Failed to " + action + " (stream ID: " + header.StreamId + ")";
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Error while invoking " + action + " on stream service.", ex);
                        status             = StatusASO.GetStatusObject(StatusASO.NS_FAILED, connection.ObjectEncoding);
                        status.description = "Error while invoking " + action + " (stream ID: " + header.StreamId + ")";
                        status.details     = ex.Message;
                    }
                    if (status != null)
                    {
                        channel.SendStatus(status);
                    }
                }
                break;

                default:
                    if (connection.IsConnected)
                    {
                        InvokeCall(connection, serviceCall);
                    }
                    else
                    {
                        // Warn user attemps to call service without being connected
                        if (log.IsWarnEnabled)
                        {
                            log.Warn("Not connected, closing connection");
                        }
                        connection.Close();
                    }
                    break;
                }
            }

            /*
             *          if(invoke is FlexInvoke)
             *          {
             *                  FlexInvoke reply = new FlexInvoke();
             *                  reply.InvokeId = invoke.InvokeId;
             *                  reply.SetResponseSuccess();
             *                  //TODO
             *                  if( serviceCall is IPendingServiceCall )
             *                  {
             *                          IPendingServiceCall pendingCall = (IPendingServiceCall)serviceCall;
             *                          reply.Response = pendingCall.Result;
             *                  }
             *                  channel.Write(reply);
             *          }
             *          else if(invoke is Invoke)
             */
            if (invoke is Invoke)
            {
                if ((header.StreamId != 0) &&
                    (serviceCall.Status == Call.STATUS_SUCCESS_VOID || serviceCall.Status == Call.STATUS_SUCCESS_NULL))
                {
                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Method does not have return value, do not reply");
                    }
                    return;
                }

                // The client expects a result for the method call.
                Invoke reply = new Invoke();
                reply.ServiceCall = serviceCall;
                reply.InvokeId    = invoke.InvokeId;
                //sending reply
                channel.Write(reply);
            }
            if (disconnectOnReturn)
            {
                connection.Close();
            }
            if (action == ACTION_CONNECT)
            {
                connection.Context.ObjectEncoding = connection.ObjectEncoding;
            }
        }
Example #23
0
 internal RtmpChannel(RtmpConnection connection, int channelId)
 {
     _connection = connection;
     _channelId  = channelId;
 }
Example #24
0
 /// <summary>
 /// Connection open event.
 /// </summary>
 /// <param name="connection">Connection object.</param>
 public virtual void ConnectionOpened(RtmpConnection connection)
 {
 }
        protected override void OnPing(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, Ping ping)
        {
            switch (ping.PingType)
            {
            case Ping.PingClient:
            case Ping.StreamBegin:
            case Ping.RecordedStream:
            case Ping.StreamPlayBufferClear:
                // The server wants to measure the RTT
                Ping pong = new Ping();
                pong.PingType = Ping.PongServer;
                // The event data is a 4-byte timestamp, which was received with the in the Ping request
                pong.Value2 = ping.Value2;
                connection.Ping(pong);
                break;

            case Ping.StreamDry:
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("Stream indicates there is no data available");
                }
#endif
                break;

            case Ping.ClientBuffer:
                //Set the client buffer
                IClientStream stream = null;
                //Get the stream id
                int streamId = ping.Value2;
                //Get requested buffer size in milliseconds
                int buffer = ping.Value3;
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(string.Format("Client sent a buffer size: {0} ms for stream id: {1}", buffer, streamId));
                }
#endif
                if (streamId != 0)
                {
                    // The client wants to set the buffer time
                    stream = connection.GetStreamById(streamId);
                    if (stream != null)
                    {
                        stream.SetClientBufferDuration(buffer);
#if !SILVERLIGHT
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug(string.Format("Setting client buffer on stream: {0}", streamId));
                        }
#endif
                    }
                }
                //Catch-all to make sure buffer size is set
                if (stream == null)
                {
                    // Remember buffer time until stream is created
                    connection.RememberStreamBufferDuration(streamId, buffer);
#if !SILVERLIGHT
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug(string.Format("Remembering client buffer on stream: {0}", streamId));
                    }
#endif
                }
                break;

            default:
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(string.Format("Unhandled ping: {0}", ping));
                }
#endif
                break;
            }
        }
Example #26
0
        /// <summary>
        /// Message recieved.
        /// </summary>
        /// <param name="connection">Connection object.</param>
        /// <param name="obj">Message object.</param>
        public void MessageReceived(RtmpConnection connection, object obj)
        {
            IRtmpEvent    message = null;
            RtmpPacket    packet  = null;
            RtmpHeader    header  = null;
            RtmpChannel   channel = null;
            IClientStream stream  = null;

            try {
                packet  = obj as RtmpPacket;
                message = packet.Message;
                header  = packet.Header;
                channel = connection.GetChannel(header.ChannelId);
                if (connection is IStreamCapableConnection)
                {
                    stream = (connection as IStreamCapableConnection).GetStreamById(header.StreamId);
                }

                // Support stream ids
#if !SILVERLIGHT
                FluorineContext.ValidateContext();
                FluorineContext.Current.Connection.SetAttribute(FluorineContext.FluorineStreamIdKey, header.StreamId);
#endif
                // Increase number of received messages
                connection.MessageReceived();

#if !SILVERLIGHT
                if (log != null && log.IsDebugEnabled)
                {
                    log.Debug("RtmpConnection message received, type = " + header.DataType);
                }
#endif

                if (message != null)
                {
                    message.Source = connection;
                }

                switch (header.DataType)
                {
                case Constants.TypeInvoke:
                    OnInvoke(connection, channel, header, message as Invoke);
                    if (message.Header.StreamId != 0 &&
                        (message as Invoke).ServiceCall.ServiceName == null &&
                        (message as Invoke).ServiceCall.ServiceMethodName == BaseRtmpHandler.ACTION_PUBLISH)
                    {
                        if (stream != null)                                 //Dispatch if stream was created
                        {
                            (stream as IEventDispatcher).DispatchEvent(message);
                        }
                    }
                    break;

                case Constants.TypeFlexInvoke:
                    OnFlexInvoke(connection, channel, header, message as FlexInvoke);
                    if (message.Header.StreamId != 0 &&
                        (message as Invoke).ServiceCall.ServiceName == null &&
                        (message as Invoke).ServiceCall.ServiceMethodName == BaseRtmpHandler.ACTION_PUBLISH)
                    {
                        if (stream != null)                                 //Dispatch if stream was created
                        {
                            (stream as IEventDispatcher).DispatchEvent(message);
                        }
                    }
                    break;

                case Constants.TypeNotify:                        // just like invoke, but does not return
                    if ((message as Notify).Data != null && stream != null)
                    {
                        // Stream metadata
                        (stream as IEventDispatcher).DispatchEvent(message);
                    }
                    else
                    {
                        OnInvoke(connection, channel, header, message as Notify);
                    }
                    break;

                case Constants.TypePing:
                    OnPing(connection, channel, header, message as Ping);
                    break;

                case Constants.TypeBytesRead:
                    OnStreamBytesRead(connection, channel, header, message as BytesRead);
                    break;

                case Constants.TypeSharedObject:
                case Constants.TypeFlexSharedObject:
                    OnSharedObject(connection, channel, header, message as SharedObjectMessage);
                    break;

                case Constants.TypeFlexStreamEnd:
                    if (stream != null)
                    {
                        (stream as IEventDispatcher).DispatchEvent(message);
                    }
                    break;

                case Constants.TypeChunkSize:
                    OnChunkSize(connection, channel, header, message as ChunkSize);
                    break;

                case Constants.TypeAudioData:
                case Constants.TypeVideoData:
                    // NOTE: If we respond to "publish" with "NetStream.Publish.BadName",
                    // the client sends a few stream packets before stopping. We need to
                    // ignore them.
                    if (stream != null)
                    {
                        ((IEventDispatcher)stream).DispatchEvent(message);
                    }
                    break;

                case Constants.TypeServerBandwidth:
                    OnServerBW(connection, channel, header, message as ServerBW);
                    break;

                case Constants.TypeClientBandwidth:
                    OnClientBW(connection, channel, header, message as ClientBW);
                    break;

                default:
#if !SILVERLIGHT
                    if (log != null && log.IsDebugEnabled)
                    {
                        log.Debug("RtmpService event not handled: " + header.DataType);
                    }
#endif
                    break;
                }
            } catch (Exception ex) {
#if !SILVERLIGHT
                if (log.IsErrorEnabled)
                {
                    log.Error(__Res.GetString(__Res.Rtmp_HandlerError), ex);
                    log.Error(__Res.GetString(__Res.Error_ContextDump));
                    //log.Error(Environment.NewLine);
                    log.Error(packet);
                }
#endif
            }
        }
 protected override void OnClientBW(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ClientBW clientBw)
 {
     channel.Write(new ServerBW(clientBw.Bandwidth));
 }
Example #28
0
 /// <summary>
 /// Connection closed.
 /// </summary>
 /// <param name="connection">Connection object.</param>
 public virtual void ConnectionClosed(RtmpConnection connection)
 {
     connection.Close();
 }
 protected override void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message)
 {
     _netConnection.OnSharedObject(connection, channel, header, message);
 }
Example #30
0
 /// <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="source"></param>
 /// <param name="streamBytesRead"></param>
 protected void OnStreamBytesRead(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, BytesRead streamBytesRead)
 {
     connection.ReceivedBytesRead(streamBytesRead.Bytes);
 }
 public override void ConnectionClosed(RtmpConnection connection)
 {
     base.ConnectionClosed(connection);
     _netConnection.RaiseNetStatus(StatusASO.GetStatusObject(StatusASO.NC_CONNECT_CLOSED, _netConnection.ObjectEncoding));
     _netConnection.RaiseDisconnect();
 }
Example #32
0
 /// <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="source"></param>
 /// <param name="chunkSize"></param>
 protected abstract void OnChunkSize(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ChunkSize chunkSize);