栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Springboot使用Netty集成protobuf开发高性能服务器 (附源码下载)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Springboot使用Netty集成protobuf开发高性能服务器 (附源码下载)

Springboot-cli 开发脚手架系列

Netty系列:Springboot使用Netty集成protobuf开发高性能服务器


文章目录
  • Springboot-cli 开发脚手架系列
  • 简介
    • 1. 下载protoc.exe
    • 2. 编写.proto文件
    • 3. 生成.java 的协议包
    • 4. netty引入协议文件
    • 5. 效果演示
    • 6. 源码分享


简介

首先我们需要使用Netty搭建基础的tcp框架,参考Springboot使用Netty优雅的创建高性能TCP服务器,接下来我们开始集成protubuf。
本博客项目源码地址:

  • 项目源码github地址
  • 项目源码国内gitee地址
1. 下载protoc.exe

官网下载地址

2. 编写.proto文件

编写规则参考官网中文文档
创建message.proto

// 声明使用proto3
syntax = "proto3";
// 包名
option java_package = "com.netty.client.procotol";
// 类名
option java_outer_classname = "MessageBuf";
 
// 消息整合,便于netty导入编码解码器
message Message {
  // 包类型
  PackType packType = 1;
  // 根据包类型多选1
  oneof Pack{
      LoginRequest loginRequest = 2;
	  LoginResponse loginResponse = 3;
	  MessageRequest messageRequest = 4;
	  MessageResponse messageResponse = 5;
  }
  // 包类型枚举
  enum PackType {
     LOGIN_REQ = 0;
	 LOGIN_RESP = 1;
	 MESSAGE_REQ = 2;
	 MESSAGE_RESP = 3;
  }
}
 
// 登录请求,包含用户名
message LoginRequest {
  string username = 1;
  string password = 2;
}

// 登录响应
message LoginResponse {
  int32 code = 1;
  string message = 2;
}
 
// 消息请求
message MessageRequest {
  int32 messageId = 1;
  int32 type = 2;
  string data = 3;
}

// 消息响应
message MessageResponse {
  int32 messageId = 1;
  int32 code = 2;
  string message = 3;
}
3. 生成.java 的协议包

找到第一步下载的protoc.exe,在protoc.exe同目录下执行

# --java_out 输出路径、message.proto 要执行的文件
protoc.exe --java_out=E:lqdprotoc-3.20.1-rc-1-win64bin message.proto

4. netty引入协议文件
  • 在我们tcp项目的基础上加入protobuf依赖
    pom.xml
        
            com.google.protobuf
            protobuf-java
            3.20.1-rc-1
        

复制第三步生成的.java文件到我们的tcp项目中,接下来我们需要把编码器换成我们第三步生成的协议包。
这里的项目开头有介绍搭建教程地址,点开连接根据教程搭建基础框架即可,非常简单,这里就不重复搭建了。

  • 我们修改channel包下的ChannelInit .java,编码解码器改为Protubuf
@Component
@RequiredArgsConstructor
public class ChannelInit extends ChannelInitializer {

    private final MessageHandler messageHandler;

    @Override
    protected void initChannel(SocketChannel channel) {
        channel.pipeline()
                // 心跳时间
                .addLast("idle", new IdleStateHandler(0, 0, 60, TimeUnit.SECONDS))
                // 添加编码解码器
                .addLast(new ProtobufVarint32FrameDecoder())
                // 此处引用我们生成的协议类MessageBuf
                .addLast(new ProtobufDecoder(MessageBuf.Message.getDefaultInstance()))
                .addLast(new ProtobufVarint32LengthFieldPrepender())
                .addLast(new ProtobufEncoder())
                // 添加消息处理器
                .addLast("messageHandler", messageHandler);
    }
}
  • 新增消息构建器,方便我们构建消息体,MessageBuilder .java
public class MessageBuilder {

    
    public static MessageBuf.Message.Builder newLogin(String username, String password) {
        MessageBuf.LoginRequest.Builder loginMes = MessageBuf.LoginRequest.newBuilder().setUsername(username).setPassword(password);
        return MessageBuf.Message.newBuilder().setLoginRequest(loginMes).setPackType(MessageBuf.Message.PackType.LOGIN_REQ);
    }

    
    public static MessageBuf.Message.Builder newLoginResp(String msg, Integer code) {
        MessageBuf.LoginResponse.Builder loginResp = MessageBuf.LoginResponse.newBuilder().setMessage(msg).setCode(code);
        return MessageBuf.Message.newBuilder().setLoginResponse(loginResp).setPackType(MessageBuf.Message.PackType.LOGIN_RESP);
    }

    
    public static MessageBuf.Message.Builder newMessageReq(Integer msgId, String data, Integer type) {
        MessageBuf.MessageRequest.Builder messageReq = MessageBuf.MessageRequest.newBuilder().setMessageId(msgId).setData(data).setType(type);
        return MessageBuf.Message.newBuilder().setMessageRequest(messageReq).setPackType(MessageBuf.Message.PackType.MESSAGE_REQ);
    }

    
    public static MessageBuf.Message.Builder newMessageResp(Integer msgId, String msg, Integer code) {
        MessageBuf.MessageResponse.Builder messageResp = MessageBuf.MessageResponse.newBuilder().setMessageId(msgId).setMessage(msg).setCode(code);
        return MessageBuf.Message.newBuilder().setMessageResponse(messageResp).setPackType(MessageBuf.Message.PackType.MESSAGE_RESP);
    }

}
  • 修改handle包下的消息处理器,MessageHandler .java
@Slf4j
@Component
@ChannelHandler.Sharable
@RequiredArgsConstructor
public class MessageHandler extends SimpleChannelInboundHandler {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MessageBuf.Message message) throws Exception {
        log.debug("n");
        log.debug("channelId:" + ctx.channel().id());
        log.debug("消息类型:{}", message.getPackType().name());
        switch (message.getPackType()) {
            case LOGIN_REQ:
                log.debug("收到登录消息n{}", message.getLoginRequest());
                // 回复客户端
                ctx.writeAndFlush(MessageBuilder.newLoginResp("login successfully", 200));
                break;
            case MESSAGE_REQ:
                log.debug("收到普通消息{}", message.getMessageRequest());
                // 回复客户端
                ctx.writeAndFlush(MessageBuilder.newMessageResp(message.getMessageRequest().getMessageId(), "ok", 200));
                break;
            default:
                log.error("不支持的消息类型");
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.debug("n");
        log.debug("断开连接");
        ChannelStore.closeAndClean(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.debug("n");
        log.debug("成功建立连接,channelId:{}", ctx.channel().id());
        super.channelActive(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.debug("心跳事件时触发");
    }
}
5. 效果演示

这里需要配合client进行测试
protobuf-client搭建教程参考Springboot使用Netty集成protobuf开发客户端(附源码)

6. 源码分享
  • Springboot-cli开发脚手架,集合各种常用框架使用案例,完善的文档,致力于让开发者快速搭建基础环境并让应用跑起来。
  • 项目源码github地址
  • 项目源码国内gitee地址

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/854557.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号