Solon v3.0.6

分享:Solon + Smart-Socket 或 Netty 开发网络通讯

</> markdown

网络通讯应用,一般要用到网络开发包(比如,Smart-Socket、Netty)。本案演示一个简单的 TcpServer(就是自定义 Tcp 协议开发)。

1、启动主类

启动 Solon 容器:demo/App.class

@SolonMain
public class App {
    public static void main(String[] args) {
        Solon.start(App.class, args);
    }
}

2、添加 TcpServer 生命周期组件

生命周期组件(实现 LifecycleBean 接口的组件),可将网络通讯框架的启动与关闭,自动整合到 Solon 的应用生命周期。之后,就是自定义协议处理代码。其它具有“启动”与“关闭”特性的框架,也可以采用生命周期组件进行整合。

@Component
public class TcpServer implements LifecycleBean {

    @Override
    public void start() throws Throwable {
        ...
    }

    @Override
    public void stop() throws Throwable {
        ...
    }
}

3、for Smart-Socket 示例

具体开发,请参考 Smart-Socket 官网资料!

  • 定义 TcpServer 组件
@Component
public class TcpServer implements LifecycleBean {
    private AioQuickServer server;

    @Override
    public void start() throws Throwable {
        server = new AioQuickServer(8888, new DecoderProtocolImpl(), new MessageProcessorImpl());
        server.start();
    }

    @Override
    public void stop() throws Throwable {
        if (server != null) {
            server.shutdown();
        }
    }
}
  • 协议实现代码
//解码协议实现
public class DecoderProtocolImpl implements Protocol<String> {
    @Override
    public String decode(ByteBuffer readBuffer, AioSession session) {
        //一个定长结构的字符串消息包:len(int)msg(string)
        int remaining = readBuffer.remaining();
        if (remaining < Integer.BYTES) {
            return null;
        }
        readBuffer.mark();
        int length = readBuffer.getInt();
        if (length > readBuffer.remaining()) {
            readBuffer.reset();
            return null;
        }
        byte[] b = new byte[length];
        readBuffer.get(b);
        readBuffer.mark();
        return new String(b);
    }
}

//消息处理实现
public class MessageProcessorImpl implements MessageProcessor<String> {
    @Override
    public void process(AioSession session, String msg) {
        System.out.println("receive from client: " + msg);
    }
}

4、for Netty 示例

具体开发,请参考 Netty 官网资料!

  • 定义 TcpServer 组件
@Component
public class TcpServer implements LifecycleBean {
    private ChannelFuture server;
    private EventLoopGroup bossGroup;
    private EventLoopGroup workGroup;

    @Override
    public void start() throws Throwable {
        bossGroup = new NioEventLoopGroup(1);
        workGroup = new NioEventLoopGroup();

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializerImpl()); //自定义初始化类

        server = serverBootstrap.bind(8888).await();

    }

    @Override
    public void stop() throws Throwable {
        if (server != null) {
            server.channel().close();
        }

        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }

        if (workGroup != null) {
            workGroup.shutdownGracefully();
        }
    }
}
  • 协议实现代码
//通道初始化
public class ChannelInitializerImpl extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new ProtocolServerImpl());
    }
}

//服务端解码实现
public class ProtocolServerImpl extends SimpleChannelInboundHandler<ByteBuf> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) throws Exception {
        //解码:一个定长结构的字符串消息包:len(int)msg(string)
        int remaining = buf.readableBytes();
        if (remaining < Integer.BYTES) {
            return;
        }
        buf.markReaderIndex();
        int length = buf.readInt();
        if (length > buf.readableBytes()) {
            buf.resetReaderIndex();
            return;
        }
        byte[] b = new byte[length];
        buf.readBytes(b);
        buf.markReaderIndex();
        String msg = new String(b);

        System.out.println("receive from client: " + msg);
    }
}