Netty5--入門
1 簡單的客戶端與服務端之間的通訊
1.1 服務端
/**
* 服務端
*
* @author Tang 2018年5月13日
*/
public class TimeServer {
public void bind(Integer inetPort) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup);
bootstrap.channel(NioServerSocketChannel.class);
bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
bootstrap.childHandler(new ChilddChannelHandler());
ChannelFuture channelFuture = bootstrap.bind(inetPort).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class ChilddChannelHandler extends
ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// TODO Auto-generated method stub
ch.pipeline().addLast(new TimeServerHandler());
}
}
public static void main(String[] args) {
new TimeServer().bind(8001);
}
}
訊息處理類:
public class TimeServerHandler extends ChannelHandlerAdapter {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
ctx.close();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, "UTF-8");
System.out.println("接收到訊息:" + body);
String currentTime = new Date().toString();
ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
ctx.write(resp);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
}
1.2 客戶端
public class TimeClient {
public void connect(String host, Integer port) {
EventLoopGroup loopGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(loopGroup);
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.TCP_NODELAY, true);
bootstrap.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new TimeClientHandler());
}
});
try {
ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
loopGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
new TimeClient().connect("127.0.0.1", 8001);
}
}
訊息處理類:
/**
* 客戶端
* @author Tang
* 2018年5月13日
*/
public class TimeClientHandler extends ChannelHandlerAdapter {
private static final String FIRST_MESSAGE = "Query Time";
private static final ByteBuf MSG = Unpooled
.buffer(FIRST_MESSAGE.getBytes().length);
static {
MSG.writeBytes(FIRST_MESSAGE.getBytes());
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(MSG);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, "UTF-8");
System.out.println("接收到訊息" + body);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
ctx.close();
}
}
先啟動服務端後再啟動客戶端,在控制檯輸入字串後,客戶端端將會收到訊息。
2 單客戶端多連線程式
物件池:
物件組:
初始化時建立多個物件,儲存在陣列中,呼叫的時候檢測是否已斷開連線
public class MultClient {
private Bootstrap bootstrap = new Bootstrap();
private List<Channel> channels = new ArrayList<Channel>();
private static final String HOST_NAME = "127.0.0.1";
private static final Integer PORT = 10101;
private static final InetSocketAddress SOCKET_ADDRESS = new InetSocketAddress(
HOST_NAME, PORT);
/**
* 引用計數
*/
private final AtomicInteger index = new AtomicInteger();
/**
* 初始化
* @param count
*/
public void init(int count) {
// worker
EventLoopGroup worker = new NioEventLoopGroup();
// 設定執行緒池
bootstrap.group(worker);
// 設定socket工廠
bootstrap.channel(NioSocketChannel.class);
// 設定管道
bootstrap.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ClientHandler());
}
});
for (int i = 1; i <= count; i++) {
ChannelFuture future = bootstrap.connect(SOCKET_ADDRESS);
channels.add(future.channel());
}
}
/**
* 獲取會話
*
* @return
*/
public Channel nextChannel() {
return getFirstActiveChannel(0);
}
private Channel getFirstActiveChannel(Integer count) {
Channel channel = channels.get(Math.abs(index.getAndIncrement()
% channels.size()));
if (!channel.isActive()) {// 是否已連線
// 重連
reconnect(channel);
if (count >= channels.size()) {
throw new RuntimeException("no can use channel");
}
return getFirstActiveChannel(count + 1);
}
return channel;
}
/**
* 重新連線
*
* @param channel
*/
private void reconnect(Channel channel) {
synchronized (channel) {
if (channels.indexOf(channel) == -1) {
return;
}
Channel newChannel = bootstrap.connect(SOCKET_ADDRESS).channel();
channels.set(channels.indexOf(channel), newChannel);
}
}
}
相關文章
- 入門入門入門 MySQL命名行MySql
- 如何入CTF的“門”?——所謂入門就是入門
- 何入CTF的“門”?——所謂入門就是入門
- scala 從入門到入門+
- makefile從入門到入門
- ACM入門之新手入門ACM
- 【小入門】react極簡入門React
- gRPC(二)入門:Protobuf入門RPC
- 《Flutter 入門經典》之“Flutter 入門 ”Flutter
- 新手入門,webpack入門詳細教程Web
- Android入門教程 | RecyclerView使用入門AndroidView
- linux新手入門――shell入門(轉)Linux
- MyBatis從入門到精通(一):MyBatis入門MyBatis
- SqlSugar ORM 入門到精通【一】入門篇SqlSugarORM
- Storm入門指南第二章 入門ORM
- VUE入門Vue
- MyBatis 入門MyBatis
- CSS 入門CSS
- JavaScript 入門JavaScript
- Nginx 入門Nginx
- RabbitMQ入門MQ
- GitHub入門Github
- Redis 入門Redis
- PostgreSQL 入門SQL
- Prometheus 入門Prometheus
- VuePress 入門Vue
- Tableau入門
- WebSocket 入門Web
- Webpack 入門Web
- UML入門
- nlp入門
- gulp入門
- Dubbo 入門
- AVFoundation 入門
- Nginx入門Nginx
- Redux入門Redux
- angular入門Angular
- golang 入門Golang