基於InChat的SpringBoot版本通訊聊天數據存儲Demo,附帶詳細流程說明[InChat1.1.4]

本博客 貓叔的博客,轉載請申明出處

閱讀本文約 “8分鐘”

適讀人羣:Java初級

前言

InChat = Iot Netty Chat

首先,感謝那些一直以來支持InChat的朋友們,你們可能是因爲工作原因,或者自己的想法,或者自己的項目等等。

InChat還不是一個合格的框架,它還存在很多弊端與問題,但是感謝你們的關注,也是你們讓它學會成長。

重新聲明一次,InChat:一個輕量級、高效率的支持多端(應用與硬件Iot)的可分佈式、異步網絡應用通訊框架。

InChat從1月1.1.3版本後,就停止了更新,期間由於個人原因(我後續也不敢保證它的連貫性),當時在8月22號,InChat發佈1.1.4版本,且在9月份預計也會繼續發佈1.1.5版本(由於1.1.4發現了一些核心問題)

接下來,我將詳細介紹1.1.4版本下的一些基本功能,歡迎大家測試,並在這裏提出你們的看法或者問題。

InChat版本

<dependency>
  <groupId>com.github.UncleCatMySelf</groupId>
  <artifactId>InChat</artifactId>
  <version>1.1.4</version>
</dependency>

構建SpringBoot的web項目

由於在停更期間,很多朋友都問到InChat在SpringBoot等web框架下的使用問題及想法,所以這個Demo是完全在SpringBoot環境下搭建的。

下載地址:InChat-SpringBoot-Demo,項目中demo-inchat-4.zip文件

這裏建議大家可以直接敲一次,看看有什麼問題。

首先,我的項目是SpringBoot-Web,數據庫是MySQL,沒有使用Redis

pom文件

<?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 https://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.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo-inchat-4</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo-inchat-4</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>com.github.UncleCatMySelf</groupId>
            <artifactId>InChat</artifactId>
            <version>1.1.4</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </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>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

關於pom文件,大家需要注意的是InChat版本其實是自帶log4j,因此可能會和其他的日誌組件有衝突,需要移除,這個在1.1.5版本也將移除。

pom-tree

如果大家在使用InChat期間報:

Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.

可以按照以上移除對應的日誌組件。

賬戶登錄

基本的數據關係

  • Message 聊天消息類
@Entity
@Data
@DynamicUpdate
public class Message {

    /**id,自增*/
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    /** 消息時間 */
    private Date time;

    /** 消息類型(發送給自己、發送給朋友、發送給羣組) */
    private String type;

    /** 消息值(聊天內容) */
    private String value;

    /** 用戶標識(登錄token) */
    private String token;

    /** 羣聊Id */
    private String groudId;

    /** 是否在線-個人(朋友是否在線) */
    private String online;

    /** 是否在線-羣聊(離線朋友) */
    private String onlineGroup;

    /** 消息接收人標識(接收朋友Token) */
    private String one;

}
  • User 用戶登錄(簡單模擬)
public class User {

    /**id*/
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String username;

    private String password;

}

JPA

這裏就簡單用JPA處理,喜歡用MyBatis的朋友也可以試試,歡迎貢獻Demo

啓動類

爲什麼突然說到啓動類呢?

因爲,InChat(1.1.3之前都是在啓動類,啓動的),這可能是一個誤解,在本次Demo中咱們的啓動類是這樣的。

@SpringBootApplication
@EnableScheduling
public class DemoInchat4Application  {

    public static void main(String[] args) {
        SpringApplication.run(DemoInchat4Application.class, args);
    }

}

是的,就這樣,在我的這個業務裏,並沒有打算一開始就啓動InChat,當然這還是要看業務而定

Controller層

這裏的Controller就是一個常規啓動http接口,啓動默認InChat服務。

@RestController
public class UserController {

    @Autowired
    private UserRepository repository;

    @GetMapping("/init")
    public String init(){
        ConfigFactory.initNetty = new MyInit();
        ConfigFactory.fromServerService = FromServerServiceImpl.TYPE2;
        ConfigFactory.listenAsynData = new UserListenAsynData();
        ConfigFactory.inChatVerifyService = new VerifyServiceImpl(repository);
        InitServer.open();
        return "success";
    }

}

大家會發現,我通過一個http啓動InChat,同時將一個UserRepository注入到InChat的校驗類裏面。

啓動。

2019-08-23 17:10:52.399  INFO 20136 --- [         BOSS_1] c.g.u.bootstrap.NettyBootstrapServer     : 服務端啓動成功【192.168.1.121:8070】

接下來介紹下InChat的幾個配置類

InChat配置類——InitNetty

繼承 InitNetty

它是初始化Netty的基本配置,你可以根據你的需要的修改配置

public class MyInit extends InitNetty {

