前言
首先對(duì)于一個(gè)簡(jiǎn)單的聊天室球涛,大家應(yīng)該都有一定的概念了,這里我們省略用戶(hù)模塊的講解校镐,而是單純的先說(shuō)說(shuō)聊天室的幾個(gè)功能:自我對(duì)話(huà)亿扁、好友交流、群聊鸟廓、離線(xiàn)消息等从祝。
今天我們要做的demo就能幫我們做到這一點(diǎn)啦!R铡榔组!
采用框架
我們整個(gè)Demo基本不需要大家花費(fèi)太多時(shí)間但惶,就可以實(shí)現(xiàn)以上的幾個(gè)功能。
首先,我們需要介紹一下我們今天打算采用的框架椎椰,InChat : 一個(gè)輕量級(jí)遥椿、高效率的支持多端(應(yīng)用與硬件Iot)的異步網(wǎng)絡(luò)應(yīng)用通訊框架,采用這個(gè)框架,我們基本上只需要兩三個(gè)類(lèi)就可以實(shí)現(xiàn)我們今天需要的功能了萌狂。
需要了解SSM & SpringBoot 嗎?
InChat 怀泊,本身不依賴(lài)于任何的底層框架茫藏,所以大家只要會(huì)基本的Java語(yǔ)言就可以實(shí)現(xiàn)一套自己的WebSocket聊天室。
框架使用手冊(cè)
關(guān)于詳細(xì)的手冊(cè)說(shuō)明霹琼,大家可以看看官網(wǎng)的介紹:InChatV1.1.0版本使用說(shuō)明
開(kāi)始Demo搭建
構(gòu)建一個(gè)空的Maven項(xiàng)目
我們不需要依賴(lài)其他的Maven包务傲,只要本文提及的框架即可。
com.github.UncleCatMySelfInChat1.1.0-alpha
對(duì)接兩個(gè)接口與實(shí)現(xiàn)
一個(gè)是框架提供給我們用戶(hù)進(jìn)行數(shù)據(jù)保存與讀取的枣申,通過(guò)這個(gè)接口的實(shí)現(xiàn)售葡,我們可以異步拿到每個(gè)聊天的通信數(shù)據(jù)。這里的InChatMessage是一個(gè)框架自定義的通信對(duì)象忠藤。
public class ToDataBaseServiceImpl implements InChatToDataBaseService{
@Override
public Boolean writeMapToDB(InChatMessage message) {
System.out.println(message.toString());
return true;
}
}
還有一個(gè)接口是對(duì)登錄的校驗(yàn)(這里我們審理用戶(hù)登錄與校驗(yàn)?zāi)K挟伙,所以直接返回true即可),還有一個(gè)是返回群聊的數(shù)組信息模孩。
public class verifyServiceImpl implements InChatVerifyService {
@Override
public boolean verifyToken(String token) {
//登錄校驗(yàn)
return true;
}
@Override
public JSONArray getArrayByGroupId(String groupId) {
//根據(jù)群聊id獲取對(duì)應(yīng)的群聊人員ID
JSONArray jsonArray = JSONArray.parseArray("[\"1111\",\"2222\",\"3333\"]");
return jsonArray;
}
}
我們可以再詳細(xì)的說(shuō)下尖阔,獲取群聊信息,是通過(guò)一個(gè)groupId來(lái)獲取對(duì)應(yīng)的用戶(hù)Id數(shù)組榨咐,我們可以自己做一個(gè)數(shù)據(jù)查詢(xún)介却。
核心的框架啟動(dòng)代碼
直接上代碼,然后我們?cè)僦v解一下块茁。
public class DemoApplication {
public static void main(String[] args) {
//配置InChat配置工廠
ConfigFactory.inChatToDataBaseService = new ToDataBaseServiceImpl();
ConfigFactory.inChatVerifyService = new verifyServiceImpl();
//默認(rèn)啟動(dòng)InChat
InitServer initServer = new InitServer(new InitNetty());
initServer.open();
//獲取用戶(hù)值
WebSocketChannelService webSocketChannelService = new WebSocketChannelService();
//啟動(dòng)新線(xiàn)程
new Thread(new Runnable() {
@Override
public void run() {
//設(shè)定默認(rèn)服務(wù)器發(fā)送值
Map map = new HashMap<>();
map.put("server","服務(wù)器");
//獲取控制臺(tái)用戶(hù)想發(fā)送的用戶(hù)Token
Scanner scanner = new Scanner(System.in);
String token = scanner.nextLine();
//獲取用戶(hù)連接
Channel channel = (Channel) webSocketChannelService.getChannel(token);
//調(diào)用接口發(fā)送
webSocketChannelService.sendFromServer(channel,map);
}
}).start();
}
}
好了齿坷,以上已經(jīng)基本完成了我們的聊天室Demo了,是不是很簡(jiǎn)單J浮永淌?
首先,我們將實(shí)現(xiàn)的兩個(gè)類(lèi)昌跌,配置到框架的配置工廠中仰禀,然后啟動(dòng)框架即可照雁,相關(guān)的類(lèi)蚕愤,都是框架提供的。下面的線(xiàn)程是一個(gè)框架的接口饺蚊,以服務(wù)器第一人稱(chēng)發(fā)送給針對(duì)用戶(hù)通知信息萍诱,輸入“1111”,Demo演示的用戶(hù)token值污呼。
關(guān)于前端
InChat : 一個(gè)輕量級(jí)裕坊、高效率的支持多端(應(yīng)用與硬件Iot)的異步網(wǎng)絡(luò)應(yīng)用通訊框架,大家可以直接來(lái)這個(gè)項(xiàng)目下獲取前端頁(yè)面燕酷,或者直接訪問(wèn)這個(gè)地址:https://github.com/UncleCatMySelf/InChat/blob/master/Front-End-Testing/chat.html
對(duì)于這個(gè)前端頁(yè)面籍凝,我們需要更改一下IP地址周瞎。
運(yùn)行調(diào)試項(xiàng)目
接下來(lái)直接啟動(dòng)后端項(xiàng)目,當(dāng)我們看到以下的信息饵蒂,則項(xiàng)目啟動(dòng)成功声诸。
INFO - 服務(wù)端啟動(dòng)成功【192.168.1.121:8090】
這里的IP需要更換以下讀者啟動(dòng)后的IP地址。
接著直接用瀏覽器打開(kāi)chat.html的頁(yè)面即可退盯,關(guān)于js的方法彼乌,大家可以看看InChatV1.1.0版本使用說(shuō)明。
運(yùn)行效果如下:
INFO - 服務(wù)端啟動(dòng)成功【192.168.1.121:8090】
DEBUG - -Dio.netty.buffer.bytebuf.checkAccessible: true
DEBUG - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@68ad4247
INFO - [DefaultWebSocketHandler.channelActive]/192.168.1.121:17330鏈接成功
DEBUG - -Dio.netty.recycler.maxCapacityPerThread: 4096
DEBUG - -Dio.netty.recycler.maxSharedCapacityFactor: 2
DEBUG - -Dio.netty.recycler.linkCapacity: 16
DEBUG - -Dio.netty.recycler.ratio: 8
DEBUG - [id: 0xabb0dbad, L:/192.168.1.121:8090 - R:/192.168.1.121:17330] WebSocket version V13 server handshake
DEBUG - WebSocket version 13 server handshake key: JYErdeATDgbPmgK0mZ+IlQ==, response: YK9ZiJehNP+IwtlkpoVkPt94yWY=
DEBUG - Decoding WebSocket Frame opCode=1
DEBUG - Decoding WebSocket Frame length=31
INFO - [DefaultWebSocketHandler.textdoMessage.LOGIN]
DEBUG - Encoding WebSocket Frame opCode=1 length=33
DEBUG - Decoding WebSocket Frame opCode=1
DEBUG - Decoding WebSocket Frame length=43
INFO - [DefaultWebSocketHandler.textdoMessage.SENDME]
1111
DEBUG - Encoding WebSocket Frame opCode=1 length=28
INFO - 【異步寫(xiě)入數(shù)據(jù)】
InChatMessage{time=Mon Dec 24 10:03:00 CST 2018, type='sendMe', value='', token='1111', groudId='null', online='null', onlineGroup=null, one='null'}
DEBUG - Decoding WebSocket Frame opCode=1
DEBUG - Decoding WebSocket Frame length=56
INFO - [DefaultWebSocketHandler.textdoMessage.SENDTO]
1111
DEBUG - Encoding WebSocket Frame opCode=1 length=41
INFO - 【異步寫(xiě)入數(shù)據(jù)】
InChatMessage{time=Mon Dec 24 10:03:01 CST 2018, type='sendTo', value='', token='1111', groudId='null', online='2222', onlineGroup=null, one='2222'}
DEBUG - Decoding WebSocket Frame opCode=1
DEBUG - Decoding WebSocket Frame length=60
INFO - [DefaultWebSocketHandler.textdoMessage.SENDGROUP]
1111
DEBUG - Encoding WebSocket Frame opCode=1 length=59
INFO - 【異步寫(xiě)入數(shù)據(jù)】
InChatMessage{time=Mon Dec 24 10:03:02 CST 2018, type='sendGroup', value='', token='1111', groudId='2', online='null', onlineGroup=[2222, 3333], one='null'}
1111
DEBUG - Encoding WebSocket Frame opCode=1 length=22