netty api 服务的运行方式
netty 本身就是一个 server ,所以不需要其他 webserver的支持,直接在shell 命令以守护进程的方式启动即可,通过后面的hujia.out
查看错误日志。下面是启动的脚本:
#!/bin/bash ps -ef|grep [h]ujia |awk '{print "kill -9 ",$2}'|sh cd /webapi/java/hujia/ CLASSPATH="." for jar in `ls ./lib` do CLASSPATH="$CLASSPATH:./lib/$jar" done CLASSPATH="./classes:$CLASSPATH" export CLASSPATH JAVA_OPTS='-Xms8000m -Xmx8000m -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+PrintGCDetails' nohup /usr/local/jdk/bin/java $JAVA_OPTS -Dapp.name=hujia -Dapp.base=$PWD me.topit.site.netty.HujiaWeixinServer >> /webapi/logs/hujia/hujia.out 2>&1 &
获取客户端 ip、服务端 ip
因为很多时候我们要同样的程序对不同的服务器做不同的处理,比如苹果官方审核的时候的开关。
public class HujiaServerHandler extends ChannelHandlerAdapter { private final Logger logger = LoggerFactory.getLogger(HujiaServerHandler.class); @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if (msg instanceof HttpRequest) { HttpRequest req = (HttpRequest) msg; String clientIP = (String) req.headers().get("X-Forwarded-For"); if (clientIP == null) { InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress(); clientIP = inSocket.getAddress().getHostAddress(); } InetSocketAddress inSocket2 = (InetSocketAddress) ctx.channel().localAddress(); String serverIP = inSocket2.getAddress().getHostAddress(); } //... } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); logger.error("ctx close!"); } }
拼装 http 头信息
至今还没有完全解决“设置gzip
压缩,页面就直接无输出,也不报错的问题”。目前线上服务通过 nginx 对Content-Type
为application/json
的数据进行gzip
压缩。
public class HujiaServerHandler extends ChannelHandlerAdapter { private final Logger logger = LoggerFactory.getLogger(HujiaServerHandler.class); @Override public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if (msg instanceof HttpRequest) { HttpRequest req = (HttpRequest) msg; if (HttpHeaderUtil.is100ContinueExpected(req)) { ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); } boolean keepAlive = HttpHeaderUtil.isKeepAlive(req); } //... String json= "xxxx"; FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(json.getBytes())); // response.headers().set(CONTENT_ENCODING, HttpHeaderValues.GZIP); response.headers().set(CONTENT_TYPE,new AsciiString("application/json; charset=utf-8")); response.headers().set(TRANSFER_ENCODING,HttpHeaderValues.CHUNKED); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE); ctx.write(response); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); logger.error("ctx close!"); } }