可以给你提供思路
也可以让你学到Netty相关的知识
当然,这只是一种实现方式
需求
看下图,其实这个项目就是为了做这样一件事。
有一个公共服务***ServerA***,它提供了一个名为***getUserName***的服务。
现在有多个类似ServerB的Web应用服务器。
当客户想通过ServerB要请求**getUserName服务时,由于ServerB服务中因为没有***UserService***的实现类,导致不能正常提供服务的问题。
预期结果
可以看到,在Client项目中,UserService没有实现类,但是返回了正常的结果。
项目结构
整个项目分为三个部分,Server端、Client端以及一个公共jar。
下图正是整个项目的目录结构图。
公共部分
公共部分的存在是因为我将服务器端和客户端写在了一个项目中,为了不让代码重复警告,所以提出来的一个公共模块。主要是几个实体类和一些序列化工具类。
-
MsgPackDecoder
- 该类是一个MsgPack编码器,主要作用将Object对象序列化成byte数组。
-
MsgPackEncoder
- 该类是一个MsgPack解码器,主要作用将byte数组反序列化成Object对象。
-
ObjectCodec
-
该类是继承了MessageToMessageCodec<ByteBuf, Object>。是自定义序列化类主要有两个方法,encode和decode
@Override protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) { // 调用工具类的序列化方法 byte[] data = ObjectSerializerUtils.serilizer(msg); ByteBuf buf = Unpooled.buffer(); buf.writeBytes(data); out.add(buf); } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) { // 调用工具类的反序列化方法 byte[] bytes = new byte[msg.readableBytes()]; msg.readBytes(bytes); Object deSerilizer = ObjectSerializerUtils.deSerilizer(bytes); out.add(deSerilizer); }
-
-
ObjectSerializerUtils
- 序列化工具类。序列化方法可以自己实现
-
MethodInvokeMeta
- 重点类。这个类是一个实体类。用于在网络中传输的类。主要有5个字段分别记录了一个接口的类对象,调用接口的方法名,方法的参数列表(包含参数类型,和参数列表),方法的返回值类型。
- 在客户端中,这个类将调用方所要调用的方法封装。
- 在服务端中,这个类主要用于服务器反射调用方法。
- 当然,也可以用String来记录这些元信息。
-
NullWritable
- 这个类主要用于在网络中传输null。当返回值为null时,服务端会返回NullWritable对象。客户端接收到NullWritabl