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從入門到入門
- gRPC(二)入門:Protobuf入門RPC
- 【小入門】react極簡入門React
- Android入門教程 | RecyclerView使用入門AndroidView
- 新手入門,webpack入門詳細教程Web
- Android入門教程 | Kotlin協程入門AndroidKotlin
- 《Flutter 入門經典》之“Flutter 入門 ”Flutter
- MyBatis從入門到精通(一):MyBatis入門MyBatis
- Tableau入門
- angular入門Angular
- lodash入門
- Webpack 入門Web
- golang 入門Golang
- lapis入門API
- MarkDown入門
- JSP入門JS
- UML入門
- VuePress 入門Vue
- RSA入門
- jQuery入門jQuery
- Hive 入門Hive
- scrapy入門
- Fetch 入門
- WebSocket 入門Web
- indexedDB入門Index
- Netty入門Netty
- GraphQL入門
- Serlvet入門
- ORM入門ORM
- RESTful入門REST
- Feathers 入門
- HTTP入門HTTP
- 入門WebpackWeb
- JPA入門
- Solr 入門Solr