分享:Solon + Smart-Socket 或 Netty 开发网络通讯
网络通讯应用,一般要用到网络开发包(比如,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);
}
}