/// <summary> /// Fires the OnBeforeCall event. /// </summary> /// <param name="serverRpcContext">Server side RPC call context</param> internal void OnBeforeCall(ServerRpcContext serverRpcContext) { BeforeCall?.Invoke(this, serverRpcContext); }
/// <summary> /// Fires the OnAfterCall event. /// </summary> /// <param name="serverRpcContext">Server side RPC call context</param> internal void OnAfterCall(ServerRpcContext serverRpcContext) { AfterCall?.Invoke(this, serverRpcContext); }
/// <summary> /// Calls a method on a server side service. /// </summary> /// <param name="request">RPC message from client</param> /// <returns>Task which provides the serialized response message containing the method result asynchronously</returns> /// <exception cref="MissingMethodException">Thrown if specified method in request doesn't exist</exception> private void ProcessRpcMessage(WireMessage request) { var sharedSecret = MessageEncryption ? SessionId.ToByteArray() : null; var callMessage = _server.Serializer .Deserialize <MethodCallMessage>( _server.MessageEncryptionManager.GetDecryptedMessageData( message: request, serializer: _server.Serializer, sharedSecret: sharedSecret, sendersPublicKeyBlob: _clientPublicKeyBlob, sendersPublicKeySize: _keyPair?.KeySize ?? 0)); ServerRpcContext serverRpcContext = new ServerRpcContext { UniqueCallKey = request.UniqueCallKey == null ? Guid.Empty : new Guid(request.UniqueCallKey), ServiceInstance = null, MethodCallMessage = callMessage, Session = this }; bool oneWay = false; byte[] serializedResult; try { var service = _server.ServiceRegistry.GetService(callMessage.ServiceName); var serviceInterfaceType = _server.ServiceRegistry.GetServiceInterfaceType(callMessage.ServiceName); CallContext.RestoreFromSnapshot(callMessage.CallContextSnapshot); serverRpcContext.ServiceInstance = service; ((RemotingServer)_server).OnBeforeCall(serverRpcContext); callMessage.UnwrapParametersFromDeserializedMethodCallMessage( out var parameterValues, out var parameterTypes); parameterValues = MapDelegateArguments(parameterValues); var method = serviceInterfaceType.GetMethod( name: callMessage.MethodName, types: parameterTypes); if (method == null) { throw new MissingMethodException( className: callMessage.ServiceName, methodName: callMessage.MethodName); } oneWay = method.GetCustomAttribute <OneWayAttribute>() != null; if (_server.Config.AuthenticationRequired && !_isAuthenticated) { throw new NetworkException("Session is not authenticated."); } var result = method.Invoke(service, parameterValues); if (!oneWay) { serverRpcContext.MethodCallResultMessage = _server .MethodCallMessageBuilder .BuildMethodCallResultMessage( serializer: _server.Serializer, uniqueCallKey: serverRpcContext.UniqueCallKey, method: method, args: parameterValues, returnValue: result); } ((RemotingServer)_server).OnAfterCall(serverRpcContext); if (oneWay) { return; } serializedResult = _server.Serializer.Serialize(serverRpcContext.MethodCallResultMessage); } catch (Exception ex) { Console.WriteLine(ex); if (serverRpcContext == null) { return; } serverRpcContext.Exception = new RemoteInvocationException( message: ex.Message, innerEx: ex.GetType().IsSerializable ? ex : null); ((RemotingServer)_server).OnAfterCall(serverRpcContext); if (oneWay) { return; } serializedResult = _server.Serializer.Serialize(serverRpcContext.Exception); } var methodReultMessage = _server.MessageEncryptionManager.CreateWireMessage( serializedMessage: serializedResult, serializer: _server.Serializer, error: serverRpcContext.Exception != null, sharedSecret: sharedSecret, keyPair: _keyPair, messageType: "rpc_result", uniqueCallKey: serverRpcContext.UniqueCallKey.ToByteArray()); _rawMessageTransport.SendMessage( _server.Serializer.Serialize(methodReultMessage)); }