---
id: callrpc
sidebar_position: 2
title: 调用rpc服务
sidebar_label: b.调用rpc服务
---

## 一、直接调用

直接调用，则是不使用**任何代理**，使用**字符串**和**参数**直接Call Rpc，使用比较简单。

下列以TcpTouchRpcClient为例，其他客户端一模一样。

```csharp
TcpTouchRpcClient client = new TcpTouchRpcClient();
client.Setup(new TouchSocketConfig()
    .SetRemoteIPHost("127.0.0.1:7789")
    .SetVerifyToken("TouchRpc"));
client.Connect();

//直接调用时，第一个参数为调用键
//第二个参数为调用配置参数，可设置调用超时时间，取消调用等功能。示例中使用的预设，实际上可以自行new InvokeOption();
//后续参数为调用参数。
//泛型为返回值类型。
bool result = client.Invoke<bool>("Login", InvokeOption.WaitInvoke, 123, "abc");
```

<a name="rrWhi"></a>

## 二、代理调用

代理调用的便捷在于，客户端不用再知道哪些服务可调，也不用再纠结调用的参数类型正不正确，因为这些，代理工具都会替你做好。

详细步骤：

1. [生成代理文件](9、生成，获取代理.md)
2. 将生成的cs文件添加到调用端一起编译。

例如：以上示例，会生成下列代理代码。
【生成的代理】

```csharp
using TouchSocket.Rpc;
using System.Threading.Tasks;
namespace RpcProxy
{
    public interface IMyRpcServer : IRemoteServer
    {
        ///<summary>
        ///登录
        ///</summary>
        /// <exception cref="System.TimeoutException">调用超时</exception>
        /// <exception cref="TouchSocket.Rpc.RpcInvokeException">Rpc调用异常</exception>
        /// <exception cref="System.Exception">其他异常</exception>
        System.Boolean Login(System.String account, System.String password, IInvokeOption invokeOption = default);
        ///<summary>
        ///登录
        ///</summary>
        /// <exception cref="System.TimeoutException">调用超时</exception>
        /// <exception cref="TouchSocket.Rpc.RpcInvokeException">Rpc调用异常</exception>
        /// <exception cref="System.Exception">其他异常</exception>
        Task<System.Boolean> LoginAsync(System.String account, System.String password, IInvokeOption invokeOption = default);

    }
    public class MyRpcServer : IMyRpcServer
    {
        public MyRpcServer(IRpcClient client)
        {
            this.Client = client;
        }
        public IRpcClient Client { get; private set; }
        ///<summary>
        ///登录
        ///</summary>
        /// <exception cref="System.TimeoutException">调用超时</exception>
        /// <exception cref="TouchSocket.Rpc.RpcInvokeException">Rpc调用异常</exception>
        /// <exception cref="System.Exception">其他异常</exception>
        public System.Boolean Login(System.String account, System.String password, IInvokeOption invokeOption = default)
        {
            if (Client == null)
            {
                throw new RpcException("IRpcClient为空，请先初始化或者进行赋值");
            }
            if (Client.TryCanInvoke?.Invoke(Client) == false)
            {
                throw new RpcException("Rpc无法执行。");
            }
            object[] parameters = new object[] { account, password };
            System.Boolean returnData = Client.Invoke<System.Boolean>("Login", invokeOption, parameters);
            return returnData;
        }
        ///<summary>
        ///登录
        ///</summary>
        public Task<System.Boolean> LoginAsync(System.String account, System.String password, IInvokeOption invokeOption = default)
        {
            if (Client == null)
            {
                throw new RpcException("IRpcClient为空，请先初始化或者进行赋值");
            }
            if (Client.TryCanInvoke?.Invoke(Client) == false)
            {
                throw new RpcException("Rpc无法执行。");
            }
            object[] parameters = new object[] { account, password };
            return Client.InvokeAsync<System.Boolean>("Login", invokeOption, parameters);
        }
    }
    public static class MyRpcServerExtensions
    {
        ///<summary>
        ///登录
        ///</summary>
        /// <exception cref="System.TimeoutException">调用超时</exception>
        /// <exception cref="TouchSocket.Rpc.RpcInvokeException">Rpc调用异常</exception>
        /// <exception cref="System.Exception">其他异常</exception>
        public static System.Boolean Login<TClient>(this TClient client, System.String account, System.String password, IInvokeOption invokeOption = default) where TClient :
        TouchSocket.Rpc.IRpcClient
        {
            if (client.TryCanInvoke?.Invoke(client) == false)
            {
                throw new RpcException("Rpc无法执行。");
            }
            object[] parameters = new object[] { account, password };
            System.Boolean returnData = client.Invoke<System.Boolean>("Login", invokeOption, parameters);
            return returnData;
        }
        ///<summary>
        ///登录
        ///</summary>
        public static Task<System.Boolean> LoginAsync<TClient>(this TClient client, System.String account, System.String password, IInvokeOption invokeOption = default) where TClient :
        TouchSocket.Rpc.IRpcClient
        {
            if (client.TryCanInvoke?.Invoke(client) == false)
            {
                throw new RpcException("Rpc无法执行。");
            }
            object[] parameters = new object[] { account, password };
            return client.InvokeAsync<System.Boolean>("Login", invokeOption, parameters);
        }
    }
}

```

使用代理扩展直接调用。

```csharp
TcpTouchRpcClient client = new TcpTouchRpcClient();
client.Setup(new TouchSocketConfig()
    .SetRemoteIPHost("127.0.0.1:7789")
    .SetVerifyToken("TouchRpc"));
client.Connect();

bool result = client.Login(123, "abc");//Login是扩展方法。可能需要额外添加命名空间。
```
