1. 程式人生 > >netty處理客戶端傳過來的get、post、websocket資料例子

netty處理客戶端傳過來的get、post、websocket資料例子

package com.penngo.http;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

public class HttpServer {

    private final int port;

    public HttpServer(int port) {
        this.port = port;
    }

    public void run() {
        ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
                Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
        bootstrap.setPipelineFactory(new HttpServerPipelineFactory());

        bootstrap.bind(new InetSocketAddress(port));
        System.out.println("Web socket server started at port " + port + '.');
        System.out.println("Open your browser and navigate to http://localhost:" + port + '/');
    }

    public static void main(String[] args) {
        int port;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        } else {
            port = 8080;
        }
        new HttpServer(port).run();
    }
}

package com.penngo.http;
import java.util.List;
import java.util.Map;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.QueryStringDecoder;
import org.jboss.netty.handler.codec.http.multipart.Attribute;
import org.jboss.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import org.jboss.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import org.jboss.netty.handler.codec.http.multipart.InterfaceHttpData;
import org.jboss.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
import org.jboss.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.WebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;

import org.jboss.netty.util.CharsetUtil;

import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
import static org.jboss.netty.handler.codec.http.HttpMethod.*;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
import static org.jboss.netty.handler.codec.http.HttpVersion.*;

public class HttpServerHandler extends SimpleChannelUpstreamHandler {
	private WebSocketServerHandshaker handshaker;
	private static final String WEBSOCKET_PATH = "/websocket";
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		Object msg = e.getMessage();
		if (msg instanceof HttpRequest) {
			handleHttpRequest(ctx, (HttpRequest) msg);
		} else if (msg instanceof WebSocketFrame) {
			handleWebSocketFrame(ctx, (WebSocketFrame) msg);
		}
	}

	private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req)
			throws Exception {
		System.out.println("handleHttpRequest method==========" + req.getMethod());
		System.out.println("handleHttpRequest uri==========" + req.getUri());
		if (req.getMethod() == GET) { // 處理get請求
			if(req.getUri().equals("/websocket")){
				  // Handshake
		        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
		                getWebSocketLocation(req), null, false);
		        handshaker = wsFactory.newHandshaker(req);
		        if (handshaker == null) {
		            wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel());
		        } else {
		            handshaker.handshake(ctx.getChannel(), req).addListener(WebSocketServerHandshaker.HANDSHAKE_LISTENER);
		        }
			}
			else{
				QueryStringDecoder decoder = new QueryStringDecoder(req.getUri());
				Map<String, List<String>> parame = decoder.getParameters();
				List<String> q = parame.get("q"); // 讀取從客戶端傳過來的引數
				String question = q.get(0);
				if (question != null && !question.equals("")) {
					System.out.println("r :" + question);
					HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);
					String data = "<html><body>你好,GET</body><html>";
					ChannelBuffer content = ChannelBuffers.copiedBuffer(data,
							CharsetUtil.UTF_8);
					res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");
					res.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
					setContentLength(res, content.readableBytes());
					res.setContent(content);
					sendHttpResponse(ctx, req, res);
				}
			}
		}
		if (req.getMethod() == POST) { // 處理POST請求
			HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(
					new DefaultHttpDataFactory(false), req);
			InterfaceHttpData postData = decoder.getBodyHttpData("q"); // //
																		// 讀取從客戶端傳過來的引數
			String question = "";
			if (postData.getHttpDataType() == HttpDataType.Attribute) {
				Attribute attribute = (Attribute) postData;
				question = attribute.getValue();
				System.out.println("q:" + question);

			}
			if (question != null && !question.equals("")) {

				HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);
				String data = "<html><body>你好,POST</body><html>";
				ChannelBuffer content = ChannelBuffers.copiedBuffer(data,
						CharsetUtil.UTF_8);
				res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");
				res.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
				setContentLength(res, content.readableBytes());
				res.setContent(content);
				sendHttpResponse(ctx, req, res);

			}
			return;
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
			throws Exception {
		e.getCause().printStackTrace();
		e.getChannel().close();
	}
	   private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
	        if (frame instanceof CloseWebSocketFrame) {
	            handshaker.close(ctx.getChannel(), (CloseWebSocketFrame) frame);
	            return;
	        }
	        if (frame instanceof PingWebSocketFrame) {
	            ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData()));
	            return;
	        }
	        if (!(frame instanceof TextWebSocketFrame)) {
	            throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass()
	                    .getName()));
	        }
	        String request = ((TextWebSocketFrame) frame).getText();
	        System.out.println("收到socket msg=" + request);
	        request = "這是來自伺服器端的資料";
	        ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase()));
	    }
	private static void sendHttpResponse(ChannelHandlerContext ctx,
			HttpRequest req, HttpResponse res) {
		if (res.getStatus().getCode() != 200) {
			res.setContent(ChannelBuffers.copiedBuffer(res.getStatus()
					.toString(), CharsetUtil.UTF_8));
			setContentLength(res, res.getContent().readableBytes());
		}

		ChannelFuture f = ctx.getChannel().write(res);
		if (!isKeepAlive(req) || res.getStatus().getCode() != 200) {
			f.addListener(ChannelFutureListener.CLOSE);
		}
	}
	 private static String getWebSocketLocation(HttpRequest req) {
	        return "ws://" + req.getHeader(HOST) + WEBSOCKET_PATH;
	    }
}
package com.penngo.http;
import static org.jboss.netty.channel.Channels.*;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;

public class HttpServerPipelineFactory implements ChannelPipelineFactory {
    public ChannelPipeline getPipeline() throws Exception {
        // Create a default pipeline implementation.
        ChannelPipeline pipeline = pipeline();
        pipeline.addLast("decoder", new HttpRequestDecoder());
//        pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
        pipeline.addLast("encoder", new HttpResponseEncoder());
        pipeline.addLast("handler", new HttpServerHandler());
        return pipeline;
    }
}