/// <summary> /// Handles remote method invocation. /// </summary> /// <param name="methodCallMessage"><see cref="IMethodCallMessage"/> to process.</param> /// <param name="methodInfo"><see cref="MethodInfo"/> for the method being called.</param> /// <returns><see cref="ReturnMessage"/>, if the call is processed successfully, otherwise, false.</returns> private ReturnMessage HandleRemoteInvocation(IMethodCallMessage methodCallMessage, MethodInfo methodInfo) { _connection.PrepareCallContext(_implicitTransactionTransfer); var returnMessage = InvokeRemoteMethod(methodCallMessage); _connection.CheckRemoteSubscriptionCounter(); return(returnMessage); }
/// <summary> /// Invokes a remote method. /// </summary> /// <param name="methodCallMessage">Remoting message.</param> /// <returns>Remoting response message</returns> private ReturnMessage InvokeRemoteMethod(IMethodCallMessage methodCallMessage) { Guid trackingID = Guid.NewGuid(); //try //{ object returnValue = null; List <DelegateCorrelationInfo> correlationSet = null; if (_activationType == ActivationType.SingleCall) { correlationSet = _delegateCorrelationSet; } BeforeInvokeEventArgs cancelArgs = new BeforeInvokeEventArgs() { TrackingID = trackingID, InterfaceName = _interfaceType.FullName, DelegateCorrelationSet = correlationSet, MethodName = methodCallMessage.MethodName, Arguments = methodCallMessage.Args, Cancel = false }; _connection.OnBeforeInvoke(cancelArgs); if (cancelArgs.Cancel) { if (cancelArgs.CancelException == null) { cancelArgs.CancelException = new InvokeCanceledException(); } _connection.OnInvokeCanceled(new InvokeCanceledEventArgs() { TrackingID = trackingID, CancelException = cancelArgs.CancelException }); throw cancelArgs.CancelException.PreserveStackTrace(); } // Prepare generic method arguments Type[] genericArgs = null; if (methodCallMessage.MethodBase.IsGenericMethod) { genericArgs = methodCallMessage.MethodBase.GetGenericArguments(); } var paramDefs = methodCallMessage.MethodBase.GetParameters(); var paramTypes = paramDefs.Select(p => p.ParameterType).ToArray(); try { object[] checkedArgs = InterceptDelegateParameters(methodCallMessage); returnValue = _connection.SendRemoteMethodCallMessage ( trackingID, _uniqueName, correlationSet, methodCallMessage.MethodName, genericArgs, paramTypes, checkedArgs, _connection.PrepareCallContext(_implicitTransactionTransfer) ); AfterInvokeEventArgs afterInvokeArgs = new AfterInvokeEventArgs() { TrackingID = trackingID, InterfaceName = _interfaceType.FullName, DelegateCorrelationSet = correlationSet, MethodName = methodCallMessage.MethodName, Arguments = methodCallMessage.Args, ReturnValue = returnValue }; _connection.OnAfterInvoke(afterInvokeArgs); } catch (InvalidSessionException) { if (_autoLoginOnExpiredSession) { if (_connection.Reconnect()) { object[] checkedArgs = InterceptDelegateParameters(methodCallMessage); returnValue = _connection.SendRemoteMethodCallMessage ( trackingID, _uniqueName, correlationSet, methodCallMessage.MethodName, genericArgs, paramTypes, checkedArgs, _connection.PrepareCallContext(_implicitTransactionTransfer) ); } else { throw; } } else { throw; } } var container = returnValue as CustomSerializationContainer; if (container != null) { var serializationHandler = _connection.SerializationHandling[container.HandledType]; if (serializationHandler == null) { throw new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_SerializationHandlerNotFound, container.HandledType.FullName)); } returnValue = serializationHandler.Deserialize(container.DataType, container.Data); } return(new ReturnMessage(returnValue, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage)); //} //catch (Exception ex) //{ // if (_connection.ErrorHandlingEnabled) // throw; // else // return new ReturnMessage(ex, methodCallMessage); //} }
/// <summary> /// Entfernte Methode aufrufen. /// </summary> /// <param name="message">Remoting-Nachricht mit Details für den entfernten Methodenaufruf</param> /// <returns>Remoting Antwortnachricht</returns> public override IMessage Invoke(IMessage message) { // Wenn keine Nachricht angegeben wurde ... if (message == null) { // Ausnahme werfen throw new ArgumentNullException("message"); } // Nachricht in benötigte Schnittstelle casten IMethodCallMessage methodCallMessage = (IMethodCallMessage)message; // Methoden-Metadaten abrufen MethodInfo methodInfo = (MethodInfo)methodCallMessage.MethodBase; methodInfo.GetParameters(); // Wenn die Methode ein Delegat ist ... if (methodInfo.ReturnType.Equals(typeof(void)) && methodCallMessage.InArgCount == 1 && methodCallMessage.ArgCount == 1 && methodCallMessage.Args[0] != null && typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType()) && (methodCallMessage.MethodName.StartsWith("set_") || methodCallMessage.MethodName.StartsWith("add_"))) { // Delegat auf zu verdrahtende Client-Methode abrufen object receiveMethodDelegate = methodCallMessage.GetArg(0); // "set_" wegschneiden string propertyName = methodCallMessage.MethodName.Substring(4); // Verdrahtungskonfiguration festschreiben DelegateInterceptor wiring = new DelegateInterceptor() { ClientDelegate = receiveMethodDelegate }; // Korrelationsinformation zusammenstellen DelegateCorrelationInfo correlationInfo = new DelegateCorrelationInfo() { IsEvent = methodCallMessage.MethodName.StartsWith("add_"), DelegateMemberName = propertyName, ClientDelegateInterceptor = wiring }; // Wenn die Serverkomponente Singletonaktiviert ist ... if (_activationType == ActivationType.Singleton) { // Ereignis der Serverkomponente abonnieren _connection.RemoteComponentFactory.AddEventHandler(_interfaceType.FullName, correlationInfo); } // Verdrahtung in der Sammlung ablegen _delegateCorrelationSet.Add(correlationInfo); // Leere Remoting-Antwortnachricht erstellen und zurückgeben return(new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage)); } else if (methodInfo.ReturnType.Equals(typeof(void)) && methodCallMessage.InArgCount == 1 && methodCallMessage.ArgCount == 1 && methodCallMessage.Args[0] != null && typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType()) && (methodCallMessage.MethodName.StartsWith("remove_"))) { // EBC-Eingangsnachricht abrufen object inputMessage = methodCallMessage.GetArg(0); // "remove_" wegschneiden string propertyName = methodCallMessage.MethodName.Substring(7); // Wenn Verdrahtungen gespeichert sind ... if (_delegateCorrelationSet.Count > 0) { // Verdrahtungskonfiguration suchen DelegateCorrelationInfo found = (from correlationInfo in (DelegateCorrelationInfo[])_delegateCorrelationSet.ToArray() where correlationInfo.DelegateMemberName.Equals(propertyName) && correlationInfo.ClientDelegateInterceptor.ClientDelegate.Equals(inputMessage) select correlationInfo).FirstOrDefault(); // Wenn eine passende Verdrahtungskonfiguration gefunden wurde ... if (found != null) { // Wenn die Serverkomponente SingleCallaktiviert ist ... if (_activationType == ActivationType.SingleCall) { // Verdrahtungskonfiguration entfernen _delegateCorrelationSet.Remove(found); } else { // Ereignisabo entfernen _connection.RemoteComponentFactory.RemoveEventHandler(_interfaceType.FullName, found); } } } // Leere Remoting-Antwortnachricht erstellen und zurückgeben return(new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage)); } else { // Aufrufkontext vorbereiten _connection.PrepareCallContext(_implicitTransactionTransfer); // Entfernten Methodenaufruf durchführen und jede Antwortnachricht sofort über einen Rückkanal empfangen return(InvokeRemoteMethod(methodCallMessage)); } }