Solon v2.7.5

Socket.D 协议转为 Mvc 接口

</> markdown

此内容 v2.6.0 后支持


1、协议转换

我们基于 sd:ws 协议为例。引入依赖包: (如果是 sd:ws,也可以从 websocket 升级转换。参考:《WebSocket 协议转换为 Socket.D》 )

<!-- socket.d 的 solon 服务启动插件 -->
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon.boot.socketd</artifactId>
</dependency>

<!-- 引用 sd:ws 协议传输包,它会使用独立的端口 -->
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>socketd-transport-java-websocket</artifactId>
    <version>${socketd.version}</version>
</dependency>

尝试把 “应答场景” 的 /mvc/ 频道,转为 solon 控制器模式开发。(其它频道不受影响)

  • 通过 ToHandlerListener ,转换为 Solon Handler 接口。从而实现控制器模式开发(即支持 Mvc、Rpc 开发模式)
//协议转换处理
@ServerEndpoint("/mvc/")
public class SocketdAsMvc extends ToHandlerListener {
    @Override
    public void onOpen(Session s){
        //如果有需要,加个鉴权(如果不需要,去掉)
        if("a".equals(s.param("u")) == false){
            s.close(); return;
        }
        
        //这个一定要调
        super.onOpen();
    }
}

//控制器
@Controller
public class HelloController {
    @Socket //不加限定注解的话,可同时支持 http 请求
    @Mapping("/mvc/hello")
    public Result hello(long id, String name) { //{code:200,...}
        return Result.succeed();
    }
}

启动后端口是什么?可参考:《Sokcet.D 与 Solon 集成》

2、使用 Socket.D 进行客户端调用

  • 以 Java 原生接口方式示例

引入依赖包

<!--  提供 sd:ws 传输编解码支持(不同的传输协议,用不同的包) -->
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>socketd-transport-java-websocket</artifactId>
    <version>${socketd.version}</version>
</dependency>
let clientSession = SocketD.createClient("sd:ws://localhost:28082/mvc/?u=a")
        .open();

let request = new StringEntity("{id:1,name:'noear'}").metaPut("Content-Type","text/json"),
let response = clientSession.sendAndRequest("/mvc/hello",  entity).await();

// event 相当于 http path(注意这个关系)
// data  相当于 http body
// meta  相当于 http header
  • 以 Java Rpc 代理模式示例

再多引入一个依赖包

<!--  提供 SocketdProxy 类 -->
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>nami.channel.socketd</artifactId>
</dependency>

代码示例(以 rpc 代理的方式展示)

//[客户端] 调用 [服务端] 的 mvc
//
HelloService rpc = SocketdProxy.create("sd:ws://localhost:28082/mvc/?u=a", HelloService.class);

System.out.println("MVC result:: " + mvc.hello("noear"));
<script src="/js/socket.d.js"></script>
const clientSession = await SocketD.createClient("sd:ws://127.0.0.1:28082/mvc/?u=a")
        .open();

//添加用户(加个内容类型,方便与 Mvc 对接)
const entity = SocketD.newEntity("{id:1,name:'noear'}").metaPut("Content-Type","text/json"),
clientSession.sendAndRequest("/mvc/hello",  entity).thenReply(reply=>{
    alert(reply.dataAsString());
})

// event 相当于 http path(注意这个关系)
// data  相当于 http body
// meta  相当于 http header