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); } }
public CreateStreamCallBack(NetStream stream, RtmpConnection connection, IPendingServiceCallback callback) { ValidationUtils.ArgumentNotNull(connection, "connection"); _stream = stream; _connection = connection; _callback = callback; }