netty寫一個http伺服器
一、客戶端
客戶端啟動類
/**
* @author yun
* 類說明:
*/
public class HttpClient {
public void connect(String host, int port) throws Exception {
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws Exception {
ch.pipeline().addLast(new HttpClientCodec());
ch.pipeline().addLast("aggre",
new HttpObjectAggregator(10*1024*1024));
ch.pipeline().addLast("decompressor",new HttpContentDecompressor());
ch.pipeline().addLast("busi",new HttpClientInboundHandler());
}
});
// Start the client.
ChannelFuture f = b.connect(host, port).sync();
URI uri = new URI("/test");
String msg = "Hello";
DefaultFullHttpRequest request =
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET,
uri.toASCIIString(),
Unpooled.wrappedBuffer(msg.getBytes("UTF-8")));
// 構建http請求
request.headers().set(HttpHeaderNames.HOST, host);
request.headers()
.set(HttpHeaderNames.CONNECTION,
HttpHeaderValues.KEEP_ALIVE);
request.headers()
.set(HttpHeaderNames.CONTENT_LENGTH,
request.content().readableBytes());
// 傳送http請求
f.channel().write(request);
f.channel().flush();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
HttpClient client = new HttpClient();
client.connect("127.0.0.1", HttpServer.port);
}
}
客戶端處理類
/**
* @authoryun
* 類說明:
*/
public class HttpClientInboundHandler
extends ChannelInboundHandlerAdapter {
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
//開始對伺服器的響應做處理
FullHttpResponse httpResponse = (FullHttpResponse)msg;
System.out.println(httpResponse.headers());
ByteBuf content = httpResponse.content();
System.out.println(content.toString(CharsetUtil.UTF_8));
content.release();
}
}
二、服務端
服務端啟動類
/**
* @author yun
* 類說明:
*/
public class HttpServer {
public static final int port = 6789; //設定服務端埠
private static EventLoopGroup group = new NioEventLoopGroup();
private static ServerBootstrap b = new ServerBootstrap();
private static final boolean SSL = false;
public static void main(String[] args) throws Exception {
final SslContext sslCtx;
if (SSL) {
//netty為我們提供的ssl加密,預設
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(),
ssc.privateKey()).build();
} else {
sslCtx = null;
}
try {
b.group(group);
b.channel(NioServerSocketChannel.class);
b.childHandler(new ServerHandlerInit(sslCtx));
// 伺服器繫結埠監聽
ChannelFuture f = b.bind(port).sync();
System.out.println("服務端啟動成功,埠是:"+port);
// 監聽伺服器關閉監聽
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
服務端channel初始器
/**
* @author yun
* 類說明:
*/
public class ServerHandlerInit extends ChannelInitializer<SocketChannel> {
private final SslContext sslCtx;
public ServerHandlerInit(SslContext sslCtx) {
this.sslCtx = sslCtx;
}
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline ph = ch.pipeline();
if (sslCtx != null) {
ph.addLast(sslCtx.newHandler(ch.alloc()));
}
//http響應編碼
ph.addLast("encode",new HttpResponseEncoder());
//http請求編碼
ph.addLast("decode",new HttpRequestDecoder());
//聚合http請求
ph.addLast("aggre",
new HttpObjectAggregator(10*1024*1024));
//啟用http壓縮
ph.addLast("compressor",new HttpContentCompressor());
//自己的業務處理
ph.addLast("busi",new BusiHandler());
}
}
服務端業務處理器
/**
* @author yun
* 類說明:
*/
public class BusiHandler extends ChannelInboundHandlerAdapter {
private String result="";
private void send(String content, ChannelHandlerContext ctx,
HttpResponseStatus status){
FullHttpResponse response =
new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,status,
Unpooled.copiedBuffer(content,CharsetUtil.UTF_8));
response.headers().set(HttpHeaderNames.CONTENT_TYPE,
"text/plain;charset=UTF-8");
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
/*
* 收到訊息時,返回資訊
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
String result="";
//接收到完成的http請求
FullHttpRequest httpRequest = (FullHttpRequest)msg;
try{
String path = httpRequest.uri();
String body = httpRequest.content().toString(CharsetUtil.UTF_8);
HttpMethod method = httpRequest.method();
if(!"/test".equalsIgnoreCase(path)){
result = "非法請求:"+path;
send(result,ctx,HttpResponseStatus.BAD_REQUEST);
return;
}
//處理http GET請求
if(HttpMethod.GET.equals(method)){
System.out.println("body:"+body);
result="Get request,Response="+RespConstant.getNews();
send(result,ctx,HttpResponseStatus.OK);
}
//處理http POST請求
if(HttpMethod.POST.equals(method)){
//.....
}
}catch(Exception e){
System.out.println("處理請求失敗!");
e.printStackTrace();
}finally{
httpRequest.release();
}
}
/*
* 建立連線時,返回訊息
*/
@Override
public void channelActive(ChannelHandlerContext ctx)
throws Exception {
System.out.println("連線的客戶端地址:"
+ ctx.channel().remoteAddress());
}
}
常量類
/**
* @author yun
* 類說明:
*/
public class RespConstant {
private static final String[] NEWS = {
"她那時候還太年輕,不知道所有命運贈送的禮物,早已在暗中標好了" +
"價格。——斯蒂芬·茨威格《斷頭皇后》",
"這是一個最好的時代,也是一個最壞的時代;" +
"這是一個智慧的年代,這是一個愚蠢的年代;\n" +
"這是一個信任的時期,這是一個懷疑的時期;" +
"這是一個光明的季節,這是一個黑暗的季節;\n" +
"這是希望之春,這是失望之冬;" +
"人們面前應有盡有,人們面前一無所有;\n" +
"人們正踏上天堂之路,人們正走向地獄之門。 —— 狄更斯《雙城記》",
};
private static final Random R = new Random();
public static String getNews(){
return NEWS[R.nextInt(NEWS.length)];
}
}
相關文章
- 使用Netty構建一個帶註解的Http伺服器框架NettyHTTP伺服器框架
- 手寫一個類SpringBoot的HTTP框架:幾十行程式碼基於Netty搭建一個 HTTP ServerSpring BootHTTP框架行程NettyServer
- 前端er,什麼時候,你想寫一個 HTTP 伺服器?前端HTTP伺服器
- Netty 實現HTTP檔案伺服器NettyHTTP伺服器
- Netty實現Http高效能伺服器NettyHTTP伺服器
- Netty(二) 實現簡單Http伺服器NettyHTTP伺服器
- netty系列之:使用netty實現支援http2的伺服器NettyHTTP伺服器
- netty系列之:搭建HTTP上傳檔案伺服器NettyHTTP伺服器
- 【Netty】第一個Netty應用Netty
- 使用Netty三分鐘手寫一個RPCNettyRPC
- 一起寫一個 Web 伺服器Web伺服器
- Node.js實現一個HTTP伺服器Node.jsHTTP伺服器
- 使用Java Socket手擼一個http伺服器JavaHTTP伺服器
- SimpleHTTPServer ——一個簡單的HTTP伺服器HTTPServer伺服器
- 手寫一個靜態伺服器伺服器
- 自己寫一個Web伺服器(1)Web伺服器
- 自己寫一個Web伺服器(2)Web伺服器
- 自己寫一個Web伺服器(3)Web伺服器
- 一起寫一個 Web 伺服器(1)Web伺服器
- 一起寫一個 Web 伺服器(2)Web伺服器
- 一起寫一個Web伺服器(3)Web伺服器
- netty系列之:自建客戶端和HTTP伺服器互動Netty客戶端HTTP伺服器
- Netty 實戰:如何編寫一個麻小俱全的 web 容器NettyWeb
- 從頭寫個http client(java)HTTPclientJava
- netty系列之:從零到壹,搭建一個SOCKS代理伺服器Netty伺服器
- Netty 框架學習 —— 第一個 Netty 應用Netty框架
- 手寫一個HTTP框架:兩個類實現基本的IoC功能HTTP框架
- 開發一個簡單的 HTTP 伺服器應用HTTP伺服器
- 如何用Netty寫一個高效能的分散式服務框架Netty分散式框架
- 基於Java NIO 寫的一個簡單版 Netty 服務端JavaNetty服務端
- netty系列之:搭建客戶端使用http1.1的方式連線http2伺服器Netty客戶端HTTP伺服器
- Lua-http庫寫一個爬蟲程式怎麼樣 ?HTTP爬蟲
- 手寫一個最迷你的Web伺服器Web伺服器
- 深入學習用 Go 編寫 HTTP 伺服器GoHTTP伺服器
- netty系列之:效能為王!建立多路複用http2伺服器NettyHTTP伺服器
- C#實現一個最簡單的HTTP伺服器C#HTTP伺服器
- HTTP代理伺服器的三個特性HTTP伺服器
- Pingora:替代Nginx、Rust編寫的HTTP伺服器GoNginxRustHTTP伺服器