/// <summary> /// Handles MessageReceived event of messenger. /// It gets messages from server and invokes appropriate method. /// /// </summary> /// <param name="sender">Source of event</param><param name="e">Event arguments</param> private void RequestReplyMessenger_MessageReceived(object sender, MessageEventArgs e) { ScsRemoteInvokeMessage remoteInvokeMessage = e.Message as ScsRemoteInvokeMessage; if (remoteInvokeMessage == null) { return; } if (this._clientObject == null) { this.SendInvokeResponse((IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException("Client does not wait for method invocations by server.")); } else { object returnValue; try { returnValue = this._clientObject.GetType().GetMethod(remoteInvokeMessage.MethodName).Invoke(this._clientObject, remoteInvokeMessage.Parameters); } catch (TargetInvocationException ex) { Exception innerException = ex.InnerException; this.SendInvokeResponse((IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException(innerException.Message, innerException)); return; } catch (Exception ex) { this.SendInvokeResponse((IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException(ex.Message, ex)); return; } this.SendInvokeResponse((IScsMessage)remoteInvokeMessage, returnValue, (ScsRemoteException)null); } }
/// <summary> /// Overrides message calls and translates them to messages to remote application. /// </summary> /// <param name="msg">Method invoke message (from RealProxy base class)</param> /// <returns>Method invoke return message (to RealProxy base class)</returns> public override IMessage Invoke(IMessage msg) { IMethodCallMessage message = msg as IMethodCallMessage; if (message == null) { return(null); } ScsRemoteInvokeMessage requestMessage = new ScsRemoteInvokeMessage { ServiceClassName = typeof(TProxy).Name, MethodName = message.MethodName, Parameters = message.InArgs }; ScsRemoteInvokeReturnMessage responseMessage = _clientMessenger.SendMessageAndWaitForResponse(requestMessage, 10) as ScsRemoteInvokeReturnMessage; if (responseMessage == null) { return(null); } return(responseMessage.RemoteException != null ? new ReturnMessage(responseMessage.RemoteException, message) : new ReturnMessage(responseMessage.ReturnValue, null, 0, message.LogicalCallContext, message)); }
/// <summary> /// 将方法调用转换为远程方法调用 /// </summary> /// <param name="method">代理方法</param> /// <param name="parameters">代理参数</param> /// <returns>方法返回结果</returns> public virtual object Intercept(MethodInfo method, object[] parameters) { if (method == null) { return(null); } var requestMessage = new ScsRemoteInvokeMessage { ServiceClassName = typeof(TProxy).Name, MethodName = method.Name, Parameters = parameters }; var responseMessage = _clientMessenger.SendMessageAndWaitForResponse(requestMessage) as ScsRemoteInvokeReturnMessage; if (responseMessage == null) { return(null); } return(responseMessage.RemoteException == null ? responseMessage.ReturnValue : throw responseMessage.RemoteException); }
/// <summary> /// Handles MessageReceived events of all clients, evaluates each message, /// finds appropriate service object and invokes appropriate method. /// /// </summary> /// <param name="sender">Source of event</param><param name="e">Event arguments</param> private void Client_MessageReceived(object sender, MessageEventArgs e) { RequestReplyMessenger <IScsServerClient> requestReplyMessenger = (RequestReplyMessenger <IScsServerClient>)sender; ScsRemoteInvokeMessage remoteInvokeMessage = e.Message as ScsRemoteInvokeMessage; if (remoteInvokeMessage == null) { return; } try { IScsServiceClient scsServiceClient = this._serviceClients[requestReplyMessenger.Messenger.ClientId]; if (scsServiceClient == null) { requestReplyMessenger.Messenger.Disconnect(); } else { ScsServiceApplication.ServiceObject serviceObject = this._serviceObjects[remoteInvokeMessage.ServiceClassName]; if (serviceObject == null) { ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException("There is no service with name '" + remoteInvokeMessage.ServiceClassName + "'")); } else { try { serviceObject.Service.CurrentClient = scsServiceClient; object returnValue; try { returnValue = serviceObject.InvokeMethod(remoteInvokeMessage.MethodName, remoteInvokeMessage.Parameters); } finally { serviceObject.Service.CurrentClient = (IScsServiceClient)null; } ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, returnValue, (ScsRemoteException)null); } catch (TargetInvocationException ex) { Exception innerException = ex.InnerException; ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException(innerException.Message + Environment.NewLine + "Service Version: " + serviceObject.ServiceAttribute.Version, innerException)); } catch (Exception ex) { ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException(ex.Message + Environment.NewLine + "Service Version: " + serviceObject.ServiceAttribute.Version, ex)); } } } } catch (Exception ex) { ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException("An error occured during remote service method call.", ex)); } }
/// <summary> /// Overrides message calls and translates them to messages to remote application. /// </summary> /// <param name="msg">Method invoke message (from RealProxy base class)</param> /// <returns>Method invoke return message (to RealProxy base class)</returns> public override IMessage Invoke(IMessage msg) { var message = msg as IMethodCallMessage; if (message == null) { return(null); } var requestMessage = new ScsRemoteInvokeMessage { ServiceClassName = typeof(TProxy).Name, MethodName = message.MethodName, //Parameters = message.InArgs Parameters = message.Args }; var responseMessage = _clientMessenger.SendMessageAndWaitForResponse(requestMessage) as ScsRemoteInvokeReturnMessage; if (responseMessage == null) { return(null); } /* * http://stackoverflow.com/questions/3081341/ref-argument-through-a-realproxy * The second parameter of ReturnMessage needs to contain the values of the ref and out parameters to pass back. You can get them by saving a reference to the array you pass in: * * public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg) * { * IMethodCallMessage call = msg as IMethodCallMessage; * var args = call.Args; * object returnValue = typeof(HelloClass).InvokeMember(call.MethodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, _hello, args); * return new ReturnMessage(returnValue, args, args.Length, call.LogicalCallContext, call); * } */ object[] args = null; int largo = 0; if (responseMessage.Parameters != null) { args = responseMessage.Parameters; largo = args.Length; } return(responseMessage.RemoteException != null ? new ReturnMessage(responseMessage.RemoteException, message) : new ReturnMessage(responseMessage.ReturnValue, args, largo, message.LogicalCallContext, message)); }
/// <summary> /// Handles MessageReceived event of messenger. It gets messages from server and invokes /// appropriate method. /// </summary> /// <param name="sender">Source of event</param> /// <param name="e">Event arguments</param> private void RequestReplyMessenger_MessageReceived(object sender, MessageEventArgs e) { // Cast message to ScsRemoteInvokeMessage and check it ScsRemoteInvokeMessage invokeMessage = e.Message as ScsRemoteInvokeMessage; if (invokeMessage == null) { return; } // Check client object. if (_clientObject == null) { SendInvokeResponse(invokeMessage, null, new ScsRemoteException("Client does not wait for method invocations by server.")); return; } // Invoke method object returnValue; try { Type type = _clientObject.GetType(); MethodInfo method = type.GetMethod(invokeMessage.MethodName); returnValue = method.Invoke(_clientObject, invokeMessage.Parameters); } catch (TargetInvocationException ex) { Exception innerEx = ex.InnerException; if (innerEx != null) { SendInvokeResponse(invokeMessage, null, new ScsRemoteException(innerEx.Message, innerEx)); } return; } catch (Exception ex) { SendInvokeResponse(invokeMessage, null, new ScsRemoteException(ex.Message, ex)); return; } // Send return value SendInvokeResponse(invokeMessage, returnValue, null); }
/// <summary> /// Handles MessageReceived events of all clients, evaluates each message, finds appropriate /// service object and invokes appropriate method. /// </summary> /// <param name="sender">Source of event</param> /// <param name="e">Event arguments</param> private void Client_MessageReceived(object sender, MessageEventArgs e) { // Get RequestReplyMessenger object (sender of event) to get client RequestReplyMessenger <IScsServerClient> requestReplyMessenger = (RequestReplyMessenger <IScsServerClient>)sender; // Cast message to ScsRemoteInvokeMessage and check it ScsRemoteInvokeMessage invokeMessage = e.Message as ScsRemoteInvokeMessage; if (invokeMessage == null) { return; } try { // Get client object IScsServiceClient client = _serviceClients[requestReplyMessenger.Messenger.ClientId]; if (client == null) { requestReplyMessenger.Messenger.Disconnect(); return; } // Get service object ServiceObject serviceObject = _serviceObjects[invokeMessage.ServiceClassName]; if (serviceObject == null) { SendInvokeResponse(requestReplyMessenger, invokeMessage, null, new ScsRemoteException("There is no service with name '" + invokeMessage.ServiceClassName + "'")); return; } // Invoke method try { // Set client to service, so user service can get client in service method using // CurrentClient property. object returnValue; serviceObject.Service.CurrentClient = client; try { returnValue = serviceObject.InvokeMethod(invokeMessage.MethodName, invokeMessage.Parameters); } finally { // Set CurrentClient as null since method call completed serviceObject.Service.CurrentClient = null; } // Send method invocation return value to the client SendInvokeResponse(requestReplyMessenger, invokeMessage, returnValue, null); } catch (TargetInvocationException ex) { Exception innerEx = ex.InnerException; if (innerEx != null) { SendInvokeResponse(requestReplyMessenger, invokeMessage, null, new ScsRemoteException(innerEx.Message + Environment.NewLine + "Service Version: " + serviceObject.ServiceAttribute.Version, innerEx)); } } catch (Exception ex) { SendInvokeResponse(requestReplyMessenger, invokeMessage, null, new ScsRemoteException(ex.Message + Environment.NewLine + "Service Version: " + serviceObject.ServiceAttribute.Version, ex)); } } catch (Exception ex) { SendInvokeResponse(requestReplyMessenger, invokeMessage, null, new ScsRemoteException("An error occured during remote service method call.", ex)); } }