**本案以简单的 Rpc 模式为例演示：（即以业务接口方式调用远程服务）**

### 1、接口定义

Rpc 模式借用了 Nami 做客户端定义（Nami 是 Solon 伴生框架，定位为 Rpc 通用客户端）

```java
@NamiClient(name = "demo",  path = "/demoe/rpc")
public interface HelloService {
    String hello(String name);
}
```


### 2、服务端

```java
//启动服务端
public class ServerApp {
    public static void main(String[] args) {
        //启动 Solon 容器（Socket.D bean&plugin 由solon容器管理）
        Solon.start(ServerApp.class, args, app -> app.enableSocketD(true));
    }
}

//定义远程服务组件
@Mapping("/demoe/rpc")
@Remoting
public class HelloServiceImpl implements HelloService {
    public String hello(String name) {
        return "name=" + name;
    }
}

//将 Socket.D 监听，转为 Handler 请求（即 Rpc 服务端模式） //这个很关键
@ServerEndpoint("/")
public class SocketdAsMvc extends ToHandlerListener {
}
```


### 3、客户端

* 使用 Socket.D 代理创建客户端（需要引用：[nami.channel.socketd](/article/168)）

```java
//启动客户端
public class ClientApp {
    public static void main(String[] args) throws Throwable {
        //启动Solon容器（Socket.D bean&plugin 由solon容器管理）
        Solon.start(ClientApp.class, args);
        
        //[客户端] 调用 [服务端] 的 rpc
        //
        HelloService rpc = SocketdProxy.create("sd:tcp://localhost:28080", HelloService.class);

        System.out.println("RPC result: " + rpc.hello("noear"));
    }
}
```

* 使用 Nami 创建客户端（推荐）


```java
//启动客户端
public class ClientApp {
    public static void main(String[] args) throws Throwable {
        //启动Solon容器（Socket.D bean&plugin 由solon容器管理）
        Solon.start(ClientApp.class, args);
        
        //[客户端] 调用 [服务端] 的 rpc（手动构建模式）
        //
        //引入：nami.channel.socketd.xxx 可用
        //HelloService rpc = Nami.builder().upstream(()->"sd:tcp://localhost:28080").encoder(SnackTypeEncoder.instance).create(HelloService.class);
        HelloService rpc = Nami.builder().url("sd:tcp://localhost:28080/demoe/rpc")
                                   .encoder(SnackTypeEncoder.instance)
                                   .create(HelloService.class);

        System.out.println("RPC result: " + rpc.hello("noear"));
    }
    
    //（注入构建模式）
    @NamiClient(url = "sd:tcp://localhost:28080")
    HelloService helloService；
}
```

* 使用 NamiClient 注解（推荐）

```java
@Configuration
public class Config {
    @Bean
    public NamiConfiguration initNami(){
        NamiConfiguration namiConfiguration = new NamiConfiguration() {
            @Override
            public void config(NamiClient client, NamiBuilder builder) {
                //指定编码器与解码器
                builder.decoder(SnackDecoder.instance);
                builder.encoder(SnackTypeEncoder.instance);
            }
        };

        return namiConfiguration;
    }
}

@Controller
public class DemoController {
    //如果有发现服务，能发现 demo 则不需要加 url //从而自动适应http或tpc协议
    @NamiClient(url = "sd:tcp://localhost:28080/demoe/rpc")
    HelloService helloService;

    @Mapping("hello")
    public String hello(String name) {
        return helloService.hello(name);
    }
}
```

### 4、具体示例

* [https://gitee.com/noear/solon_socketd_demo/tree/main/demo04.rpc](https://gitee.com/noear/solon_socketd_demo/tree/main/demo04.rpc)


* [https://gitee.com/noear/solon_rpc_demo](https://gitee.com/noear/solon_rpc_demo)


* [https://gitee.com/noear/solon-examples/tree/main/8.Solon-Remoting-SocketD/demo8041-rpc](https://gitee.com/noear/solon-examples/tree/main/8.Solon-Remoting-SocketD/demo8041-rpc)
