架构细节原博客都有,请参照 http://cpjsjxy.iteye.com/blog/1587601
propholder.xml
config/properties/settings.properties
settings.properties
app.handler.pool.corePoolSize=16 app.handler.pool.maximumPoolSize=32 app.handler.pool.keepAliveSecond=300 app.handler.pool.name=gamework app.handler.sleepTime=10 app.channel.readtimeout = 3600 #http socket websocket_text websocket_binary app.requestType=socket
测试类
TestClient
package com.cp.test; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.LengthFieldPrepender; import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequestEncoder; import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpVersion; import java.net.URI; import com.cp.domain.ERequestType; public class TestClient { public void connect(String host, int port, final ERequestType requestType) throws Exception { EventLoopGroup workerGroup = new NioEventLoopGroup(); String msg = "Are you ok?"; if (ERequestType.SOCKET.equals(requestType)) { try { Bootstrap b = new Bootstrap(); b.group(workerGroup); b.channel(NioSocketChannel.class).option( ChannelOption.TCP_NODELAY, true); b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000); b.handler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( "encode", new LengthFieldBasedFrameDecoder( Integer.MAX_VALUE, 0, 4, 0, 4)); ch.pipeline().addLast("decode", new LengthFieldPrepender(4)); ch.pipeline().addLast("handler", new ClientInboundHandler()); } }); ChannelFuture f = b.connect(host, port).sync(); ByteBuf messageData = Unpooled.buffer(); messageData.writeInt(999); messageData.writeInt(msg.length()); messageData.writeBytes(msg.getBytes()); f.channel().writeAndFlush(messageData).sync(); f.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } } else if (ERequestType.HTTP.equals(requestType)) { Bootstrap b = new Bootstrap(); b.group(workerGroup); b.channel(NioSocketChannel.class); b.option(ChannelOption.SO_KEEPALIVE, true); b.handler(new ChannelInitializer () { @Override public void initChannel(SocketChannel ch) throws Exception { // 客户端接收到的是httpResponse响应,所以要使用HttpResponseDecoder进行解码 ch.pipeline().addLast(new HttpResponseDecoder()); // 客户端发送的是httprequest,所以要使用HttpRequestEncoder进行编码 ch.pipeline().addLast(new HttpRequestEncoder()); ch.pipeline().addLast(new ClientInboundHandler()); } }); ChannelFuture f = b.connect(host, port).sync(); b.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true); b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000); URI uri = new URI("http://" + host + ":" + port); DefaultFullHttpRequest request = new DefaultFullHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.POST, uri.toASCIIString(), Unpooled.wrappedBuffer(msg.getBytes("UTF-8"))); // 构建http请求 request.headers().set(HttpHeaders.Names.HOST, host); request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, request.content().readableBytes()); // 发送http请求 f.channel().write(request); f.channel().flush(); f.channel().closeFuture().sync(); } try { } finally { workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { TestClient client = new TestClient(); client.connect("127.0.0.1", 8080, ERequestType.SOCKET); } }
ClientInboundHandler
package com.cp.test; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.HttpHeaders; import io.netty.handler.codec.http.HttpResponse; public class ClientInboundHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof HttpResponse) { HttpResponse response = (HttpResponse) msg; System.out.println("CONTENT_TYPE:" + response.headers().get(HttpHeaders.Names.CONTENT_TYPE)); } if (msg instanceof HttpContent) { HttpContent content = (HttpContent) msg; ByteBuf buf = content.content(); System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8)); buf.release(); } if (msg instanceof ByteBuf) { ByteBuf messageData = (ByteBuf) msg; int commandId = messageData.readInt(); int length = messageData.readInt(); byte[] c = new byte[length]; messageData.readBytes(c); System.out.println("commandId:"+commandId+"\tmessage:"+new String(c)); } } }
本测试代码已经过http、socket、websocket测试。
鉴于很多朋友想深入交流,特提供源码demo项目下载地址:
https://github.com/pofuchenzhou/netty-spring-game.git