Solon v3.7.1

分享:Solon + 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 Netty 示例

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

  • 定义 TcpServer 组件
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.MultiThreadIoEventLoopGroup;
import io.netty.channel.nio.NioIoHandler;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.bean.LifecycleBean;

@Component
public class TcpServer implements LifecycleBean {
    private ChannelFuture server;
    private EventLoopGroup bossGroup;
    private EventLoopGroup workGroup;

    @Override
    public void start() throws Throwable {
        bossGroup = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory());
        workGroup = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory());

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializerImpl());

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

    }

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

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

        if (workGroup != null) {
            workGroup.shutdownGracefully();
        }
    }
}
  • 协议实现代码
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
import java.nio.charset.Charset;

public class ChannelInitializerImpl extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) {
        ChannelPipeline pipeline = ch.pipeline();

        pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));

        pipeline.addLast(new ProtocolServerImpl());
    }
}

public class ProtocolServerImpl extends SimpleChannelInboundHandler<String> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        System.out.println("receive from client: " + msg);
    }
}