public void OnStreamEvent(Notify notify) { bool onStatus = notify.ServiceCall.ServiceMethodName.Equals("onStatus"); if (!onStatus) { if (notify.ServiceCall.ServiceMethodName.Equals("onMetaData")) { RaiseOnMetaData(notify.ServiceCall.Arguments[0] as IDictionary); } if (notify.ServiceCall.ServiceMethodName.Equals("onPlayStatus")) { RaiseOnPlayStatus(notify.ServiceCall.Arguments[0] as IDictionary); } MethodInfo mi = MethodHandler.GetMethod(_client.GetType(), notify.ServiceCall.ServiceMethodName, notify.ServiceCall.Arguments, false, false); if (mi != null) { ParameterInfo[] parameterInfos = mi.GetParameters(); object[] args = new object[parameterInfos.Length]; notify.ServiceCall.Arguments.CopyTo(args, 0); TypeHelper.NarrowValues(args, parameterInfos); try { InvocationHandler invocationHandler = new InvocationHandler(mi); object result = invocationHandler.Invoke(_client, args); } catch (Exception exception) { notify.ServiceCall.Exception = exception; notify.ServiceCall.Status = FluorineFx.Messaging.Rtmp.Service.Call.STATUS_INVOCATION_EXCEPTION; //log.Error("Error while invoking method " + call.ServiceMethodName + " on client", exception); } } else { string msg = __Res.GetString(__Res.Invocation_NoSuitableMethod, notify.ServiceCall.ServiceMethodName, _client.GetType().Name); this.RaiseNetStatus(new FluorineException(msg)); } } else { object[] args = notify.ServiceCall.Arguments; ASObject statusASO = null; if ((args != null) && (args.Length > 0)) { statusASO = args[0] as ASObject; } this.RaiseNetStatus(statusASO); } }
public void SendMessage(string handler, IList arguments) { BeginUpdate(); try { _so.SendMessage(handler, arguments); } finally { EndUpdate(); } // Invoke method on registered handler string serviceName, serviceMethod; int dotPos = handler.LastIndexOf("."); if (dotPos != -1) { serviceName = handler.Substring(0, dotPos); serviceMethod = handler.Substring(dotPos + 1); } else { serviceName = string.Empty; serviceMethod = handler; } object soHandler = GetServiceHandler(serviceName); if (soHandler == null && this.HasParent) { // No custom handler, check for service defined in the scope's context IScopeContext context = this.Parent.Context; try { //Search for a handler only if there is a service name specified if (serviceName != string.Empty) { // The type must have a name of "SharedObjectName.DottedServiceName" soHandler = ObjectFactory.CreateInstance(_so.Name + "." + serviceName); } } catch (Exception) { // No such type. log.Debug(__Res.GetString(__Res.Type_InitError, _so.Name + "." + serviceName)); } } if (soHandler != null) { MethodInfo mi = MethodHandler.GetMethod(soHandler.GetType(), serviceMethod, arguments); if (mi != null) { ParameterInfo[] parameterInfos = mi.GetParameters(); object[] args = new object[parameterInfos.Length]; arguments.CopyTo(args, 0); TypeHelper.NarrowValues(args, parameterInfos); try { InvocationHandler invocationHandler = new InvocationHandler(mi); object result = invocationHandler.Invoke(soHandler, args); } catch (Exception exception) { log.Error(__Res.GetString(__Res.ServiceHandler_InvocationFailed, serviceMethod, handler), exception); } } } // Notify server listeners foreach (ISharedObjectListener listener in _serverListeners) { listener.OnSharedObjectSend(this, handler, arguments); } }
public override void Invoke(AMFContext context) { MessageOutput messageOutput = context.MessageOutput; for (int i = 0; i < context.AMFMessage.BodyCount; i++) { AMFBody amfBody = context.AMFMessage.GetBodyAt(i); ResponseBody responseBody = null; //Check for Flex2 messages and skip if (amfBody.IsEmptyTarget) { continue; } if (amfBody.IsDebug) { continue; } if (amfBody.IsDescribeService) { responseBody = new ResponseBody(); responseBody.IgnoreResults = amfBody.IgnoreResults; responseBody.Target = amfBody.Response + AMFBody.OnResult; responseBody.Response = null; DescribeService describeService = new DescribeService(amfBody); responseBody.Content = describeService.GetDescription(); messageOutput.AddBody(responseBody); continue; } //Check if response exists. responseBody = messageOutput.GetResponse(amfBody); if (responseBody != null) { continue; } try { MessageBroker messageBroker = _endpoint.GetMessageBroker(); RemotingService remotingService = messageBroker.GetService(RemotingService.RemotingServiceId) as RemotingService; if (remotingService == null) { string serviceNotFound = __Res.GetString(__Res.Service_NotFound, RemotingService.RemotingServiceId); responseBody = new ErrorResponseBody(amfBody, new FluorineException(serviceNotFound)); messageOutput.AddBody(responseBody); if (log.IsErrorEnabled) { log.Error(serviceNotFound); } continue; } Destination destination = null; if (destination == null) { destination = remotingService.GetDestinationWithSource(amfBody.TypeName); } if (destination == null) { destination = remotingService.DefaultDestination; } //At this moment we got a destination with the exact source or we have a default destination with the "*" source. if (destination == null) { string destinationNotFound = __Res.GetString(__Res.Destination_NotFound, amfBody.TypeName); responseBody = new ErrorResponseBody(amfBody, new FluorineException(destinationNotFound)); messageOutput.AddBody(responseBody); if (log.IsErrorEnabled) { log.Error(destinationNotFound); } continue; } try { remotingService.CheckSecurity(destination); } catch (UnauthorizedAccessException exception) { responseBody = new ErrorResponseBody(amfBody, exception); if (log.IsDebugEnabled) { log.Debug(exception.Message); } continue; } //Cache check string source = amfBody.TypeName + "." + amfBody.Method; IList parameterList = amfBody.GetParameterList(); string key = FluorineFx.Configuration.CacheMap.GenerateCacheKey(source, parameterList); if (FluorineConfiguration.Instance.CacheMap.ContainsValue(key)) { object result = FluorineFx.Configuration.FluorineConfiguration.Instance.CacheMap.Get(key); if (result != null) { if (log != null && log.IsDebugEnabled) { log.Debug(__Res.GetString(__Res.Cache_HitKey, source, key)); } responseBody = new ResponseBody(amfBody, result); messageOutput.AddBody(responseBody); continue; } } object instance; FactoryInstance factoryInstance = destination.GetFactoryInstance(); lock (factoryInstance) { factoryInstance.Source = amfBody.TypeName; if (FluorineContext.Current.ActivationMode != null)//query string can override the activation mode { factoryInstance.Scope = FluorineContext.Current.ActivationMode; } instance = factoryInstance.Lookup(); } if (instance != null) { try { bool isAccessible = TypeHelper.GetTypeIsAccessible(instance.GetType()); if (!isAccessible) { string msg = __Res.GetString(__Res.Type_InitError, amfBody.TypeName); if (log.IsErrorEnabled) { log.Error(msg); } responseBody = new ErrorResponseBody(amfBody, new FluorineException(msg)); messageOutput.AddBody(responseBody); continue; } MethodInfo mi = null; if (!amfBody.IsRecordsetDelivery) { mi = MethodHandler.GetMethod(instance.GetType(), amfBody.Method, parameterList); } else { //will receive recordsetid only (ignore) mi = instance.GetType().GetMethod(amfBody.Method); } if (mi != null) { object[] roleAttributes = mi.GetCustomAttributes(typeof(RoleAttribute), true); if (roleAttributes != null && roleAttributes.Length == 1) { RoleAttribute roleAttribute = roleAttributes[0] as RoleAttribute; string[] roles = roleAttribute.Roles.Split(','); bool authorized = messageBroker.LoginManager.DoAuthorization(roles); if (!authorized) { throw new UnauthorizedAccessException(__Res.GetString(__Res.Security_AccessNotAllowed)); } } #region Invocation handling PageSizeAttribute pageSizeAttribute = null; MethodInfo miCounter = null; object[] pageSizeAttributes = mi.GetCustomAttributes(typeof(PageSizeAttribute), true); if (pageSizeAttributes != null && pageSizeAttributes.Length == 1) { pageSizeAttribute = pageSizeAttributes[0] as PageSizeAttribute; miCounter = instance.GetType().GetMethod(amfBody.Method + "Count"); if (miCounter != null && miCounter.ReturnType != typeof(System.Int32)) { miCounter = null; //check signature } } ParameterInfo[] parameterInfos = mi.GetParameters(); //Try to handle missing/optional parameters. object[] args = new object[parameterInfos.Length]; if (!amfBody.IsRecordsetDelivery) { if (args.Length != parameterList.Count) { string msg = __Res.GetString(__Res.Arg_Mismatch, parameterList.Count, mi.Name, args.Length); if (log != null && log.IsErrorEnabled) { log.Error(msg); } responseBody = new ErrorResponseBody(amfBody, new ArgumentException(msg)); messageOutput.AddBody(responseBody); continue; } parameterList.CopyTo(args, 0); if (pageSizeAttribute != null) { PagingContext pagingContext = new PagingContext(pageSizeAttribute.Offset, pageSizeAttribute.Limit); PagingContext.SetPagingContext(pagingContext); } } else { if (amfBody.Target.EndsWith(".release")) { responseBody = new ResponseBody(amfBody, null); messageOutput.AddBody(responseBody); continue; } string recordsetId = parameterList[0] as string; string recordetDeliveryParameters = amfBody.GetRecordsetArgs(); byte[] buffer = System.Convert.FromBase64String(recordetDeliveryParameters); recordetDeliveryParameters = System.Text.Encoding.UTF8.GetString(buffer); if (recordetDeliveryParameters != null && recordetDeliveryParameters != string.Empty) { string[] stringParameters = recordetDeliveryParameters.Split(new char[] { ',' }); for (int j = 0; j < stringParameters.Length; j++) { if (stringParameters[j] == string.Empty) { args[j] = null; } else { args[j] = stringParameters[j]; } } //TypeHelper.NarrowValues(argsStore, parameterInfos); } PagingContext pagingContext = new PagingContext(System.Convert.ToInt32(parameterList[1]), System.Convert.ToInt32(parameterList[2])); PagingContext.SetPagingContext(pagingContext); } TypeHelper.NarrowValues(args, parameterInfos); try { InvocationHandler invocationHandler = new InvocationHandler(mi); object result = invocationHandler.Invoke(instance, args); if (FluorineConfiguration.Instance.CacheMap != null && FluorineConfiguration.Instance.CacheMap.ContainsCacheDescriptor(source)) { //The result should be cached CacheableObject cacheableObject = new CacheableObject(source, key, result); FluorineConfiguration.Instance.CacheMap.Add(cacheableObject.Source, cacheableObject.CacheKey, cacheableObject); result = cacheableObject; } responseBody = new ResponseBody(amfBody, result); if (pageSizeAttribute != null) { int totalCount = 0; string recordsetId = null; IList list = amfBody.GetParameterList(); string recordetDeliveryParameters = null; if (!amfBody.IsRecordsetDelivery) { //fist call paging object[] argsStore = new object[list.Count]; list.CopyTo(argsStore, 0); recordsetId = System.Guid.NewGuid().ToString(); if (miCounter != null) { //object[] counterArgs = new object[0]; totalCount = (int)miCounter.Invoke(instance, args); } string[] stringParameters = new string[argsStore.Length]; for (int j = 0; j < argsStore.Length; j++) { if (argsStore[j] != null) { stringParameters[j] = argsStore[j].ToString(); } else { stringParameters[j] = string.Empty; } } recordetDeliveryParameters = string.Join(",", stringParameters); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(recordetDeliveryParameters); recordetDeliveryParameters = System.Convert.ToBase64String(buffer); } else { recordsetId = amfBody.GetParameterList()[0] as string; } if (result is DataTable) { DataTable dataTable = result as DataTable; dataTable.ExtendedProperties["TotalCount"] = totalCount; dataTable.ExtendedProperties["Service"] = recordetDeliveryParameters + "/" + amfBody.Target; dataTable.ExtendedProperties["RecordsetId"] = recordsetId; if (amfBody.IsRecordsetDelivery) { dataTable.ExtendedProperties["Cursor"] = Convert.ToInt32(list[list.Count - 2]); dataTable.ExtendedProperties["DynamicPage"] = true; } } } } catch (UnauthorizedAccessException exception) { responseBody = new ErrorResponseBody(amfBody, exception); if (log.IsDebugEnabled) { log.Debug(exception.Message); } } catch (Exception exception) { if (exception is TargetInvocationException && exception.InnerException != null) { responseBody = new ErrorResponseBody(amfBody, exception.InnerException); } else { responseBody = new ErrorResponseBody(amfBody, exception); } if (log.IsDebugEnabled) { log.Debug(__Res.GetString(__Res.Invocation_Failed, mi.Name, exception.Message)); } } #endregion Invocation handling } else { responseBody = new ErrorResponseBody(amfBody, new MissingMethodException(amfBody.TypeName, amfBody.Method)); } } finally { factoryInstance.OnOperationComplete(instance); } } else { responseBody = new ErrorResponseBody(amfBody, new TypeInitializationException(amfBody.TypeName, null)); } } catch (Exception exception) { if (log != null && log.IsErrorEnabled) { log.Error(exception.Message + String.Format(" (Type: {0}, Method: {1})", amfBody.TypeName, amfBody.Method), exception); } responseBody = new ErrorResponseBody(amfBody, exception); } messageOutput.AddBody(responseBody); } }
public bool Invoke(IServiceCall call, object service) { string serviceMethod = call.ServiceMethodName; object[] arguments = call.Arguments; // First, search for method with exact parameter type match MethodInfo mi = MethodHandler.GetMethod(service.GetType(), serviceMethod, arguments, true, false, false); if (mi == null) { // Second, search for method with type conversions // This second call will trace 'suitable method' errors too mi = MethodHandler.GetMethod(service.GetType(), serviceMethod, arguments, false, false, true); if (mi == null) { string msg = __Res.GetString(__Res.Invocation_NoSuitableMethod, serviceMethod); call.Status = Call.STATUS_METHOD_NOT_FOUND; call.Exception = new FluorineException(msg); return(false); } } try { ParameterInfo[] parameterInfos = mi.GetParameters(); object[] parameters = new object[parameterInfos.Length]; arguments.CopyTo(parameters, 0); TypeHelper.NarrowValues(parameters, parameterInfos); object result = null; if (mi.ReturnType == typeof(void)) { InvocationHandler invocationHandler = new InvocationHandler(mi); invocationHandler.Invoke(service, parameters); call.Status = Call.STATUS_SUCCESS_VOID; } else { InvocationHandler invocationHandler = new InvocationHandler(mi); result = invocationHandler.Invoke(service, parameters); call.Status = result == null ? Call.STATUS_SUCCESS_NULL : Call.STATUS_SUCCESS_RESULT; } if (call is IPendingServiceCall) { (call as IPendingServiceCall).Result = result; } } catch (SecurityException exception) { call.Exception = exception; call.Status = Call.STATUS_ACCESS_DENIED; if (log.IsDebugEnabled) { log.Debug(exception.Message); } return(false); } catch (UnauthorizedAccessException exception) { call.Exception = exception; call.Status = Call.STATUS_ACCESS_DENIED; if (log.IsDebugEnabled) { log.Debug(exception.Message); } return(false); } catch (TargetInvocationException exception) { call.Exception = exception.InnerException; call.Status = Call.STATUS_INVOCATION_EXCEPTION; if (log.IsDebugEnabled) { log.Debug(__Res.GetString(__Res.Invocation_Failed, mi.Name, exception.InnerException.Message)); } return(false); } catch (Exception exception) { call.Exception = exception; call.Status = Call.STATUS_GENERAL_EXCEPTION; if (log.IsDebugEnabled) { log.Debug(__Res.GetString(__Res.Invocation_Failed, mi.Name, exception.Message)); } return(false); } return(true); }
public override Task Invoke(AMFContext context) { MessageOutput messageOutput = context.MessageOutput; for (int i = 0; i < context.AMFMessage.BodyCount; i++) { AMFBody amfBody = context.AMFMessage.GetBodyAt(i); ResponseBody responseBody = null; //Check for Flex2 messages and skip if (amfBody.IsEmptyTarget) { continue; } //Check if response exists. responseBody = messageOutput.GetResponse(amfBody); if (responseBody != null) { continue; } try { MessageBroker messageBroker = _endpoint.GetMessageBroker(); RemotingService remotingService = messageBroker.GetService(RemotingService.RemotingServiceId) as RemotingService; if (remotingService == null) { string serviceNotFound = __Res.GetString(__Res.Service_NotFound, RemotingService.RemotingServiceId); responseBody = new ErrorResponseBody(amfBody, new AMFException(serviceNotFound)); messageOutput.AddBody(responseBody); continue; } Destination destination = null; if (destination == null) { destination = remotingService.GetDestinationWithSource(amfBody.TypeName); } if (destination == null) { destination = remotingService.DefaultDestination; } //At this moment we got a destination with the exact source or we have a default destination with the "*" source. if (destination == null) { string destinationNotFound = __Res.GetString(__Res.Destination_NotFound, amfBody.TypeName); responseBody = new ErrorResponseBody(amfBody, new AMFException(destinationNotFound)); messageOutput.AddBody(responseBody); continue; } //Cache check string source = amfBody.TypeName + "." + amfBody.Method; IList parameterList = amfBody.GetParameterList(); FactoryInstance factoryInstance = destination.GetFactoryInstance(); factoryInstance.Source = amfBody.TypeName; object instance = factoryInstance.Lookup(); if (instance != null) { bool isAccessible = TypeHelper.GetTypeIsAccessible(instance.GetType()); if (!isAccessible) { string msg = __Res.GetString(__Res.Type_InitError, amfBody.TypeName); responseBody = new ErrorResponseBody(amfBody, new AMFException(msg)); messageOutput.AddBody(responseBody); continue; } MethodInfo mi = null; if (!amfBody.IsRecordsetDelivery) { mi = MethodHandler.GetMethod(instance.GetType(), amfBody.Method, amfBody.GetParameterList()); } else { //will receive recordsetid only (ignore) mi = instance.GetType().GetMethod(amfBody.Method); } if (mi != null) { #region Invocation handling ParameterInfo[] parameterInfos = mi.GetParameters(); //Try to handle missing/optional parameters. object[] args = new object[parameterInfos.Length]; if (!amfBody.IsRecordsetDelivery) { if (args.Length != parameterList.Count) { string msg = __Res.GetString(__Res.Arg_Mismatch, parameterList.Count, mi.Name, args.Length); responseBody = new ErrorResponseBody(amfBody, new ArgumentException(msg)); messageOutput.AddBody(responseBody); continue; } parameterList.CopyTo(args, 0); } else { if (amfBody.Target.EndsWith(".release")) { responseBody = new ResponseBody(amfBody, null); messageOutput.AddBody(responseBody); continue; } string recordsetId = parameterList[0] as string; string recordetDeliveryParameters = amfBody.GetRecordsetArgs(); byte[] buffer = System.Convert.FromBase64String(recordetDeliveryParameters); recordetDeliveryParameters = System.Text.Encoding.UTF8.GetString(buffer); if (recordetDeliveryParameters != null && recordetDeliveryParameters != string.Empty) { string[] stringParameters = recordetDeliveryParameters.Split(new char[] { ',' }); for (int j = 0; j < stringParameters.Length; j++) { if (stringParameters[j] == string.Empty) { args[j] = null; } else { args[j] = stringParameters[j]; } } //TypeHelper.NarrowValues(argsStore, parameterInfos); } } TypeHelper.NarrowValues(args, parameterInfos); try { InvocationHandler invocationHandler = new InvocationHandler(mi); object result = invocationHandler.Invoke(instance, args); responseBody = new ResponseBody(amfBody, result); } catch (UnauthorizedAccessException exception) { responseBody = new ErrorResponseBody(amfBody, exception); } catch (Exception exception) { if (exception is TargetInvocationException && exception.InnerException != null) { responseBody = new ErrorResponseBody(amfBody, exception.InnerException); } else { responseBody = new ErrorResponseBody(amfBody, exception); } } #endregion Invocation handling } else { responseBody = new ErrorResponseBody(amfBody, new MissingMethodException(amfBody.TypeName, amfBody.Method)); } } else { responseBody = new ErrorResponseBody(amfBody, new TypeInitializationException(amfBody.TypeName, null)); } } catch (Exception exception) { responseBody = new ErrorResponseBody(amfBody, exception); } messageOutput.AddBody(responseBody); } return(Task.FromResult <object>(null)); }
public override object Invoke(IMessage message) { object result = null; RemotingMessage remotingMessage = message as RemotingMessage; string operation = remotingMessage.operation; string className = this.DestinationDefinition.Properties.Source; //This property is provided for backwards compatibility. The best practice, however, is to not expose the underlying source of a //RemoteObject destination on the client and only one source to a destination. if (remotingMessage.source != null && remotingMessage.source != string.Empty) { if (className == "*") { className = remotingMessage.source; } if (className != remotingMessage.source) { string msg = __Res.GetString(__Res.Type_MismatchMissingSource, remotingMessage.source, this.DestinationDefinition.Properties.Source as string); throw new MessageException(msg, new TypeLoadException(msg)); } } if (className == null) { throw new TypeInitializationException("null", null); } //Service mapping obsolete for Flex Remoting /* * if (FluorineConfiguration.Instance.ServiceMap != null) * { * string method = remotingMessage.operation; * if (FluorineConfiguration.Instance.ServiceMap.Contains(className)) * { * string serviceLocation = FluorineConfiguration.Instance.ServiceMap.GetServiceLocation(className); * method = FluorineConfiguration.Instance.ServiceMap.GetMethod(className, method); * if (log != null && log.IsDebugEnabled) * log.Debug(__Res.GetString(__Res.Service_Mapping, className + "." + remotingMessage.operation, serviceLocation + "." + method)); * * className = serviceLocation; * remotingMessage.operation = method; * } * } */ //Cache check string source = className + "." + operation; IList parameterList = remotingMessage.body as IList; string key = dotFlex.Configuration.CacheMap.GenerateCacheKey(source, parameterList); if (FluorineConfiguration.Instance.CacheMap.ContainsValue(key)) { result = dotFlex.Configuration.FluorineConfiguration.Instance.CacheMap.Get(key); if (result != null) { if (log != null && log.IsDebugEnabled) { log.Debug(__Res.GetString(__Res.Cache_HitKey, operation, key)); } return(result); } } FactoryInstance factoryInstance = this.Destination.GetFactoryInstance(); factoryInstance.Source = className; object instance = factoryInstance.Lookup(); if (instance != null) { try { Type type = instance.GetType(); bool isAccessible = TypeHelper.GetTypeIsAccessible(type); if (!isAccessible) { string msg = __Res.GetString(__Res.Type_InitError, type.FullName); throw new MessageException(msg, new TypeLoadException(msg)); } MethodInfo mi = MethodHandler.GetMethod(type, operation, parameterList); if (mi != null) { try { //Messagebroker checked xml configured security, check attributes too object[] roleAttributes = mi.GetCustomAttributes(typeof(RoleAttribute), true); if (roleAttributes != null && roleAttributes.Length == 1) { RoleAttribute roleAttribute = roleAttributes[0] as RoleAttribute; string[] roles = roleAttribute.Roles.Split(','); bool authorized = this.Destination.Service.GetMessageBroker().LoginManager.DoAuthorization(roles); if (!authorized) { throw new UnauthorizedAccessException(__Res.GetString(__Res.Security_AccessNotAllowed)); } } ParameterInfo[] parameterInfos = mi.GetParameters(); object[] args = new object[parameterInfos.Length]; parameterList.CopyTo(args, 0); TypeHelper.NarrowValues(args, parameterInfos); InvocationHandler invocationHandler = new InvocationHandler(mi); result = invocationHandler.Invoke(instance, args); } catch (TargetInvocationException exception) { MessageException messageException = null; if (exception.InnerException is MessageException) { messageException = exception.InnerException as MessageException;//User code throws MessageException } else { messageException = new MessageException(exception.InnerException); } if (log.IsDebugEnabled) { log.Debug(__Res.GetString(__Res.Invocation_Failed, mi.Name, messageException.Message)); } return(messageException.GetErrorMessage()); //Do not throw here, we do not want to log user code exceptions. //throw messageException; } } else { throw new MessageException(new MissingMethodException(className, operation)); } } catch (MessageException) { throw; } catch (Exception exception) { MessageException messageException = new MessageException(exception); throw messageException; } finally { factoryInstance.OnOperationComplete(instance); } } else { throw new MessageException(new TypeInitializationException(className, null)); } if (FluorineConfiguration.Instance.CacheMap != null && FluorineConfiguration.Instance.CacheMap.ContainsCacheDescriptor(source)) { //The result should be cached CacheableObject cacheableObject = new CacheableObject(source, key, result); FluorineConfiguration.Instance.CacheMap.Add(cacheableObject.Source, cacheableObject.CacheKey, cacheableObject); result = cacheableObject; } return(result); }
internal void DispatchSharedObjectMessage(SharedObjectMessage message) { #if !(NET_1_1) List <ASObject> changeList = null; List <ASObject> notifications = null; List <SendMessageEventArgs> messages = null; #else ArrayList changeList = null; ArrayList notifications = null; ArrayList messages = null; #endif bool raiseOnConnect = false; foreach (ISharedObjectEvent sharedObjectEvent in message.Events) { switch (sharedObjectEvent.Type) { case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_INITIAL_DATA: if (message.Version > 0) { _version = message.Version; } _attributes.Clear(); _initialSyncReceived = true; //Delay the connection notification until the attribute store has been populated //RaiseOnConnect(); raiseOnConnect = true; break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_UPDATE_DATA: case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_UPDATE_ATTRIBUTE: { ASObject infoObject = new ASObject(); infoObject["code"] = "change"; infoObject["name"] = sharedObjectEvent.Key; infoObject["oldValue"] = this.GetAttribute(sharedObjectEvent.Key); //Do not update the attribute store if this is a notification that the SetAttribute is accepted if (sharedObjectEvent.Type != FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_UPDATE_ATTRIBUTE) { _attributes[sharedObjectEvent.Key] = sharedObjectEvent.Value; } if (changeList == null) #if !(NET_1_1) { changeList = new List <ASObject>(); } #else { changeList = new ArrayList(); } #endif changeList.Add(infoObject); } break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_CLEAR_DATA: { ASObject infoObject = new ASObject(); infoObject["code"] = "clear"; if (changeList == null) #if !(NET_1_1) { changeList = new List <ASObject>(); } #else { changeList = new ArrayList(); } #endif changeList.Add(infoObject); _attributes.Clear(); } break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_DELETE_ATTRIBUTE: case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_DELETE_DATA: { _attributes.Remove(sharedObjectEvent.Key); ASObject infoObject = new ASObject(); infoObject["code"] = "delete"; infoObject["name"] = sharedObjectEvent.Key; if (changeList == null) #if !(NET_1_1) { changeList = new List <ASObject>(); } #else { changeList = new ArrayList(); } #endif changeList.Add(infoObject); } break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_STATUS: { ASObject infoObject = new ASObject(); infoObject["level"] = sharedObjectEvent.Value; infoObject["code"] = sharedObjectEvent.Key; if (notifications == null) #if !(NET_1_1) { notifications = new List <ASObject>(); } #else { notifications = new ArrayList(); } #endif notifications.Add(infoObject); } break; case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.CLIENT_SEND_MESSAGE: case FluorineFx.Messaging.Rtmp.SO.SharedObjectEventType.SERVER_SEND_MESSAGE: { string handler = sharedObjectEvent.Key; IList arguments = sharedObjectEvent.Value as IList; MethodInfo mi = MethodHandler.GetMethod(this.GetType(), handler, arguments); if (mi != null) { ParameterInfo[] parameterInfos = mi.GetParameters(); object[] args = new object[parameterInfos.Length]; arguments.CopyTo(args, 0); TypeHelper.NarrowValues(args, parameterInfos); try { InvocationHandler invocationHandler = new InvocationHandler(mi); object result = invocationHandler.Invoke(this, args); } catch (Exception exception) { #if !SILVERLIGHT log.Error("Error while invoking method " + handler + " on shared object", exception); #endif } } else { if (messages == null) #if !(NET_1_1) { messages = new List <SendMessageEventArgs>(); } #else { messages = new ArrayList(); } #endif messages.Add(new SendMessageEventArgs(handler, arguments)); } } break; default: break; } } if (raiseOnConnect) { RaiseOnConnect(); } if (changeList != null && changeList.Count > 0) { #if !(NET_1_1) RaiseSync(changeList.ToArray()); #else RaiseSync(changeList.ToArray(typeof(ASObject)) as ASObject[]); #endif } if (notifications != null) { foreach (ASObject infoObject in notifications) { RaiseNetStatus(infoObject); } } if (messages != null) { foreach (SendMessageEventArgs e in messages) { RaiseSendMessage(e); } } }
internal void DispatchSharedObjectMessage(SharedObjectMessage message) { List <ASObject> list = null; List <ASObject> list2 = null; foreach (ISharedObjectEvent event2 in message.Events) { ASObject obj2; switch (event2.Type) { case SharedObjectEventType.SERVER_SEND_MESSAGE: case SharedObjectEventType.CLIENT_SEND_MESSAGE: { string key = event2.Key; IList arguments = event2.Value as IList; MethodInfo methodInfo = MethodHandler.GetMethod(base.GetType(), key, arguments); if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; arguments.CopyTo(array, 0); TypeHelper.NarrowValues(array, parameters); try { object obj3 = new InvocationHandler(methodInfo).Invoke(this, array); } catch (Exception exception) { log.Error("Error while invoking method " + key + " on shared object", exception); } } break; } case SharedObjectEventType.CLIENT_CLEAR_DATA: obj2 = new ASObject(); obj2["code"] = "clear"; if (list == null) { list = new List <ASObject>(); } list.Add(obj2); base._attributes.Clear(); break; case SharedObjectEventType.CLIENT_DELETE_ATTRIBUTE: case SharedObjectEventType.CLIENT_DELETE_DATA: base._attributes.Remove(event2.Key); obj2 = new ASObject(); obj2["code"] = "delete"; obj2["name"] = event2.Key; if (list == null) { list = new List <ASObject>(); } list.Add(obj2); break; case SharedObjectEventType.CLIENT_INITIAL_DATA: if (message.Version > 0) { this._version = message.Version; } base._attributes.Clear(); this._initialSyncReceived = true; this.RaiseOnConnect(); break; case SharedObjectEventType.CLIENT_STATUS: obj2 = new ASObject(); obj2["level"] = event2.Value; obj2["code"] = event2.Key; if (list2 == null) { list2 = new List <ASObject>(); } list2.Add(obj2); break; case SharedObjectEventType.CLIENT_UPDATE_DATA: case SharedObjectEventType.CLIENT_UPDATE_ATTRIBUTE: obj2 = new ASObject(); obj2["code"] = "change"; obj2["name"] = event2.Key; obj2["oldValue"] = this.GetAttribute(event2.Key); base._attributes[event2.Key] = event2.Value; if (list == null) { list = new List <ASObject>(); } list.Add(obj2); break; } } if ((list != null) && (list.Count > 0)) { this.RaiseSync(list.ToArray()); } if (list2 != null) { foreach (ASObject obj2 in list2) { this.RaiseNetStatus(obj2); } } }
public override async Task <object> Invoke(IMessage message) { Task <object> result = null; RemotingMessage remotingMessage = message as RemotingMessage; string operation = remotingMessage.operation; string className = this.DestinationSettings.Properties["source"] as string; //This property is provided for backwards compatibility. The best practice, however, is to not expose the underlying source of a //RemoteObject destination on the client and only one source to a destination. if (remotingMessage.source != null && remotingMessage.source != string.Empty) { if (className == "*") { className = remotingMessage.source; } if (className != remotingMessage.source) { string msg = __Res.GetString(__Res.Type_MismatchMissingSource, remotingMessage.source, this.DestinationSettings.Properties["source"] as string); throw new MessageException(msg, new TypeLoadException(msg)); } } if (className == null) { throw new TypeInitializationException("null", null); } //Cache check string source = className + "." + operation; IList parameterList = remotingMessage.body as IList; FactoryInstance factoryInstance = this.Destination.GetFactoryInstance(); factoryInstance.Source = className; object instance = factoryInstance.Lookup(); if (instance != null) { Type type = instance.GetType(); bool isAccessible = TypeHelper.GetTypeIsAccessible(type); if (!isAccessible) { string msg = __Res.GetString(__Res.Type_InitError, type.FullName); throw new MessageException(msg, new TypeLoadException(msg)); } try { MethodInfo mi = MethodHandler.GetMethod(type, operation, parameterList); if (mi != null) { ParameterInfo[] parameterInfos = mi.GetParameters(); object[] args = new object[parameterInfos.Length]; parameterList.CopyTo(args, 0); TypeHelper.NarrowValues(args, parameterInfos); InvocationHandler invocationHandler = new InvocationHandler(mi); result = (Task <object>)invocationHandler.Invoke(instance, args); await result; } else { throw new MessageException(new MissingMethodException(className, operation)); } } catch (TargetInvocationException exception) { MessageException messageException = null; if (exception.InnerException is MessageException) { messageException = exception.InnerException as MessageException;//User code throws MessageException } else { messageException = new MessageException(exception.InnerException); } throw messageException; } catch (Exception exception) { MessageException messageException = new MessageException(exception); throw messageException; } } else { throw new MessageException(new TypeInitializationException(className, null)); } return(result.Result); }
public void SendMessage(string handler, IList arguments) { string str; string str2; this.BeginUpdate(); try { this._so.SendMessage(handler, arguments); } finally { this.EndUpdate(); } int length = handler.LastIndexOf("."); if (length != -1) { str = handler.Substring(0, length); str2 = handler.Substring(length + 1); } else { str = string.Empty; str2 = handler; } object serviceHandler = this.GetServiceHandler(str); if ((serviceHandler == null) && base.HasParent) { IScopeContext context = this.Parent.Context; try { serviceHandler = ObjectFactory.CreateInstance(this._so.Name + "." + str); } catch (Exception) { log.Debug(__Res.GetString("Type_InitError", new object[] { this._so.Name + "." + str })); } } if (serviceHandler != null) { MethodInfo methodInfo = MethodHandler.GetMethod(serviceHandler.GetType(), str2, arguments); if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; arguments.CopyTo(array, 0); TypeHelper.NarrowValues(array, parameters); try { object obj3 = new InvocationHandler(methodInfo).Invoke(serviceHandler, array); } catch (Exception exception) { log.Error("Error while invoking method " + str2 + " on shared object handler " + handler, exception); } } } foreach (ISharedObjectListener listener in this._serverListeners) { listener.OnSharedObjectSend(this, handler, arguments); } }
public void Handle(HttpApplication httpApplication) { object result = null; string url = null; bool debug = false; CompressionLevels compressionLevel = CompressionLevels.None; if (FluorineConfiguration.Instance.HttpCompressSettings.HandleRequest == HandleRequest.Swx || FluorineConfiguration.Instance.HttpCompressSettings.HandleRequest == HandleRequest.All) { compressionLevel = FluorineConfiguration.Instance.HttpCompressSettings.CompressionLevel; } bool allowDomain = FluorineConfiguration.Instance.SwxSettings.AllowDomain; try { NameValueCollection parameters; if (httpApplication.Request.RequestType == "GET") { parameters = httpApplication.Request.QueryString; } else { parameters = httpApplication.Request.Form; } string serviceClass = parameters["serviceClass"]; string operation = parameters["method"]; string args = parameters["args"]; url = parameters["url"]; debug = parameters["debug"] != null?FluorineFx.Util.Convert.ToBoolean(parameters["debug"]) : false; if (url != null) { url = HttpUtility.UrlDecode(url); // Firefox/Flash (at least, and tested only on a Mac), sends // file:/// (three slashses) in the URI and that fails the validation // so replacing that with two slashes instead. url = url.Replace("///", "//"); try { UriBuilder uriBuilder = new UriBuilder(url); } catch (UriFormatException) { if (log.IsWarnEnabled) { string msg = __Res.GetString(__Res.Swx_InvalidCrossDomainUrl, url); log.Warn(msg); } url = null; } } else { if (allowDomain && log.IsWarnEnabled) { string msg = "No referring URL received from Flash. Cross-domain will not be supported on this call regardless of allowDomain setting"; log.Warn(msg); } } // If the user did not pass an args array, treat it as // an empty args array. (Although this may be an error // on the client side, it may also be the user calling // a method that doesn't take arguments and we shouldn't // force the user to create an args parameter with an empty // array.) if (args == "undefined" || args == string.Empty) { args = "[]"; } // Massage special characters back args = args.Replace("\\t", "\t"); args = args.Replace("\\n", "\n"); args = args.Replace("\\'", "'"); FluorineFx.Json.JavaScriptArray argsArray = FluorineFx.Json.JavaScriptConvert.DeserializeObject(args) as FluorineFx.Json.JavaScriptArray; object[] arguments = argsArray.ToArray(); object instance = ObjectFactory.CreateInstance(serviceClass); MethodInfo mi = MethodHandler.GetMethod(instance.GetType(), operation, arguments); ParameterInfo[] parameterInfos = mi.GetParameters(); TypeHelper.NarrowValues(arguments, parameterInfos); InvocationHandler invocationHandler = new InvocationHandler(mi); result = invocationHandler.Invoke(instance, arguments); } catch (TargetInvocationException exception) { Hashtable resultObj = new Hashtable(); resultObj["error"] = true; resultObj["code"] = "SERVER.PROCESSING"; resultObj["message"] = exception.InnerException.Message; result = resultObj; } catch (Exception exception) { Hashtable resultObj = new Hashtable(); resultObj["error"] = true; resultObj["code"] = "SERVER.PROCESSING"; resultObj["message"] = exception.Message; result = resultObj; } SwxAssembler assembler = new SwxAssembler(); byte[] buffer = assembler.WriteSwf(result, debug, compressionLevel, url, allowDomain); httpApplication.Response.Clear(); httpApplication.Response.ClearHeaders(); httpApplication.Response.Buffer = true; httpApplication.Response.ContentType = "application/swf"; httpApplication.Response.AppendHeader("Content-Length", buffer.Length.ToString()); httpApplication.Response.AppendHeader("Content-Disposition", "attachment; filename=data.swf"); if (buffer.Length > 0) { httpApplication.Response.OutputStream.Write(buffer, 0, buffer.Length); } try { httpApplication.Response.Flush(); } catch (SecurityException) { } }
public void Handle(HttpApplication httpApplication) { object data = null; string str = null; Hashtable hashtable; bool debug = false; CompressionLevels none = CompressionLevels.None; if ((FluorineConfiguration.Instance.HttpCompressSettings.HandleRequest == HandleRequest.Swx) || (FluorineConfiguration.Instance.HttpCompressSettings.HandleRequest == HandleRequest.All)) { none = FluorineConfiguration.Instance.HttpCompressSettings.CompressionLevel; } bool allowDomain = FluorineConfiguration.Instance.SwxSettings.AllowDomain; try { NameValueCollection queryString; string str5; if (httpApplication.Request.RequestType == "GET") { queryString = httpApplication.Request.QueryString; } else { queryString = httpApplication.Request.Form; } string typeName = queryString["serviceClass"]; string methodName = queryString["method"]; string str4 = queryString["args"]; str = queryString["url"]; debug = (queryString["debug"] != null) ? Convert.ToBoolean(queryString["debug"]) : false; if (str != null) { str = HttpUtility.UrlDecode(str); str = str.Replace("///", "//"); try { UriBuilder builder = new UriBuilder(str); } catch (UriFormatException) { if (log.get_IsWarnEnabled()) { str5 = __Res.GetString("Swx_InvalidCrossDomainUrl", new object[] { str }); log.Warn(str5); } str = null; } } else if (allowDomain && log.get_IsWarnEnabled()) { str5 = "No referring URL received from Flash. Cross-domain will not be supported on this call regardless of allowDomain setting"; log.Warn(str5); } switch (str4) { case "undefined": case string.Empty: str4 = "[]"; break; } object[] arguments = (JavaScriptConvert.DeserializeObject(str4.Replace(@"\t", "\t").Replace(@"\n", "\n").Replace(@"\'", "'")) as JavaScriptArray).ToArray(); object obj3 = ObjectFactory.CreateInstance(typeName); MethodInfo methodInfo = MethodHandler.GetMethod(obj3.GetType(), methodName, arguments); ParameterInfo[] parameters = methodInfo.GetParameters(); TypeHelper.NarrowValues(arguments, parameters); data = new InvocationHandler(methodInfo).Invoke(obj3, arguments); } catch (TargetInvocationException exception) { hashtable = new Hashtable(); hashtable["error"] = true; hashtable["code"] = "SERVER.PROCESSING"; hashtable["message"] = exception.InnerException.Message; data = hashtable; } catch (Exception exception2) { hashtable = new Hashtable(); hashtable["error"] = true; hashtable["code"] = "SERVER.PROCESSING"; hashtable["message"] = exception2.Message; data = hashtable; } byte[] buffer = new SwxAssembler().WriteSwf(data, debug, none, str, allowDomain); httpApplication.Response.Clear(); httpApplication.Response.ClearHeaders(); httpApplication.Response.Buffer = true; httpApplication.Response.ContentType = "application/swf"; int length = buffer.Length; httpApplication.Response.AppendHeader("Content-Length", length.ToString()); httpApplication.Response.AppendHeader("Content-Disposition", "attachment; filename=data.swf"); if (buffer.Length > 0) { httpApplication.Response.OutputStream.Write(buffer, 0, buffer.Length); } try { httpApplication.Response.Flush(); } catch (SecurityException) { } }
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); } } }
public override object Invoke(IMessage message) { object obj2 = null; string str3; MessageException innerException; RemotingMessage message2 = message as RemotingMessage; string operation = message2.operation; string fullTypeName = base.DestinationSettings.Properties["source"] as string; if ((message2.source != null) && (message2.source != string.Empty)) { if (fullTypeName == "*") { fullTypeName = message2.source; } if (fullTypeName != message2.source) { str3 = __Res.GetString("Type_MismatchMissingSource", new object[] { message2.source, base.DestinationSettings.Properties["source"] as string }); throw new MessageException(str3, new TypeLoadException(str3)); } } if (fullTypeName == null) { throw new TypeInitializationException("null", null); } string source = fullTypeName + "." + operation; IList body = message2.body as IList; string cacheKey = CacheMap.GenerateCacheKey(source, body); if (FluorineConfiguration.Instance.CacheMap.ContainsValue(cacheKey)) { obj2 = FluorineConfiguration.Instance.CacheMap.Get(cacheKey); if (obj2 != null) { if ((log != null) && log.get_IsDebugEnabled()) { log.Debug(__Res.GetString("Cache_HitKey", new object[] { operation, cacheKey })); } return(obj2); } } FactoryInstance factoryInstance = base.Destination.GetFactoryInstance(); factoryInstance.Source = fullTypeName; object obj3 = factoryInstance.Lookup(); if (obj3 == null) { throw new MessageException(new TypeInitializationException(fullTypeName, null)); } Type type = obj3.GetType(); if (!TypeHelper.GetTypeIsAccessible(type)) { str3 = __Res.GetString("Type_InitError", new object[] { type.FullName }); throw new MessageException(str3, new TypeLoadException(str3)); } try { MethodInfo methodInfo = MethodHandler.GetMethod(type, operation, body); if (methodInfo == null) { throw new MessageException(new MissingMethodException(fullTypeName, operation)); } object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RoleAttribute), true); if ((customAttributes != null) && (customAttributes.Length == 1)) { RoleAttribute attribute = customAttributes[0] as RoleAttribute; string[] roles = attribute.Roles.Split(new char[] { ',' }); if (!base.Destination.Service.DoAuthorization(roles)) { throw new UnauthorizedAccessException(__Res.GetString("Security_AccessNotAllowed")); } } ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; body.CopyTo(array, 0); TypeHelper.NarrowValues(array, parameters); obj2 = new InvocationHandler(methodInfo).Invoke(obj3, array); } catch (TargetInvocationException exception) { innerException = null; if (exception.InnerException is MessageException) { innerException = exception.InnerException as MessageException; } else { innerException = new MessageException(exception.InnerException); } throw innerException; } catch (Exception exception3) { innerException = new MessageException(exception3); throw innerException; } if ((FluorineConfiguration.Instance.CacheMap != null) && FluorineConfiguration.Instance.CacheMap.ContainsCacheDescriptor(source)) { CacheableObject obj4 = new CacheableObject(source, cacheKey, obj2); FluorineConfiguration.Instance.CacheMap.Add(obj4.Source, obj4.CacheKey, obj4); obj2 = obj4; } return(obj2); }
object ProcessMessage(AMFMessage amfMessage) { // Apply AMF-based operation selector /* * Dictionary<string, string> operationNameDictionary = new Dictionary<string, string>(); * foreach (OperationDescription operation in _endpoint.Contract.Operations) * { * try * { * operationNameDictionary.Add(operation.Name.ToLower(), operation.Name); * } * catch (ArgumentException) * { * throw new Exception(String.Format("The specified contract cannot be used with case insensitive URI dispatch because there is more than one operation named {0}", operation.Name)); * } * } */ //SessionMode, CallbackContract, ProtectionLevel AMFMessage output = new AMFMessage(amfMessage.Version); for (int i = 0; i < amfMessage.BodyCount; i++) { AMFBody amfBody = amfMessage.GetBodyAt(i); object content = amfBody.Content; if (content is IList) { content = (content as IList)[0]; } IMessage message = content as IMessage; if (message != null) { //WCF should not assign client id for Flex... if (message.clientId == null) { message.clientId = Guid.NewGuid().ToString("D"); } //IMessage resultMessage = _endpoint.ServiceMessage(message); IMessage responseMessage = null; CommandMessage commandMessage = message as CommandMessage; if (commandMessage != null && commandMessage.operation == CommandMessage.ClientPingOperation) { responseMessage = new AcknowledgeMessage(); responseMessage.body = true; } else { RemotingMessage remotingMessage = message as RemotingMessage; string operation = remotingMessage.operation; //TODO: you could use an alias for a contract to expose a different name to the clients in the metadata using the Name property of the ServiceContract attribute string source = remotingMessage.source; Type serviceType = TypeHelper.Locate(source); Type contractInterface = serviceType.GetInterface(_endpoint.Contract.ContractType.FullName); //WCF also lets you apply the ServiceContract attribute directly on the service class. Avoid using it. //ServiceContractAttribute serviceContractAttribute = ReflectionUtils.GetAttribute(typeof(ServiceContractAttribute), type, true) as ServiceContractAttribute; if (contractInterface != null) { object instance = Activator.CreateInstance(serviceType); IList parameterList = remotingMessage.body as IList; MethodInfo mi = MethodHandler.GetMethod(contractInterface, operation, parameterList, false, false); //MethodInfo mi = MethodHandler.GetMethod(serviceType, operation, parameterList, false, false); if (mi != null) { //TODO OperationContract attribute to alias it to a different publicly exposed name OperationContractAttribute operationContractAttribute = ReflectionUtils.GetAttribute(typeof(OperationContractAttribute), mi, true) as OperationContractAttribute; if (operationContractAttribute != null) { //mi = MethodHandler.GetMethod(serviceType, operation, parameterList, false, false); ParameterInfo[] parameterInfos = mi.GetParameters(); object[] args = new object[parameterInfos.Length]; parameterList.CopyTo(args, 0); TypeHelper.NarrowValues(args, parameterInfos); object result = mi.Invoke(instance, args); if (!(result is IMessage)) { responseMessage = new AcknowledgeMessage(); responseMessage.body = result; } else { responseMessage = result as IMessage; } } else { responseMessage = ErrorMessage.GetErrorMessage(remotingMessage, new SecurityException("Method in not part of an service contract")); } } else { responseMessage = ErrorMessage.GetErrorMessage(remotingMessage, new SecurityException("Method in not part of an service contract")); } } else { responseMessage = ErrorMessage.GetErrorMessage(remotingMessage, new SecurityException(String.Format("The specified contract {0} cannot be used with the source named {1} and operation named {2}", _endpoint.Contract.ContractType.Name, source, operation))); } } if (responseMessage is AsyncMessage) { ((AsyncMessage)responseMessage).correlationId = message.messageId; } responseMessage.destination = message.destination; responseMessage.clientId = message.clientId; ResponseBody responseBody = new ResponseBody(amfBody, responseMessage); output.AddBody(responseBody); } } return(output); }
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 bool Invoke(IServiceCall call, object service) { IConnection connection = FluorineContext.Current.Connection; string serviceMethodName = call.ServiceMethodName; object[] arguments = call.Arguments; object[] destinationArray = null; if (arguments != null) { destinationArray = new object[arguments.Length + 1]; destinationArray[0] = connection; Array.Copy(arguments, 0, destinationArray, 1, arguments.Length); } else { destinationArray = new object[] { connection }; } object[] objArray3 = null; MethodInfo methodInfo = MethodHandler.GetMethod(service.GetType(), serviceMethodName, destinationArray, true, false, false); if (methodInfo == null) { methodInfo = MethodHandler.GetMethod(service.GetType(), serviceMethodName, arguments, true, false, false); if (methodInfo == null) { methodInfo = MethodHandler.GetMethod(service.GetType(), serviceMethodName, destinationArray, false, false, false); if (methodInfo == null) { methodInfo = MethodHandler.GetMethod(service.GetType(), serviceMethodName, arguments, false, false, false); if (methodInfo == null) { string message = __Res.GetString("Invocation_NoSuitableMethod", new object[] { serviceMethodName }); call.Status = 0x11; call.Exception = new FluorineException(message); this._log.Error(message, call.Exception); return(false); } objArray3 = arguments; } else { objArray3 = destinationArray; } } else { objArray3 = arguments; } } else { objArray3 = destinationArray; } try { this._log.Debug("Invoking method: " + methodInfo.Name); ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; objArray3.CopyTo(array, 0); TypeHelper.NarrowValues(array, parameters); object obj2 = null; if (methodInfo.ReturnType == typeof(void)) { InvocationHandler handler = new InvocationHandler(methodInfo); handler.Invoke(service, array); call.Status = 4; } else { obj2 = new InvocationHandler(methodInfo).Invoke(service, array); call.Status = (obj2 == null) ? ((byte)3) : ((byte)2); } if (call is IPendingServiceCall) { (call as IPendingServiceCall).Result = obj2; } } catch (SecurityException exception) { call.Exception = exception; call.Status = 0x12; this._log.Error("Error executing call: " + call); this._log.Error("Service invocation error", exception); return(false); } catch (TargetInvocationException exception2) { call.Exception = exception2; call.Status = 0x13; this._log.Error("Error executing call: " + call); this._log.Error("Service invocation error", exception2); return(false); } catch (Exception exception3) { call.Exception = exception3; call.Status = 20; this._log.Error("Error executing call: " + call); this._log.Error("Service invocation error", exception3); return(false); } return(true); }