Netty示例:文件下载

Netty服务端启动代码:

public class NettyWebSocketServer extends Thread {
    protected ServerBootstrap BOOTSTRAP;
    protected EventLoopGroup BOSS_GROUP;
    protected EventLoopGroup WORKER_GROUP;
    protected int PORT;

    public NettyWebSocketServer(int port, ChannelInitializer<?> initializer){
        PORT = port;
        BOSS_GROUP = new NioEventLoopGroup(1);
        WORKER_GROUP = new NioEventLoopGroup();
        BOOTSTRAP = new ServerBootstrap();
        BOOTSTRAP.group(BOSS_GROUP, WORKER_GROUP)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(initializer);

    }

    public void run(){
        try {
            ChannelFuture future = BOOTSTRAP.bind(PORT).sync();
            LogUtil.println("Netty Websocket Server startup at PORT : " + PORT);
            future.channel().closeFuture().sync();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            shutdown();
        }
    }

    public void shutdown(){
        BOSS_GROUP.shutdownGracefully();
        WORKER_GROUP.shutdownGracefully();
        LogUtil.println("Netty Websocket Server shutdown!");
    }
    
    public void startService(){
    	this.start();
    }

	public int getPORT() {
		return PORT;
	}
    

}

Channel通信链配置

public abstract class BaseChannelInitilalizer extends
		ChannelInitializer<SocketChannel> {

	protected ChannelHandler HANDLER;
	
	protected MessageProcessMgr msgMgr;

	public BaseChannelInitilalizer(ChannelHandler handler, MessageProcessMgr msgMgr) {
		HANDLER = handler;
		this.msgMgr = msgMgr;
	}
}


public class TestServerInitializer extends BaseChannelInitilalizer {

	public TestServerInitializer(ChannelHandler handler,
			MessageProcessMgr msgMgr) {
		super(handler, msgMgr);
	}

	@Override
	protected void initChannel(SocketChannel channel) throws Exception {
		ChannelPipeline pipeline = channel.pipeline();
		pipeline.addLast(new HttpServerCodec());
		pipeline.addLast(new HttpObjectAggregator(65536));
		pipeline.addLast(new ChunkedWriteHandler());
		pipeline.addLast(HANDLER);
	}

}

消息分发器
@Sharable
public class TestDispacheHandler extends SimpleChannelInboundHandler<Object> {
	
	private static final Pattern INSECURE_URI = Pattern.compile(".*[<>&\"].*");
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, Object msg)
			throws Exception {
		if(msg instanceof FullHttpRequest){
			FullHttpRequest request = (FullHttpRequest)msg;
	        final String uri = request.getUri();
	        final String path = sanitizeUri(uri);		
	        File file = new File(path);
	        RandomAccessFile raf = new RandomAccessFile(file, "r");
	        long fileLength = raf.length();
	        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
	        HttpHeaders.setContentLength(response, fileLength);
	        setContentTypeHeader(response, file);
	        if (HttpHeaders.isKeepAlive(request)) {
	            response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
	        }
	        ctx.write(response);
	        ChannelFuture sendFileFuture;
	        ChannelFuture lastContentFuture;
	        sendFileFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)),ctx.newProgressivePromise());
	        lastContentFuture = sendFileFuture;
	        sendFileFuture.addListener(new ChannelProgressiveFutureListener() {
	            @Override
	            public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {
	                if (total < 0) { // total unknown
	                    System.err.println(future.channel() + " Transfer progress: " + progress);
	                } else {
	                    System.err.println(future.channel() + " Transfer progress: " + progress + " / " + total);
	                }
	            }
	            public void operationComplete(ChannelProgressiveFuture future) {
	                System.err.println(future.channel() + " Transfer complete.");
	            }
	        });
	        lastContentFuture.addListener(ChannelFutureListener.CLOSE);
		}
	}

	
    private static String sanitizeUri(String uri) {
        try {
            uri = URLDecoder.decode(uri, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new Error(e);
        }

        if (uri.isEmpty() || uri.charAt(0) != '/') {
            return null;
        }

        uri = uri.replace('/', File.separatorChar);
        if (uri.contains(File.separator + '.') ||
            uri.contains('.' + File.separator) ||
            uri.charAt(0) == '.' || uri.charAt(uri.length() - 1) == '.' ||
            INSECURE_URI.matcher(uri).matches()) {
            return null;
        }
        return SystemPropertyUtil.get("user.dir") + File.separator + uri;
    }
    
    private static void setContentTypeHeader(HttpResponse response, File file) {
        MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
        response.headers().set(CONTENT_TYPE, mimeTypesMap.getContentType(file.getPath()));
    }

}
注解 @Sharable:如果不加这个注解,则分发器只会收到一次消息,以后再也收不到了
sendFileFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)),ctx.newProgressivePromise());

Chunk方式传输文件

public class TestMain {

	public static void main(String[] args) throws Exception{
		new NettyWebSocketServer(8080,new TestServerInitializer(new TestDispacheHandler(), null)).startService();
		Thread.sleep(1000000);
	}
}



浏览器中输入

http://127.0.0.1:8080/netty_demo_upload.jar,开始下载文件







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值