前言
今天的主要內容是:LayIM消息中圖片,文件的上傳對接、用戶狀態的監聽、群在線人數的監聽。下面我將挨個介紹。
圖片上傳
關於Spring boot中的文件上傳的博客很多,我也是摘抄了部分代碼。上傳部分簡單介紹,主要介紹在開發過程中遇到的問題。首先我們看一下LayIM的相應的接口:
layim.config({ //上傳圖片接口,uploadImage: {url: '/upload/file'} //上傳文件接口,uploadFile: {url: '/upload/file'} //其他代碼})是的,沒錯我們只要寫兩個接口就能實現LayIM中發圖片,發文件的功能了,我這裡省點事,由於LayIM已經判斷了文件類型,所以我這裡只用了一個上傳接口。返回的格式是醬紫的:
{"code":0,"msg":"success","data":{"src":"/upload/d8740baa-cf7e-497c-a085-5c6ed9633f35.gif","name":"8.gif"}}上傳代碼就很簡單了,獲取文件後綴,生成guid的名稱,保存到相應文件夾下。最後返回LayIM想要的響應數據。
剛開始想的是直接傳到/resources/static/upload/文件夾下,後來發現上傳成功之後訪問路徑會出現404的情況,原因就是:即使文件夾下有那個文件,但是target相應的文件夾下沒有,所以重新編譯運行之後才可以,那這樣肯定不行。於是我就找解決方案,後來看到這麼一種處理方式,就是把每個文件請求也映射到Controller中的一個路徑上,然後使用ResourceLoader 去找響應的文件。代碼如下:
/** * 上傳文件的路徑配置* */ @Value("${layim.upload.dir}") private String fileDirPath; private final ResourceLoader resourceLoader; @Autowired public UploadController(ResourceLoader resourceLoader){ this.resourceLoader = resourceLoader; }獲取文件代碼,那麼在訪問那個文件的時候,指定文件名,Resource就會根據路徑返回相應的資源。
/** * 訪問文件路徑,使用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(); } }看一下效果:(為了給大家做演示截圖的時候遇到上傳文件大小限制的問題,配置改一下就可以了。)
http: multipart: max-file-size: 30MB max-request-size: 30MB
上文中的代碼value 配置為:filename:.+,這樣我們訪問路徑如果遇到比如/abc.jpg 那麼就會匹配上getFile這個方法。然後由ResourceLoader幫我們找文件。不過為了多了解一點,我跟踪了一下源代碼。先看一下DefaultResourceLoader中的getResource方法。
@Overridepublic 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:開頭的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 { //最後將文件地址轉化成了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);}}}後來在我調試的過程中發現,比如我訪問的路徑是/abc.gif,那麼他後台就會轉換成這個地址:file:///G:/JavaProject/SpringBootLayIM/upload/abc.gif ,所以同理,在本機上直接將這個地址打開也是能夠訪問的。上文中的地址(file:///..)就是layim.upload.dir的值。同樣,我把文件夾改為resources/static/upload/下同樣適用,因為,通過ResourceLoader,他將文件定位到了服務器的物理地址。
target下甚至連uplaod文件夾都沒有,但是文件還是能夠訪問到
文件上傳
和圖片用的是同一個接口,差別在於上傳大文件需要改一下配置,上文中已經寫到,這裡不在詳述。
用戶在線狀態
在LayIM的狀態監聽中,有這麼一項:
//監聽天窗口的切換layim.on('chatChange', function(res){ console.log(res.data); });其實在讀取列表的時候就應該要加載用戶在線離線狀態。不過這裡只演示,當窗口切換時候,查一下對面的狀態。所以,在觸發chatChange事件後,我們向服務器發送一條請求。
var t = res.data.type=='friend'; socket.send({ mtype:t? socket.mtype.checkIsOnline:socket.mtype.checkOnlineCount, id:res.data.id });上面有兩個情況,第一種單聊的時候,我需要知道對方的狀態。第二種,群聊的時候我想知道有多少人在線。所以稍微做了下區分。
新加兩個消息處理類:
其實判斷是否在線的代碼如下:
ChannelContext checkChannelContext = Aio.getChannelContextByUserid(channelContext.getGroupContext(),body.getId()); //檢查是否在線boolean isOnline = checkChannelContext != null && !checkChannelContext.isClosed();
然後封裝消息返回給服務器。消息流程在單聊群聊的實現中已經介紹過,這裡不在贅述。
判斷群裡有多少人的方法如下:
SetWithLock<ChannelContext> channelLocks = Aio.getChannelContextsByGroup(channelContext.getGroupContext(),body.getId()); int onlineCount = channelLocks.getObj().size();
看一下效果,數據量有點小,就兩個用戶,不過作為演示還是夠用噠。
另外的賬號登錄後:
總結
本篇內容不是很多,就是一個文件的上傳和tio中的個別api的簡單應用,不過令我興奮的是在我調試代碼的時候,發現了很多可玩的東西,比如這玩意:
當然,作者已經在框架介紹中介紹過了,可以監聽每個客戶端的發送消息情況,作為統計之類的。所以,下一步可以拿這些數據搞一些事情。
最後,由於剩下的內容就是一些簡單的消息歷史記錄,消息的保存,好友申請等增刪改查的東西,後續不在過多介紹。項目正式寫完之後在發一篇。接下來的準備玩玩t-io裡面的數據~~(等等,是不是跑偏了,本來是學習springboot的。。。)
代碼地址: https://github.com/fanpan26/SpringBootLayIM
總結
以上所述是小編給大家介紹的Spring boot + LayIM + t-io 實現文件上傳、 監聽用戶狀態的實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!