Inheritance: FluorineFx.Messaging.Rtmp.Stream.AbstractClientStream, IPendingServiceCallback, IEventDispatcher, INetStreamEventHandler
        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);
            }
        }
Exemple #2
0
 public CreateStreamCallBack(NetStream stream, RtmpConnection connection, IPendingServiceCallback callback)
 {
     ValidationUtils.ArgumentNotNull(connection, "connection");
     _stream = stream;
     _connection = connection;
     _callback = callback;
 }