    @Override
    public int getWebport() {
        return 8070;
    }
    //分佈式
    @Override
    public Boolean getDistributed() {
        return false;
    }
    //加密
    @Override
    public boolean isSsl() {
        return false;
    }

InChat配置類——FromServerService

實現 FromServerService

這個與InChat1.1.3版本沒有差別,是一個服務器發送的系統通知,可以通過Http發送任務

public enum  FromServerServiceImpl implements FromServerService {

    TYPE1(1,"【系統通知】您的賬號存在異常,請注意安全保密信息。"),
    TYPE2(2,"【系統通知】恭喜您連續登錄超過5天,獎勵5積分。");

    private Integer code;

    private String message;

    FromServerServiceImpl(Integer code, String message){
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public String findByCode(Object code) {
        Integer codes = (Integer)code;
        for (FromServerServiceImpl item: FromServerServiceImpl.values()) {
            if (item.code == codes){
                return item.message;
            }
        }
        return null;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }


}

InChat配置類——ListenAsynData

繼承 ListenAsynData

異步數據獲取,就是聊天數據獲取的類,在1.1.4中,你需要自己寫一個載體(Map或者list)來存儲聊天數據,我在這個Demo中使用Map,其實可以用list,需要注意,InChat中提供了一個將Map轉爲InChatMessage的工具類MessageChangeUtil,
我希望我的業務不是時刻存儲數據,所以我將聊天數據存儲到Map中,使用定時器,定時存儲到數據庫中。

public class UserListenAsynData extends ListenAsynData {

    @Override
    public void asynData(Map<String, Object> maps) {

        InChatMessage inChatMessage = MessageChangeUtil.Change(maps);
        CacheMap.add(inChatMessage);

    }
}

InChat配置類——InChatVerifyService

繼承 InChatVerifyService

你需要給這個類加一個靜態變量,方便後續初始化後,做數據操作

這個類中的兩個方法,一個是用戶登錄校驗,一個是根據羣聊ID獲取羣聊成員數組

這兩個數據我都默認通過數據庫處理,羣聊ID我是直接模擬,大家可以在數據庫中存儲一個對應的表試試

public class VerifyServiceImpl implements InChatVerifyService {

    private UserRepository repository;

    public VerifyServiceImpl(UserRepository repository){
        this.repository = repository;
    }

    public boolean verifyToken(String token) {
            User user = repository.findByUsername(token);
            if (user.getId() != null){
                return true;
            }
            return false;
    }

    public JSONArray getArrayByGroupId(String groupId) {
        JSONArray jsonArray = JSONArray.parseArray("[\"1111\",\"2222\",\"3333\"]");
        return jsonArray;
    }
}

定時任務

我使用定時任務,定時存儲聊天數據,這裏需要注意,一定要清空存儲過的內容

@Component
public class SchedulerTask {

    @Autowired
    private MessageRepository repository;

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 30000)
    public void reportCurrentTime() {
        System.out.println("現在時間:" + dateFormat.format(new Date()));
        Map<Integer,InChatMessage> Chatcache = CacheMap.copy();
        InChatMessage inChatMessage = Chatcache.get(1);
        Message message = new Message();
        message.setOne(inChatMessage.getOne());
        message.setGroudId(inChatMessage.getGroudId());
        message.setOnline(inChatMessage.getOnline());
        message.setOnlineGroup(inChatMessage.getOnlineGroup());
        message.setToken(inChatMessage.getToken());
        message.setType(inChatMessage.getType());
        message.setValue(inChatMessage.getValue());
        message.setTime(inChatMessage.getTime());
        repository.save(message);
    }
}

我這裏就簡單意識一下

功能測試

單機模式下,發送給自己、發送給別人、發送給羣組(單機,不加密)

danji

正常運行,由於數據存儲,我定時器只存儲一條,大家記得修改下

data

單機,ssl加密,發送給自己、發送給別人、發送給羣組(單機、加密)

jiami

關於加密,大家可以構建自己的加密文件,或者使用inchat.jks

大家可以參考InChatV1.1.3版本使用說明

生成自己的jks加密文件,請在 InitNetty類 的繼承類中做對應的修改。

public abstract class InitNetty {

    //...

    /** 是否啓動分佈式 */
    private Boolean isDistributed = false;

    /** 是否啓動加密 */
    private boolean ssl = false;

    private String jksFile = "inchat.jks";

    private String jksStorePassword = "123456";

    private String jksCertificatePassword = "123456";

    //....
}

分佈式,發送數據

本Demo暫不測試,大家有興趣可是在InChatV1.1.3版本使用說明中學習瞭解。

因爲分佈式使用後,兩個Demo項目都會存在數據存儲,這個不在InChat的設計範圍,所以目前推薦大家先使用單機版本

後續的分佈式,會有一個數據存儲的中間雲組件,集中處理聊天的數據存儲問題等

InChat將繼續發展。

公衆號:Java貓說

學習交流羣:728698035

現架構設計(碼農)兼創業技術顧問,不羈平庸,熱愛開源,雜談程序人生與不定期乾貨。

Image Text

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章