Springboot+Netty实现http和ws统一端口处理

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>
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring BootNetty是两个独立且流行的开发框架。Spring Boot是Java平台上的一种快速开发框架,用于构建微服务和可扩展的应用程序。而Netty是一款高性能的网络通信框架,主要用于构建分布式系统和网络应用。 Spring Boot结合Netty可以实现生产者-消费者模式。在这种模式下,生产者负责产生数据,并通过网络发送给消费者,消费者则接收并处理这些数据。具体实现可以按照以下步骤进行: 1. 首先,使用Spring Boot创建一个生产者应用程序。在该应用程序中,可以使用Netty框架创建一个服务器,接收来自客户端的请求,并将数据发送给消费者。 2. 消费者可以是另一个应用程序,也可以是一个单独的模块。消费者需要使用Netty框架创建一个客户端,连接到生产者的服务器,并接收来自生产者的数据。 3. 在生产者和消费者之间,可以定义一个协议,用于数据的传输和解析。可以使用基于文本的协议,如JSON或XML,也可以使用二进制协议,如Protocol Buffers或MessagePack。 4. 在生产者中,可以定义一个消息队列,用于存储待发送的数据。当有新数据产生时,将其放入消息队列中,然后由Netty服务器从队列中取出数据,并发送给消费者。 5. 消费者在接收到数据后,可以进行相应的处理,例如存储到数据库、发送到另一个系统或进行其他业务逻辑操作。 通过Spring BootNetty的结合,可以实现高性能、可扩展和可靠的生产者-消费者模式。这种模式广泛应用于分布式系统、即时通讯、实时数据处理等领域,能够满足大规模数据传输和处理的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值