Spring boot + LayIM + t-io 實(shí)現(xiàn)文件上傳、 監(jiān)聽(tīng)用戶(hù)狀態(tài)的實(shí)例代碼
前言
今天的主要內(nèi)容是:LayIM消息中圖片,文件的上傳對(duì)接、用戶(hù)狀態(tài)的監(jiān)聽(tīng)、群在線人數(shù)的監(jiān)聽(tīng)。下面我將挨個(gè)介紹。
圖片上傳
關(guān)于Spring boot中的文件上傳的博客很多,我也是摘抄了部分代碼。上傳部分簡(jiǎn)單介紹,主要介紹在開(kāi)發(fā)過(guò)程中遇到的問(wèn)題。首先我們看一下LayIM的相應(yīng)的接口:
layim.config({
//上傳圖片接口
,uploadImage: {url: '/upload/file'}
//上傳文件接口
,uploadFile: {url: '/upload/file'}
//其他代碼
})
是的,沒(méi)錯(cuò)我們只要寫(xiě)兩個(gè)接口就能實(shí)現(xiàn)LayIM中發(fā)圖片,發(fā)文件的功能了,我這里省點(diǎn)事,由于LayIM已經(jīng)判斷了文件類(lèi)型,所以我這里只用了一個(gè)上傳接口。返回的格式是醬紫的:
{"code":0,"msg":"success","data":{"src":"/upload/d8740baa-cf7e-497c-a085-5c6ed9633f35.gif","name":"8.gif"}}
上傳代碼就很簡(jiǎn)單了,獲取文件后綴,生成guid的名稱(chēng),保存到相應(yīng)文件夾下。最后返回LayIM想要的響應(yīng)數(shù)據(jù)。
剛開(kāi)始想的是直接傳到 /resources/static/upload/文件夾下,后來(lái)發(fā)現(xiàn)上傳成功之后訪問(wèn)路徑會(huì)出現(xiàn)404的情況,原因就是:即使文件夾下有那個(gè)文件,但是target相應(yīng)的文件夾下沒(méi)有,所以重新編譯運(yùn)行之后才可以,那這樣肯定不行。于是我就找解決方案,后來(lái)看到這么一種處理方式,就是把每個(gè)文件請(qǐng)求也映射到Controller中的一個(gè)路徑上,然后使用 ResourceLoader 去找響應(yīng)的文件。代碼如下:
/**
* 上傳文件的路徑配置
* */
@Value("${layim.upload.dir}")
private String fileDirPath;
private final ResourceLoader resourceLoader;
@Autowired
public UploadController(ResourceLoader resourceLoader){
this.resourceLoader = resourceLoader;
}
獲取文件代碼,那么在訪問(wèn)那個(gè)文件的時(shí)候,指定文件名,Resource就會(huì)根據(jù)路徑返回相應(yīng)的資源。
/**
* 訪問(wèn)文件路徑,使用resourceLoader獲取文件
* */
@GetMapping(value = "/{filename:.+}")
@ResponseBody
public ResponseEntity<?> getFile(@PathVariable String filename) {
try {
String location = "file:"+ Paths.get(fileDirPath, filename).toString();
Resource resource = resourceLoader.getResource(location);
return ResponseEntity.ok(resource);
} catch (Exception e) {
return ResponseEntity.notFound().build();
}
}
看一下效果:(為了給大家做演示截圖的時(shí)候遇到上傳文件大小限制的問(wèn)題,配置改一下就可以了。)

http: multipart: max-file-size: 30MB max-request-size: 30MB
上文中的代碼 value 配置為:filename:.+,這樣我們?cè)L問(wèn)路徑如果遇到 比如 /abc.jpg 那么就會(huì)匹配上 getFile這個(gè)方法。然后由ResourceLoader幫我們找文件。不過(guò)為了多了解一點(diǎn),我跟蹤了一下源代碼。先看一下DefaultResourceLoader中的getResource方法。
@Override
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
for (ProtocolResolver protocolResolver : this.protocolResolvers) {
Resource resource = protocolResolver.resolve(location, this);
if (resource != null) {
return resource;
}
}
//我們是使用file:開(kāi)頭的
if (location.startsWith("/")) {
return getResourceByPath(location);
}
//這里判斷是不是走 classpath:
else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
try {
//最后將文件地址轉(zhuǎn)化成了url
// Try to parse the location as a URL...
URL url = new URL(location);
return new UrlResource(url);
}
catch (MalformedURLException ex) {
// No URL -> resolve as resource path.
return getResourceByPath(location);
}
}
}
后來(lái)在我調(diào)試的過(guò)程中發(fā)現(xiàn),比如我訪問(wèn)的路徑是 /abc.gif,那么他后臺(tái)就會(huì)轉(zhuǎn)換成這個(gè)地址:file:///G:/JavaProject/SpringBootLayIM/upload/abc.gif ,所以同理,在本機(jī)上直接將這個(gè)地址打開(kāi)也是能夠訪問(wèn)的。上文中的地址(file:///..)就是 layim.upload.dir 的值。同樣,我把文件夾改為resources/static/upload/下同樣適用,因?yàn)?,通過(guò)ResourceLoader,他將文件定位到了服務(wù)器的物理地址。

target下甚至連uplaod文件夾都沒(méi)有,但是文件還是能夠訪問(wèn)到

