本博客 貓叔的博客,轉載請申明出處php
閱讀本文約 「8分鐘」java
適讀人羣:Java初級mysql
InChat = Iot Netty Chatgit
首先,感謝那些一直以來支持InChat的朋友們,大家多是由於工做緣由,或者本身的想法,或者本身的項目等等。github
InChat還不是一個合格的框架,它還存在不少弊端與問題,可是感謝大家的關注,也是大家讓它學會成長。web
從新聲明一次,InChat:一個輕量級、高效率的支持多端(應用與硬件Iot)的可分佈式、異步網絡應用通信框架。spring
InChat從1月1.1.3版本後,就中止了更新,期間因爲我的緣由(我後續也不敢保證它的連貫性),當時在8月22號,InChat發佈1.1.4版本,且在9月份預計也會繼續發佈1.1.5版本(因爲1.1.4發現了一些核心問題)sql
接下來,我將詳細介紹1.1.4版本下的一些基本功能,歡迎你們測試,並在這裏提出大家的見解或者問題。數據庫
<dependency>
<groupId>com.github.UncleCatMySelf</groupId>
<artifactId>InChat</artifactId>
<version>1.1.4</version>
</dependency>
複製代碼
因爲在停更期間,不少朋友都問到InChat在SpringBoot等web框架下的使用問題及想法,因此這個Demo是徹底在SpringBoot環境下搭建的。apache
下載地址: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版本也將移除。
若是你們在使用InChat期間報:
Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.
複製代碼
能夠按照以上移除對應的日誌組件。
@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;
}
複製代碼
public class User {
/**id*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String username;
private String password;
}
複製代碼
這裏就簡單用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就是一個常規啓動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的幾個配置類
繼承 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;
}
複製代碼
實現 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;
}
}
複製代碼
繼承 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);
}
}
複製代碼
繼承 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);
}
}
複製代碼
我這裏就簡單意識一下
正常運行,因爲數據存儲,我定時器只存儲一條,你們記得修改下
關於加密,你們能夠構建本身的加密文件,或者使用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將繼續發展。
學習交流羣:728698035
現架構設計(碼農)兼創業技術顧問,不羈平庸,熱愛開源,雜談程序人生與不按期乾貨。