fix:协议

上级 a4231383
package com.kwan.shuyu.advance_02_protocol;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
/**
* 测试 netty提供的 Http协议接口
*
* @author : qinyingjie
* @version : 2.2.0
* @date : 2023/4/27 19:38
*/
@Slf4j
public class TestHttp {
public static void main(String[] args) {
final NioEventLoopGroup boss = new NioEventLoopGroup();
final NioEventLoopGroup worker = new NioEventLoopGroup();
try {
final ServerBootstrap bs = new ServerBootstrap();
bs.channel(NioServerSocketChannel.class);
bs.group(boss, worker);
bs.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
// 做http服务器端 , 解码器对请求进行解码
ch.pipeline().addLast(new HttpServerCodec());
/**
* SimpleChannelInboundHandler 可以指定 只关心某一种类型的Handler
*/
ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() { // 或者:HttpContent
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
log.debug("******************************************************** Get请求");
// 请求行
log.debug("msg.uri() = " + msg.uri());
log.debug("msg.headers() = " + msg.headers());
// 返回 响应 new DefaultFullHttpResponse(Http协议版本,Http状态码)
final DefaultFullHttpResponse response = new DefaultFullHttpResponse(msg.protocolVersion(), HttpResponseStatus.OK);
final byte[] bytes = "<h1>Hello, World</h1>".getBytes();
response.headers().setInt(CONTENT_LENGTH, bytes.length); // 【告诉客户端 消息长度,防止一直转圈】
response.content().writeBytes(bytes);
// 写回响应
ctx.writeAndFlush(response);
}
});
// 下面自己随便写的
ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpContent>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpContent msg) throws Exception {
log.debug("########################################################## Post请求");
// 请求行
log.debug("msg.toString() = " + msg.toString());
}
});
}
});
final ChannelFuture channelFuture = bs.bind(8080).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
log.error("Server error", e);
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
\ No newline at end of file
package com.kwan.shuyu.advance_02_protocol;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
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.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.Charset;
/**
* 以redis协议 为例 【首先开启redis】
* <b>命令</b> :set key value
* <b>命令内容</b> :set name zhangsan
* 首先 把整个看成一个数组
* <content>
* 协议内容:
* ```
* 3 数组个数
* $3 key命令长度
* set
* $4 key值 内容长度
* name
* $8 value值 内容长度
* zhangsan
* ```
* </content>
*/
@Slf4j
public class TestRedisClient {
public static void main(String[] args) {
final byte[] LINE = {'\r', '\n'};
final NioEventLoopGroup worker = new NioEventLoopGroup();
try {
final Bootstrap bs = new Bootstrap();
bs.channel(NioSocketChannel.class);
bs.group(worker);
bs.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
// 连接建立 运行 ,模拟redis协议 发送数据
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// 分配 ByteBuf
final ByteBuf buf = ctx.alloc().buffer();
buf.writeBytes("*3".getBytes());
buf.writeBytes(LINE);
buf.writeBytes("$3".getBytes());
buf.writeBytes(LINE);
buf.writeBytes("set".getBytes());
buf.writeBytes(LINE);
buf.writeBytes("$4".getBytes());
buf.writeBytes(LINE);
buf.writeBytes("name".getBytes());
buf.writeBytes(LINE);
buf.writeBytes("$8".getBytes());
buf.writeBytes(LINE);
buf.writeBytes("zhanglisi".getBytes());
buf.writeBytes(LINE);
ctx.writeAndFlush(buf);
}
// read事件 接受redis的返回结果
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
final String s = buf.toString(Charset.defaultCharset());
System.out.println("... ... redis返回结果 = " + s);
}
});
}
});
final ChannelFuture channelFuture = bs.connect("localhost", 6379).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
log.error("Client error", e);
} finally {
worker.shutdownGracefully();
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册