Example #1
0
 /// <summary>
 /// Fires the OnBeforeCall event.
 /// </summary>
 /// <param name="serverRpcContext">Server side RPC call context</param>
 internal void OnBeforeCall(ServerRpcContext serverRpcContext)
 {
     BeforeCall?.Invoke(this, serverRpcContext);
 }
Example #2
0
 /// <summary>
 /// Fires the OnAfterCall event.
 /// </summary>
 /// <param name="serverRpcContext">Server side RPC call context</param>
 internal void OnAfterCall(ServerRpcContext serverRpcContext)
 {
     AfterCall?.Invoke(this, serverRpcContext);
 }
Example #3
0
        /// <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));
        }