InChat-based SpringBook version of Communication Chat Data Storage Demo, with detailed process description [InChat 1.1.4]

Keywords: Java Spring Maven Database

This blog Uncle Cat's Blog For reprinting, please state your origin

Read this article for about "8 minutes"

Readable crowd: Java beginner

Preface

InChat = Iot Netty Chat

First of all, thank you for your support. InChat Friends, you may be working for reasons, or your own ideas, or your own projects and so on.

InChat is not yet a qualified framework. It has many drawbacks and problems, but thank you for your attention and for letting it learn to grow.

Once again, InChat: a lightweight, efficient, multi-terminal (application and hardware Iot) distributed, asynchronous network application communication framework.

InChat stopped updating since January 1.1.3, and for personal reasons (I'm not sure about its consistency in the future). On August 22, InChat released version 1.1.4, and is expected to continue releasing version 1.1.5 in September (because 1.1.4 found some core problems).

Next, I will introduce some basic functions of version 1.1.4 in detail. Welcome to test them, and Here Put forward your opinions or questions.

InChat version

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

Building SpringBoot's web Project

Because many friends asked about the use of InChat in SpringBook and other web frameworks during the suspension period, this Demo was built entirely in SpringBook environment.

Download address: InChat-SpringBoot-Demo The demo-inchat-4.zip file in the project

Here we suggest that you can knock directly once to see what's wrong.

First, my project is SpringBoot-Web, my database is MySQL, and I don't use Redis.

pom file

<?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>

With regard to pom files, it should be noted that the InChat version actually comes with log4j, so it may conflict with other log components and need to be removed, which will also be removed in version 1.1.5.

If you use InChat Period Report:

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

The corresponding log components can be removed according to the above.

Account login

Basic data relationships

  • Message Chat Message Class
@Entity
@Data
@DynamicUpdate
public class Message {

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

    /** Message time */
    private Date time;

    /** Message type (to oneself, to friends, to groups) */
    private String type;

    /** Message value (chat content) */
    private String value;

    /** User ID (login token) */
    private String token;

    /** Group chat Id */
    private String groudId;

    /** Whether Online - Individual (Friends Are Online) */
    private String online;

    /** Whether or not to chat online (offline friends) */
    private String onlineGroup;

    /** Message Receiver ID (Receiving Friend Token) */
    private String one;

}
  • User user login (simple simulation)
public class User {

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

    private String username;

    private String password;

}

JPA

Here is a simple JPA processing, like to use MyBatis friends can also try, welcome to contribute Demo

Startup class

Why suddenly talk about boot classes?

Because InChat (all started classes before 1.1.3), this may be a misunderstanding. In this Demo, our start classes are like this.

@SpringBootApplication
@EnableScheduling
public class DemoInchat4Application  {

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

}

Yes, that's it. In my business, I didn't plan to start InChat at the beginning. Of course, it depends on the business.

Controller layer

Here Controller is a general way to start the http interface and start the default InChat service.

@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";
    }

}

As you will see, I started InChat through an http and injected a User Repository into InChat's validation class.

Start.

2019-08-23 17:10:52.399 INFO 20136 - [BOSS_1] c.g.u.bootstrap.Netty Bootstrap Server: Server Start Successfully [192.168.1.121:8070]

Next, I will introduce some configuration classes of InChat.

InChat Configuration Class - InitNetty

InitNetty Inheritance

It's the basic configuration for initializing Netty, and you can modify the configuration to suit your needs.

public class MyInit extends InitNetty {

    @Override
    public int getWebport() {
        return 8070;
    }
    //Distributed
    @Override
    public Boolean getDistributed() {
        return false;
    }
    //encryption
    @Override
    public boolean isSsl() {
        return false;
    }

InChat Configuration Class - FromServerService

Implementing FromServer Service

This is not different from InChat version 1.1.3. It's a system notification sent by a server that can send tasks through Http.

public enum  FromServerServiceImpl implements FromServerService {

    TYPE1(1,"[System Notice] There is an exception in your account. Please pay attention to the security and confidentiality information."),
    TYPE2(2,"[Congratulations on your continuous login for more than 5 days, rewarding you with 5 points.");

    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 configuration class -- ListenAsynData

Inheriting ListenAsynData

Asynchronous data acquisition is the class of chat data acquisition. In 1.1.4, you need to write a carrier (Map or list) to store chat data. In this Demo, I use Map, in fact, I can use list. It should be noted that InChat provides a tool class, Message ChangeUtil, which converts Map into InChat Message.
I hope my business doesn't store data all the time, so I store chat data in Map, use timer, and store it in database regularly.

public class UserListenAsynData extends ListenAsynData {

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

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

    }
}

InChat Configuration Class - InChatVerifyService

Inheritance of InChat VerifyService

You need to add a static variable to this class to facilitate data manipulation after subsequent initialization.

Two methods in this class are user login checking and group chat member array acquisition based on group chat ID.

These two data are processed by default through the database, group chat ID I am a direct simulation, you can try to store a corresponding table in the database.

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;
    }
}

Timing tasks

I use timed tasks to store chat data regularly. Here's what I need to pay attention to. Make sure that I empty the stored content.

@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("Now time:" + 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);
    }
}

I'll just have a brief idea.

functional testing

In stand-alone mode, send to oneself, others and groups (stand-alone, not encrypted)

Normal operation, due to data storage, I only store one timer, you remember to modify the following

Single machine, ssl encryption, send to oneself, send to others, send to groups (single machine, encryption)

For encryption, you can build your own encryption file, or use inchat.jks

You can refer to it. Instructions for InChat V1.1.3

Generate your own jks encryption file, please make corresponding modifications in the inheritance class of InitNetty class.

public abstract class InitNetty {

    //...

    /** Whether to Start Distributed */
    private Boolean isDistributed = false;

    /** Whether to start encryption */
    private boolean ssl = false;

    private String jksFile = "inchat.jks";

    private String jksStorePassword = "123456";

    private String jksCertificatePassword = "123456";

    //....
}

Distributed, sending data

This Demo is not tested yet, but you are interested in it. Instructions for InChat V1.1.3 Learn to understand.

Because both Demo projects will have data storage after distributed use, which is not within the design scope of InChat, it is recommended that you use the stand-alone version first.

Follow-up distributed, there will be a data storage mid-cloud component, centralized processing of chat data storage issues, and so on.

InChat will continue to grow.

Public Number: Java Cat Says

Learning Communication Group: 728698035

Architecture design (code farmer) and entrepreneurship technical consultant, uninhibited mediocrity, love open source, chat about the process of life and irregular dry goods.

Posted by sheilam on Fri, 23 Aug 2019 04:32:49 -0700