文件上傳
和圖片用的是同一個(gè)接口,差別在于上傳大文件需要改一下配置,上文中已經(jīng)寫(xiě)到,這里不在詳述。
用戶(hù)在線狀態(tài)
在LayIM的狀態(tài)監(jiān)聽(tīng)中,有這么一項(xiàng):
//監(jiān)聽(tīng)天窗口的切換
layim.on('chatChange', function(res){
console.log(res.data);
});
其實(shí)在讀取列表的時(shí)候就應(yīng)該要加載用戶(hù)在線離線狀態(tài)。不過(guò)這里只演示,當(dāng)窗口切換時(shí)候,查一下對(duì)面的狀態(tài)。所以,在觸發(fā)chatChange事件后,我們向服務(wù)器發(fā)送一條請(qǐng)求。
var t = res.data.type=='friend';
socket.send({
mtype:t? socket.mtype.checkIsOnline:socket.mtype.checkOnlineCount,
id:res.data.id
});
上面有兩個(gè)情況,第一種單聊的時(shí)候,我需要知道對(duì)方的狀態(tài)。第二種,群聊的時(shí)候我想知道有多少人在線。所以稍微做了下區(qū)分。
新加兩個(gè)消息處理類(lèi):

其實(shí)判斷是否在線的代碼如下:
ChannelContext checkChannelContext = Aio.getChannelContextByUserid(channelContext.getGroupContext(),body.getId()); //檢查是否在線 boolean isOnline = checkChannelContext != null && !checkChannelContext.isClosed();
然后封裝消息返回給服務(wù)器。消息流程在 單聊群聊的實(shí)現(xiàn) 中已經(jīng)介紹過(guò),這里不在贅述。
判斷群里有多少人的方法如下:
SetWithLock<ChannelContext> channelLocks = Aio.getChannelContextsByGroup(channelContext.getGroupContext(),body.getId()); int onlineCount = channelLocks.getObj().size();
看一下效果,數(shù)據(jù)量有點(diǎn)小,就兩個(gè)用戶(hù),不過(guò)作為演示還是夠用噠。


另外的賬號(hào)登錄后:


總結(jié)
本篇內(nèi)容不是很多,就是一個(gè)文件的上傳和tio中的個(gè)別api的簡(jiǎn)單應(yīng)用,不過(guò)令我興奮的是在我調(diào)試代碼的時(shí)候,發(fā)現(xiàn)了很多可玩的東西,比如這玩意:

當(dāng)然,作者已經(jīng)在框架介紹中介紹過(guò)了,可以監(jiān)聽(tīng)每個(gè)客戶(hù)端的發(fā)送消息情況,作為統(tǒng)計(jì)之類(lèi)的。所以,下一步可以拿這些數(shù)據(jù)搞一些事情。
最后,由于剩下的內(nèi)容就是一些簡(jiǎn)單的消息歷史記錄,消息的保存,好友申請(qǐng)等增刪改查的東西,后續(xù)不在過(guò)多介紹。項(xiàng)目正式寫(xiě)完之后在發(fā)一篇。接下來(lái)的準(zhǔn)備玩玩t-io里面的數(shù)據(jù)~~(等等,是不是跑偏了,本來(lái)是學(xué)習(xí)springboot的。。。)
代碼地址: https://github.com/fanpan26/SpringBootLayIM
總結(jié)
以上所述是小編給大家介紹的Spring boot + LayIM + t-io 實(shí)現(xiàn)文件上傳、 監(jiān)聽(tīng)用戶(hù)狀態(tài)的實(shí)例代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Java+OpenCV實(shí)現(xiàn)人臉檢測(cè)并自動(dòng)拍照
這篇文章主要為大家詳細(xì)介紹了Java+OpenCV實(shí)現(xiàn)人臉檢測(cè),并調(diào)用筆記本攝像頭實(shí)時(shí)抓拍,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
詳解SpringBoot多跨域請(qǐng)求的支持(JSONP)
跨域是很多項(xiàng)目需要遇到的文章,本篇文章主要介紹了詳解SpringBoot多跨域請(qǐng)求的支持(JSONP),具有一定的參考價(jià)值,有興趣的可以了解一下2017-04-04
使用MyBatis-Plus實(shí)現(xiàn)聯(lián)表查詢(xún)分頁(yè)的示例代碼
本文主要講述了如何在SpringBoot項(xiàng)目中使用MyBatis-Plus的分頁(yè)插件,通過(guò)這個(gè)示例,可以學(xué)會(huì)如何利用MyBatis-Plus進(jìn)行高效的分頁(yè)查詢(xún),感興趣的可以了解一下2024-10-10
Java?C++題解leetcode672燈泡開(kāi)關(guān)示例
這篇文章主要為大家介紹了Java?C++題解leetcode672燈泡開(kāi)關(guān)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
SpringBoot實(shí)現(xiàn)多個(gè)子域共享cookie的示例
本文主要介紹了SpringBoot實(shí)現(xiàn)多個(gè)子域共享cookie的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
Java開(kāi)發(fā)環(huán)境配置教程(win7 64bit)
這篇文章主要為大家詳細(xì)介紹了win7 64bit下Java開(kāi)發(fā)環(huán)境的配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
基于SpringBoot和Vue3的博客平臺(tái)文章詳情與評(píng)論功能實(shí)現(xiàn)
在前面的教程中,我們已經(jīng)實(shí)現(xiàn)了基于Spring Boot和Vue3的發(fā)布、編輯、刪除文章功能以及文章列表與分頁(yè)功能。本教程將引導(dǎo)您實(shí)現(xiàn)博客平臺(tái)的文章詳情與評(píng)論功能,需要的朋友可以參考一下2023-04-04

