Netty Http server & Client

一:Http Server

package com.taoyuanforrest.nettyserver;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public final class HttpServer {

    static final int PORT = 8080;

    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.option(ChannelOption.SO_BACKLOG, 1024);
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new HttpServerInitializer());

            Channel ch = b.bind(PORT).sync().channel();

            ch.closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

package com.taoyuanforrest.nettyserver;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;

public class HttpServerInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    public void initChannel(SocketChannel ch) {
        ChannelPipeline p = ch.pipeline();
        p.addLast(new HttpResponseEncoder());
        p.addLast(new HttpRequestDecoder());
        p.addLast(new HttpServerHandler());
    }
}

package com.taoyuanforrest.nettyserver;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;

import static io.netty.handler.codec.http.HttpHeaders.Names.*;
import static io.netty.handler.codec.http.HttpHeaders.Values;
import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static io.netty.handler.codec.http.HttpVersion.*;

public class HttpServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {

        if (msg instanceof HttpRequest) {
            HttpRequest req = (HttpRequest) msg;
            System.out.println("uri is: " + req.getUri() + " method is: " + req.getMethod());
            boolean keepAlive = HttpHeaders.isKeepAlive(req);
            FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer("hello".getBytes()));
            response.headers().set(CONTENT_TYPE, "text/plain");
            response.headers().set(CONTENT_LENGTH, response.content().readableBytes());

            if (!keepAlive) {
                ctx.write(response).addListener(ChannelFutureListener.CLOSE);
            } else {
                response.headers().set(CONNECTION, Values.KEEP_ALIVE);
                ctx.write(response);
            }
        }
        
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

二:Http Client

package com.taoyuanforrest.nettyclient;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import static io.netty.handler.codec.http.HttpVersion.*;

public final class HttpClient {
	
	static final String SERVER = "127.0.0.1";
	static final int PORT = 8080;
	
    public static void main(String[] args) throws Exception {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(workerGroup)
             .channel(NioSocketChannel.class)
             .handler(new HttpClientInitializer());

            ChannelFuture f = b.connect(SERVER, PORT).sync();
            String uri = "/demo";  
            String msg = "i'm client";  
            DefaultFullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, HttpMethod.POST,  
                    uri, Unpooled.wrappedBuffer(msg.getBytes())); 
            
            request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);  
            request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, request.content().readableBytes());  
            f.channel().write(request);  
            f.channel().flush();  
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
}

package com.taoyuanforrest.nettyclient;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpResponseDecoder;

public class HttpClientInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    public void initChannel(SocketChannel ch) {
        ChannelPipeline p = ch.pipeline();
        p.addLast(new HttpResponseDecoder());
        p.addLast(new HttpRequestEncoder());
        p.addLast(new HttpClientHandler());
    }
}

package com.taoyuanforrest.nettyclient;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponse;

public class HttpClientHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
    	if (msg instanceof HttpResponse) {  
            HttpResponse response = (HttpResponse) msg;  
            System.out.println("CONTENT_TYPE:" + response.headers().get(HttpHeaders.Names.CONTENT_TYPE)); 
        }  
  
        if (msg instanceof HttpContent) {  
        	HttpContent content = (HttpContent)msg;
            ByteBuf buf = content.content();
            System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));
            buf.release();
        } 
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

源码工程:

http://download.csdn.net/detail/sundongsdu/8958995

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这里是一个简单的 Spring Boot + Netty Client + Netty Server 的示例代码: 首先,创建一个 Netty Server 类,用于接收客户端连接并处理消息: ```java @Component public class NettyServer { private static final Logger logger = LoggerFactory.getLogger(NettyServer.class); @Value("${netty.server.port}") private Integer port; private ChannelFuture serverChannelFuture; @Autowired private NettyServerInitializer nettyServerInitializer; @PostConstruct public void start() throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap() .group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(nettyServerInitializer) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); serverChannelFuture = bootstrap.bind(port).sync(); logger.info("Netty Server started on port {}.", port); serverChannelFuture.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } @PreDestroy public void stop() { serverChannelFuture.channel().close(); } } ``` 其中,`NettyServerInitializer` 类是一个 `ChannelInitializer` 的实现,用于初始化服务器的 ChannelPipeline,这里就不贴出来了。 接下来,创建一个 Netty Client 类,用于向服务器发送消息,并接收服务器的响应: ```java @Component public class NettyClient { private static final Logger logger = LoggerFactory.getLogger(NettyClient.class); @Value("${netty.server.host}") private String host; @Value("${netty.server.port}") private Integer port; private ChannelFuture clientChannelFuture; @Autowired private NettyClientInitializer nettyClientInitializer; public void start() throws InterruptedException { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap() .group(group) .channel(NioSocketChannel.class) .handler(nettyClientInitializer); clientChannelFuture = bootstrap.connect(host, port).sync(); logger.info("Netty Client connected to {}:{}", host, port); clientChannelFuture.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } public void sendMessage(String message) { if (clientChannelFuture != null && clientChannelFuture.channel().isActive()) { clientChannelFuture.channel().writeAndFlush(message); logger.info("Sent message to server: {}", message); } else { logger.error("Netty Client is not connected to the server."); } } } ``` 同样地,`NettyClientInitializer` 类也是一个 `ChannelInitializer` 的实现,用于初始化客户端的 ChannelPipeline。 最后,我们可以在 Spring Boot 应用中使用这两个组件: ```java @SpringBootApplication public class NettyDemoApplication { public static void main(String[] args) { SpringApplication.run(NettyDemoApplication.class, args); } @Autowired private NettyClient nettyClient; @Scheduled(fixedDelay = 1000) public void sendMessageToServer() { nettyClient.sendMessage("Hello, Netty Server!"); } } ``` 这里使用了 Spring Boot 的 `@Autowired` 和 `@Scheduled` 注解,每隔一秒钟向服务器发送一条消息。 以上就是一个简单的 Spring Boot + Netty Client + Netty Server 的示例代码,你可以根据自己的需要进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值