http:/localhost:8080/api
ws:/localhost:8080/ws
核心就是两个channel处理器,http和ws
websocket
package com.example.netty;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class MyTextWebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext,
WebSocketFrame webSocketFrame) throws Exception {
log.info("MyTextWebSocketFrameHandler:{}",
webSocketFrame.content().toString(io.netty.util.CharsetUtil.UTF_8));
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
WebSocketServerProtocolHandler.HandshakeComplete handshakeCompletedEvent = (WebSocketServerProtocolHandler.HandshakeComplete) evt;
String uri = handshakeCompletedEvent.requestUri(); // 握手请求 URI
HttpHeaders headers = handshakeCompletedEvent.requestHeaders(); // 握手请求头
log.info("HandshakeComplete:{}", uri);
log.info("HandshakeComplete:{}", headers);
}
}
}
http
package com.example.netty;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
/**
* <p>
* description:
* </p>
*
*/
@Slf4j
public class MyHttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
String url = request.uri();
if (url.endsWith("/api")) { //接口相关
apiHandler(ctx, request);
}
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK, Unpooled.wrappedBuffer("OK".getBytes()));
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
private void apiHandler(ChannelHandlerContext ctx, FullHttpRequest request) {
// 获取通道
Channel channel = ctx.channel();
//请求内容
String body = request.content().toString(CharsetUtil.UTF_8);
//请求Type
String method = request.method().name();
log.info("请求内容:{},请求Type:{}", body, method);
}
}
为netty创建配置注入ioc容器
package com.example.config;
import com.example.netty.MyHttpHandler;
import com.example.netty.MyTextWebSocketFrameHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
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.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.cors.CorsConfig;
import io.netty.handler.codec.http.cors.CorsConfigBuilder;
import io.netty.handler.codec.http.cors.CorsHandler;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class NettyConfiguration {
@Bean(destroyMethod = "shutdownGracefully")
public EventLoopGroup bossGroup() {
return new NioEventLoopGroup();
}
@Bean(destroyMethod = "shutdownGracefully")
public EventLoopGroup workerGroup() {
return new NioEventLoopGroup();
}
@Bean
public ServerBootstrap serverBootstrap() {
return new ServerBootstrap();
}
@Bean
public Channel serverChannel(EventLoopGroup bossGroup, EventLoopGroup workerGroup, ServerBootstrap serverBootstrap) {
return serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
// Add more configuration here, like child handlers for HTTP and WebSocket
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
// 跨域配置
CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();
ch.pipeline().addLast(new CorsHandler(corsConfig));
ch.pipeline().addLast(new HttpServerCodec()); // HTTP 编解码
ch.pipeline().addLast(new ChunkedWriteHandler()); // 支持大文件传输
ch.pipeline().addLast(new HttpObjectAggregator(65536)); // HTTP 消息聚合
ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws")); // WebSocket 协议处理
ch.pipeline().addLast(new MyTextWebSocketFrameHandler()); // WebSocket 文本帧处理
ch.pipeline().addLast(new MyHttpHandler()); // HTTP 请求处理
}
})
.bind(8080).syncUninterruptibly().channel();
}
}
创建Netty 服务
package com.example.netty;
import io.netty.channel.Channel;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.server.WebServerException;
public class NettyWebServer implements WebServer {
private final Channel channel;
public NettyWebServer(Channel channel) {
this.channel = channel;
}
@Override
public void start() throws WebServerException {
// No-op: Netty server starts immediately after channel is bound
}
@Override
public void stop() throws WebServerException {
channel.close().syncUninterruptibly();
}
@Override
public int getPort() {
return 8080;
}
}
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.3</version>
</dependency>
<!-- netty4.1.42-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.42.Final</version>
</dependency>
标签:Netty,http,Springboot,netty,io,import,public,channel
From: https://www.cnblogs.com/MnysLjj/p/18177065