Netty编程——简单的http服务器

经常看到Tornado的监听端口,身为Javaista,tomcat对底层封装极其丧心病狂,计划开始手撸一个基于Netty的http服务器,并不断完善,顺便学习NIO和RPC

第一个超级简单,hello world,本次编码使用kotlin实现,具体和Java没有太大区别,接下来从netty各个组件开始学习完善优化

  1. channel、eventloop和channelfuture
  2. netty数据容器
  3. 编解码
  4. 多线程
  5. 网络协议


package com.kotlin.server

import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.close
import io.netty.handler.codec.http.HttpRequest
import io.netty.bootstrap.ServerBootstrap
import io.netty.buffer.Unpooled
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelInboundHandlerAdapter
import io.netty.channel.ChannelInitializer
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioServerSocketChannel
import java.io.UnsupportedEncodingException
import io.netty.channel.socket.SocketChannel
import io.netty.handler.codec.http.*


object HttpServer {

    @Throws(InterruptedException::class)
    @JvmStatic
    fun main(args: Array) {
        val bossGroup = NioEventLoopGroup()
        val workerGroup = NioEventLoopGroup()
        try {
            val b = ServerBootstrap()
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel::class.java)
                    .childHandler(object : ChannelInitializer() {
                        @Throws(Exception::class)
                        override fun initChannel(ch: SocketChannel) {
                            val pipeline = ch.pipeline()
                            pipeline.addLast(HttpServerCodec())
                            pipeline.addLast(HttpServerHandler())
                        }
                    })
            val f = b.bind(8080).sync()
            f.channel().closeFuture().sync()
        } finally {
            workerGroup.shutdownGracefully()
            bossGroup.shutdownGracefully()
        }
    }
}

internal class HttpServerHandler : ChannelInboundHandlerAdapter() {

    @Throws(UnsupportedEncodingException::class)
    override fun channelRead(ctx: ChannelHandlerContext, msg: Any) {

        if (msg is HttpRequest) {

            // 请求,解码器将请求转换成HttpRequest对象
           // val request:HttpRequest = msg
            // 获取请求参数
            val queryStringDecoder = QueryStringDecoder(msg.uri())
            var name = "World"
//            if (queryStringDecoder.parameters().get("name") != null) {
//                name = queryStringDecoder.parameters().get("name").get(0)
//            }

            // 响应HTML
            val responseHtml = "Hello, $name"
            val responseBytes = responseHtml.toByteArray(charset("UTF-8"))
            val contentLength = responseBytes.size

            // 构造FullHttpResponse对象,FullHttpResponse包含message body
            val response = DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(responseBytes))
            response.headers().set("Content-Type", "text/html; charset=utf-8")
            response.headers().set("Content-Length", Integer.toString(contentLength))

            ctx.writeAndFlush(response)
        }
    }

    override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
        cause.printStackTrace()
        ctx.close()
    }
}
这样粗浅低层次的POC正对应着本人水平~~

你可能感兴趣的:(Netty)