Netty 简易聊天 (一)

package com.ashuo.nettychat.server;

import com.ashuo.nettychat.server.handler.HttpHandler;

import io.netty.bootstrap.ServerBootstrap;
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.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;

public class ChatServer {
	private int port = 80;
	public void start() {
		//boss线程
		EventLoopGroup boosGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		
		try {
			//链路配置引擎
			ServerBootstrap b = new ServerBootstrap();
			//主从模型
			b.group(boosGroup, workerGroup).channel(NioServerSocketChannel.class)
			.option(ChannelOption.SO_BACKLOG,1024)
			.childHandler(new ChannelInitializer() {

				@Override
				protected void initChannel(SocketChannel ch) throws Exception {
					// 子线程业务 
					
					//解码和编码 Http请求
					ch.pipeline().addLast(new HttpServerCodec());
					ch.pipeline().addLast(new HttpObjectAggregator(64*1024));
					//用于处理文件流
					ch.pipeline().addLast(new ChunkedWriteHandler());
					ch.pipeline().addLast(new HttpHandler());
					
				}
			});
			//阻塞 等待客户连接
			ChannelFuture f  = b.bind(this.port).sync();
			System.out.println("服务已经启动,监听端口是:"+this.port);
			f.channel().closeFuture().sync();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			workerGroup.shutdownGracefully();
			boosGroup.shutdownGracefully();
			
		}
	}
	public static void main(String[] args) {
		try {
			new ChatServer().start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
package com.ashuo.nettychat.server.handler;

import java.io.File;
import java.io.RandomAccessFile;
import java.net.URISyntaxException;
import java.net.URL;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultFileRegion;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.LastHttpContent;

public class HttpHandler extends SimpleChannelInboundHandler{
	
	private URL baseURL = HttpHandler.class.getProtectionDomain().getCodeSource().getLocation();
	private final String WEB_ROOT = "webroot";
	private File GetFileFromRoot(String fileName) throws URISyntaxException {
		String path = baseURL.toURI()+WEB_ROOT+"/"+fileName;
		path = !path.contains("file:")?path:path.substring(6);
		path = path.replaceAll("//", "/");	
		return new File(path);
	}
	@Override
	//netty 以0结尾的方法都是实现类的方法。Spring 以do 开头的都是实现类的方法
	protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
		// 客户端请求的url
		String uri = request.getUri();
		String page = uri.equals("/")?"index.html":uri;
		RandomAccessFile file =new RandomAccessFile(GetFileFromRoot(page), "r");
		String contentType = "text/html;";
		//不同的文件返回不懂的头
		if(uri.endsWith(".css")) {
			contentType = "text/css;";
		}else if (uri.endsWith(".js")) {
			contentType = "text/javascript;";
		}else if(uri.toLowerCase().matches("(jpg|png|gif)$")){
			String ext = uri.substring(uri.lastIndexOf("."));
			contentType="image/"+ext+";";
		}
		
		HttpResponse response = new DefaultHttpResponse(request.getProtocolVersion(), HttpResponseStatus.OK);
		response.headers().set(HttpHeaders.Names.CONTENT_TYPE,contentType+"charset=utf-8");
		boolean keepAlive = HttpHeaders.isKeepAlive(request);
		//长连接处理
		if(keepAlive) {
			response.headers().set(HttpHeaders.Names.CONTENT_LENGTH,file.length());
			response.headers().set(HttpHeaders.Names.CONNECTION,HttpHeaders.Values.KEEP_ALIVE);
		}
		
		ctx.write(response);
		ctx.write(new DefaultFileRegion(file.getChannel(), 0, file.length()));
		
		//清空缓冲区(不要忘)(不要忘)(不要忘)
		ChannelFuture f =ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
		if(!keepAlive) {
			f.addListener(ChannelFutureListener.CLOSE);
		}
//		System.out.println(file);
		
	}

}

pom


	4.0.0

	com.ashuo
	nettychat
	0.0.1-SNAPSHOT
	jar

	nettychat
	http://maven.apache.org

	
		UTF-8
	

	
		
			io.netty
			netty-all
			4.1.6.Final
		
		
			org.msgpack
			msgpack
			0.6.12
		
		
			log4j
			log4j
			1.2.17
		
		
			com.alibaba
			fastjson
			1.2.4
		
		
			junit
			junit
			3.8.1
			test
		
	

 

你可能感兴趣的:(netty)