bboyjing's blog

CrazyIM学习笔记一【序】

  最近在看《Netty、Redis、Zookeeper高效并发实战》这本书,其中第九章讲了一个IM系统的开发实践。大致看了下,可能由于篇幅问题,源码的实现没有完全写出来。所以打算一步步把源码整理出来,顺便记录一下学习过程,供道友交流参考。该系统主要基于Netty、SpringBoot等组件,数据传输格式使用的是Protobuf,系统中用到了很多关于Netty的知识点,如果不是很了解的话建议看一下该书的前八章。本章节的主要目的是把项目框架搭建好,下面就开始吧。

搭建项目主体

  搭建常规的基于SpringBoot的Mave项目,建一个空项目就可以了,因为后面具体的功能会使用到子模块。pom文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.didadu</groupId>
<artifactId>crazyIM</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>crazyIM</name>
<description>CrazyIM Based Netty</description>
<properties>
<java.version>1.8</java.version>
</properties>
</project>

然后新建一个chatcommon公共子模块,暂时也是个空项目。pom文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>crazyIM</artifactId>
<groupId>cn.didadu</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>chatcommon</artifactId>
</project>

在chatcommon模块中搭建Protobuf环境

  在chatcommon模块的的根目录下新建目录proto,用于存放ProtoBuf相关文件。这一部分的目的是,通过maven插件,编译项目时将ProtoBuf文件转换成Java类。下面写一个小例子测试一下:

  1. 在proto目录中新建文件Msg.proto:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // [开始声明]
    syntax = "proto3";
    //定义protobuf的包名称空间
    package cn.didadu.chatcommon.protobuf;
    // [结束声明]
    // [开始 java 选项配置]
    option java_package = "cn.didadu.chatcommon.protobuf";
    option java_outer_classname = "MsgProtos";
    // [结束 java 选项配置]
    // [开始 消息定义]
    message Msg {
    uint32 id = 1; // Unique ID number for this person.
    string content = 2;
    }
    // [结束 消息定义]
  2. github下载需要的版本,然后下载的可执行文件拷贝到proto目录。

  3. 引入protobuf依赖和引入protobuf-maven-plugin,protobuf的版本号在父项目中管理。pom文件如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
    <artifactId>crazyIM</artifactId>
    <groupId>cn.didadu</groupId>
    <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>chatcommon</artifactId>
    <dependencies>
    <dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    </dependency>
    </dependencies>
    <build>
    <plugins>
    <!-- Protobuf生成Java POJO插件 -->
    <plugin>
    <groupId>org.xolstice.maven.plugins</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.5.0</version>
    <extensions>true</extensions>
    <configuration>
    <!--proto文件路径-->
    <protoSourceRoot>${project.basedir}/proto</protoSourceRoot>
    <!--目标路径-->
    <outputDirectory>${project.build.sourceDirectory}</outputDirectory>
    <!--设置是否在生成java文件之前清空outputDirectory的文件-->
    <clearOutputDirectory>false</clearOutputDirectory>
    <!--临时目录-->
    <temporaryProtoFileDirectory>${project.build.directory}/protoc-temp</temporaryProtoFileDirectory>
    <!--protoc 可执行文件路径-->
    <protocExecutable>${project.basedir}/proto/protoc</protocExecutable>
    </configuration>
    <executions>
    <execution>
    <goals>
    <goal>compile</goal>
    <goal>test-compile</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>
    </project>
  4. 编译文件,即可生成MsgProtos.java类。

  至此环境初步搭建完毕,慢慢再完善,下一章节将实现ProtoBuf协议以及编解码器的相关内容。