本博客 貓叔的博客,轉載請申明出處閱讀本文約 「8分鐘」java
適讀人羣:Java初級mysql
InChat = Iot Netty Chat
首先,感謝那些一直以來支持InChat的朋友們,大家多是由於工做緣由,或者本身的想法,或者本身的項目等等。git
InChat還不是一個合格的框架,它還存在不少弊端與問題,可是感謝大家的關注,也是大家讓它學會成長。github
從新聲明一次,InChat:一個輕量級、高效率的支持多端(應用與硬件Iot)的可分佈式、異步網絡應用通信框架。web
InChat從1月1.1.3版本後,就中止了更新,期間因爲我的緣由(我後續也不敢保證它的連貫性),當時在8月22號,InChat發佈1.1.4版本,且在9月份預計也會繼續發佈1.1.5版本(因爲1.1.4發現了一些核心問題)spring
接下來,我將詳細介紹1.1.4版本下的一些基本功能,歡迎你們測試,並在這裏提出大家的見解或者問題。sql
<dependency> <groupId>com.github.UncleCatMySelf</groupId> <artifactId>InChat</artifactId> <version>1.1.4</version> </dependency>
因爲在停更期間,不少朋友都問到InChat在SpringBoot等web框架下的使用問題及想法,因此這個Demo是徹底在SpringBoot環境下搭建的。數據庫
下載地址:InChat-SpringBoot-Demo,項目中demo-inchat-4.zip文件apache
這裏建議你們能夠直接敲一次,看看有什麼問題。json
首先,個人項目是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
現架構設計(碼農)兼創業技術顧問,不羈平庸,熱愛開源,雜談程序人生與不按期乾貨。