首页 > 其他分享 >Springboot+Netty实现http和ws统一端口处理

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

时间:2024-05-07 13:45:19浏览次数:11  
标签:Netty http Springboot netty io import public channel

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

相关文章

  • GRPC与HTTP/3.0
    弱网环境下的表现不同GRPC是基于HTTP/2.0协议开发的,HTTP/2.0通过以下举措在性能方面有极大的提升:引出了Stream概念,多个Stream可以复用在一条TCP连接,解决了HTTP/1.1的队头阻塞问题(在一条TCP连接上服务端对多个请求的响应只能一个一个同步的响应,即使多个请求是并发的)开发了......
  • Java发送HTTP GET/POST请求
    一、Java11HttpClient在Java11的java.net.http.*包中,有一个HttpClient类可以完成HTTP请求。Java11HttpClientExample.javapackagecom.lyl.http;importjava.net.URI;importjava.net.URLEncoder;importjava.net.http.HttpClient;importjava.net.http.HttpRequest;im......
  • SpringBoot集成WebSocket
    SpringBoot集成WebSocket1.引jar包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency&......
  • https加密机制
    参考:https://www.cnblogs.com/sxiszero/p/11133747.htmlhttps://www.cnblogs.com/technology178/p/14094375.html对称加密:只用一个秘钥的加解密,如果秘钥进行了泄漏,导致数据不安全非对称加密:非对称加密算法需要一组密钥对,分别是公钥和私钥,这两个密钥是成对出现的。公钥加密的内......
  • springboot在2.4以后版本使用application.yml替换bootstrap.yml
    首先确认你的springboot版本是高于2.4的版本的,然后移除以下依赖<!--<dependency>--><!--<groupId>org.springframework.cloud</groupId>--><!--<artifactId>spring-cloud-starter-bootstrap</artifactId>--><!--</d......
  • springboot~CompletableFuture并行计算
    在Spring中,CompletableFuture通常用于异步编程,可以方便地处理异步任务的执行和结果处理,CompletableFuture是Java8引入的一个类,用于支持异步编程和并发操作。它基于Future和CompletionStage接口,提供了丰富的方法来处理异步任务的执行和结果处理。下面是CompletableFuture......
  • 3. SpringBoot 整合第三方技术
    1.整合Junit一般来说是不需要进行处理的,因为在创建SpringBoot工程时,会自动整合junit​的要说怎么配置的话?也可以写一下相关的配置:以下就是SpringBoot整合Junit相关步骤导入相关依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-b......
  • Camunda 整合SpringBoot基本Api
    代码实现:需要接口@AutowiredprivateRuntimeServiceruntimeService;@AutowiredprivateRepositoryServicerepositoryService;@AutowiredprivateTaskServicetaskService;发布流程:@GetMapping("/deploy")publicObjectdeploy(){......
  • [java与https]第一篇、证书杂谈
    一、算法、密钥(对)、证书、证书库令狐冲是个马场老板,这天,他接到店里伙计电话,说有人已经签了租马合同,准备到马场提马,,他二话不说,突突突就去了,到了之后,发现不认识租客。令狐冲说,你把你租马合同给我看看,这就是证书。没成想这租客是个二道贩子,他呼啦一下掏出来一个装满租马合同的文件......
  • SpringBoot3.1.5对应新版本SpringCloud开发(2)-Eureka的负载均衡
    Eureka的负载均衡负载均衡原理负载均衡流程老版本流程介绍当order-servic发起的请求进入Ribbon后会被LoadBalancerInterceptor负载均衡拦截器拦截,拦截器获取到请求中的服务名称,交给RibbonLoadBanlancerCient,然后RibbonLoadBanlancerCient会将服务名称当作服务id交给Dynamic......