Preface
Today's main content is: pictures in LayIM messages, file upload and docking, user status monitoring, and group online users monitoring. I will introduce it one by one below.
Image upload
There are many blogs about file uploads in Spring boot, and I have also excerpted some of the code. The upload part is briefly introduced, mainly introducing the problems encountered during the development process. First, let’s take a look at the corresponding interface of LayIM:
layim.config({ //Upload image interface, uploadImage: {url: '/upload/file'} //Upload file interface, uploadFile: {url: '/upload/file'} //Other code})Yes, that's right, we can implement the function of sending pictures and sending files in LayIM by writing two interfaces. I'll save some trouble here. Since LayIM has judged the file type, I only use one upload interface here. The returned format is:
{"code":0,"msg":"success","data":{"src":"/upload/d8740baa-cf7e-497c-a085-5c6ed9633f35.gif","name":"8.gif"}}Uploading the code is very simple. Get the file suffix, generate the guid name, and save it to the corresponding folder. Finally, return the response data that LayIM wants.
At first I thought about directly passing it to the /resources/static/upload/ folder. Later, I found that the access path will have a 404 situation after the upload is successful. The reason is: even if there is that file in the folder, but there is no target folder , so it can only be recompiled and run, so this will definitely not work. So I looked for a solution. Later I saw a way to handle it, which is to map each file request to a path in the Controller, and then use the ResourceLoader to find the responding file. The code is as follows:
/** * Path configuration for uploading file* */ @Value("${layim.upload.dir}") private String fileDirPath; private final ResourceLoader resourceLoader; @Autowired public UploadController(ResourceLoader resourceLoader){ this.resourceLoader = resourceLoader; }Get the file code, then when accessing that file, specify the file name, and Resource will return the corresponding resource according to the path.
/** * Access the file path and use resourceLoader to get the file* */ @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(); } }Take a look at the effect: (In order to encounter the problem of uploading file size limitation when making demonstration screenshots for everyone, just change the configuration.)
http: multipart: max-file-size: 30MB max-request-size: 30MB
The above code value is configured as: filename:.+, so that if we encounter a method like /abc.jpg, we will match the getFile method. Then ResourceLoader helps us find the file. But to learn more, I followed the source code. Let's first look at the getResource method in the DefaultResourceLoader.
@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;}} //We are using file: if (location.startsWith("/")) {return getResourceByPath(location);} //This is to determine whether to go classpath:else if (location.startsWith(CLASSPATH_URL_PREFIX)) {return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());}else {try { // Finally convert the file address into 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);}}}}Later, during my debugging process, I found that for example, the path I accessed was /abc.gif, then its background would be converted to this address: file:///G:/JavaProject/SpringBootLayIM/upload/abc.gif. So similarly, it is also possible to access by opening this address directly on the machine. The address (file:///..) above is the value of layout.upload.dir . Similarly, I changed the folder to resources/static/upload/, because, through ResourceLoader, it locates the file to the physical address of the server.
There is not even an uplaod folder under target, but the files can still be accessed
File upload
It uses the same interface as the picture. The difference is that uploading large files requires changing the configuration. It has been written above and will not be described in detail here.
User online status
In LayIM's status monitoring, there is this:
//Switching of the monitor skylight is layim.on('chatChange', function(res){ console.log(res.data); });In fact, when reading the list, the user should be loaded offline. However, here is only a demonstration. When the window switches, check the status of the opposite side. So, after the chatChange event is triggered, we send a request to the server.
var t = res.data.type=='friend'; socket.send({ mtype:t? socket.mtype.checkIsOnline:socket.mtype.checkOnlineCount, id:res.data.id });There are two situations above. When I chat alone, I need to know the other party’s status. The second type is that during group chat, I want to know how many people are online. So I made a little difference.
Add two new message processing classes:
In fact, the code to determine whether it is online is as follows:
ChannelContext checkChannelContext = Aio.getChannelContextByUserid(channelContext.getGroupContext(),body.getId()); //Check whether online boolean isOnline = checkChannelContext != null && !checkChannelContext.isClosed();
Then encapsulate the message back to the server. The message process has been introduced in the implementation of single chat group chat, so I will not go into details here.
The following are the ways to determine how many people are in the group:
SetWithLock<ChannelContext> channelLocks = Aio.getChannelContextsByGroup(channelContext.getGroupContext(),body.getId()); int onlineCount = channelLocks.getObj().size();
Look at the effect, the data volume is a bit small, only two users, but it is still enough for a demonstration.
After logging in with another account:
Summarize
This article is not a lot of content, it is just uploading a file and simple applications of individual APIs in Tio. However, what excites me is that when I debug the code, I found a lot of playable things, such as this thing:
Of course, the author has already introduced it in the framework introduction, and can listen to the message sent by each client as statistics and other things. So, the next step is to use this data to do something.
Finally, since the rest is some simple message history, message preservation, friend application and other things that add, delete, modify and check, we will not introduce it too much in the future. I'll post a post after the project is officially written. Next, I will play with the data in t-io~~ (Wait, have you gone astray? I was originally learning springboot...)
Code address: https://github.com/fanpan26/SpringBootLayIM
Summarize
The above is the example code for Spring boot + LayIM + t-io to implement file upload and monitor user status that the editor introduced to you. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!