新增远程压缩;修复图片缓存一直不更新的问题
This commit is contained in:
parent
55c28d358c
commit
cd6920b05a
@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
@ -8,7 +7,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
61
pom.xml
61
pom.xml
@ -9,8 +9,8 @@
|
|||||||
<version>1.0</version>
|
<version>1.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@ -61,32 +61,55 @@
|
|||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.graalvm.buildtools</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>native-maven-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
<version>0.9.28</version>
|
<version>3.4.2</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>native</id>
|
|
||||||
<goals>
|
|
||||||
<goal>compile-no-fork</goal>
|
|
||||||
</goals>
|
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
<mainClass>lion.Main</mainClass>
|
<mainClass>lion.Main</mainClass>
|
||||||
<imageName>storageNode</imageName>
|
</manifest>
|
||||||
<fallback>false</fallback>
|
</archive>
|
||||||
<verbose>true</verbose>
|
|
||||||
<quickBuild>true</quickBuild>
|
|
||||||
<buildArgs>
|
|
||||||
<arg>-H:+ReportExceptionStackTraces</arg>
|
|
||||||
</buildArgs>
|
|
||||||
<metadataRepository>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
</metadataRepository>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- <plugin>-->
|
||||||
|
<!-- <groupId>org.graalvm.buildtools</groupId>-->
|
||||||
|
<!-- <artifactId>native-maven-plugin</artifactId>-->
|
||||||
|
<!-- <version>0.9.28</version>-->
|
||||||
|
<!-- <executions>-->
|
||||||
|
<!-- <execution>-->
|
||||||
|
<!-- <id>native</id>-->
|
||||||
|
<!-- <goals>-->
|
||||||
|
<!-- <goal>compile-no-fork</goal>-->
|
||||||
|
<!-- </goals>-->
|
||||||
|
<!-- <phase>package</phase>-->
|
||||||
|
<!-- </execution>-->
|
||||||
|
<!-- </executions>-->
|
||||||
|
<!-- <configuration>-->
|
||||||
|
<!-- <mainClass>lion.Main</mainClass>-->
|
||||||
|
<!-- <imageName>storageNode</imageName>-->
|
||||||
|
<!-- <fallback>false</fallback>-->
|
||||||
|
<!-- <verbose>true</verbose>-->
|
||||||
|
<!-- <quickBuild>true</quickBuild>-->
|
||||||
|
<!-- <buildArgs>-->
|
||||||
|
<!-- <arg>-H:+ReportExceptionStackTraces</arg>-->
|
||||||
|
<!-- </buildArgs>-->
|
||||||
|
<!-- <metadataRepository>-->
|
||||||
|
<!-- <enabled>true</enabled>-->
|
||||||
|
<!-- </metadataRepository>-->
|
||||||
|
<!-- </configuration>-->
|
||||||
|
<!-- </plugin>-->
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|||||||
34
src/main/java/lion/CustomUtil.java
Normal file
34
src/main/java/lion/CustomUtil.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package lion;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class CustomUtil {
|
||||||
|
|
||||||
|
public static AtomicInteger counter = new AtomicInteger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 寻找一定数量的可用端口
|
||||||
|
*
|
||||||
|
* @return 可用端口的起始位置 -1为没有(几乎没有可能)
|
||||||
|
*/
|
||||||
|
public static short _findIdlePort(){
|
||||||
|
for(int i=20000; i<65535; i++){
|
||||||
|
try(ServerSocket ignored = new ServerSocket(i)){
|
||||||
|
return (short) i;
|
||||||
|
}catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,6 +18,8 @@ public class AbstractMessage {
|
|||||||
|
|
||||||
public static final byte MAINTAIN_MESSAGE = 7;
|
public static final byte MAINTAIN_MESSAGE = 7;
|
||||||
|
|
||||||
|
public static final byte FILE_TRANSFER_MESSAGE = 8;
|
||||||
|
|
||||||
public static final byte GALLERY_REQUEST_MESSAGE = 101;
|
public static final byte GALLERY_REQUEST_MESSAGE = 101;
|
||||||
|
|
||||||
public byte messageType;
|
public byte messageType;
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
package lion.Message.Acclerator;
|
||||||
|
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileTransferMessage extends AbstractMessage {
|
||||||
|
{
|
||||||
|
messageType = FILE_TRANSFER_MESSAGE;
|
||||||
|
}
|
||||||
|
String filename;
|
||||||
|
int port;
|
||||||
|
boolean isThumbnail;
|
||||||
|
}
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package lion.Message;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class IdentityMessage extends AbstractMessage{
|
|
||||||
{
|
|
||||||
messageType = IDENTITY_MESSAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +1,10 @@
|
|||||||
package lion.Message;
|
package lion.Message.Main;
|
||||||
|
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class DeleteGalleryMessage extends AbstractMessage{
|
public class DeleteGalleryMessage extends AbstractMessage {
|
||||||
{
|
{
|
||||||
messageType = DELETE_GALLERY_MESSAGE;
|
messageType = DELETE_GALLERY_MESSAGE;
|
||||||
}
|
}
|
||||||
@ -1,10 +1,11 @@
|
|||||||
package lion.Message;
|
package lion.Message.Main;
|
||||||
|
|
||||||
import lion.Domain.GalleryTask;
|
import lion.Domain.GalleryTask;
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class DownloadPostMessage extends AbstractMessage{
|
public class DownloadPostMessage extends AbstractMessage {
|
||||||
{
|
{
|
||||||
messageType = DOWNLOAD_POST_MESSAGE;
|
messageType = DOWNLOAD_POST_MESSAGE;
|
||||||
}
|
}
|
||||||
@ -1,10 +1,11 @@
|
|||||||
package lion.Message;
|
package lion.Message.Main;
|
||||||
|
|
||||||
import lion.Domain.GalleryTask;
|
import lion.Domain.GalleryTask;
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class DownloadStatusMessage extends AbstractMessage{
|
public class DownloadStatusMessage extends AbstractMessage {
|
||||||
GalleryTask[] galleryTasks;
|
GalleryTask[] galleryTasks;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1,10 +1,11 @@
|
|||||||
package lion.Message;
|
package lion.Message.Main;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class GalleryPageQueryMessage extends AbstractMessage{
|
public class GalleryPageQueryMessage extends AbstractMessage {
|
||||||
{
|
{
|
||||||
messageType = GALLERY_PAGE_QUERY_MESSAGE;
|
messageType = GALLERY_PAGE_QUERY_MESSAGE;
|
||||||
}
|
}
|
||||||
@ -1,10 +1,11 @@
|
|||||||
package lion.Message;
|
package lion.Message.Main;
|
||||||
|
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
//请求预览/压缩包
|
//请求预览/压缩包
|
||||||
public class GalleryRequestMessage extends AbstractMessage{
|
public class GalleryRequestMessage extends AbstractMessage {
|
||||||
|
|
||||||
public static final byte SOURCE = 1;
|
public static final byte SOURCE = 1;
|
||||||
public static final byte PREVIEW = 2;
|
public static final byte PREVIEW = 2;
|
||||||
12
src/main/java/lion/Message/Main/IdentityMessage.java
Normal file
12
src/main/java/lion/Message/Main/IdentityMessage.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package lion.Message.Main;
|
||||||
|
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class IdentityMessage extends AbstractMessage {
|
||||||
|
{
|
||||||
|
messageType = IDENTITY_MESSAGE;
|
||||||
|
}
|
||||||
|
String identity;
|
||||||
|
}
|
||||||
9
src/main/java/lion/Message/Main/MaintainMessage.java
Normal file
9
src/main/java/lion/Message/Main/MaintainMessage.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package lion.Message.Main;
|
||||||
|
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
|
|
||||||
|
public class MaintainMessage extends AbstractMessage {
|
||||||
|
{
|
||||||
|
messageType = MAINTAIN_MESSAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,11 +1,12 @@
|
|||||||
package lion.Message;
|
package lion.Message.Main;
|
||||||
|
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class ResponseMessage extends AbstractMessage{
|
public class ResponseMessage extends AbstractMessage {
|
||||||
{
|
{
|
||||||
messageType = RESPONSE_MESSAGE;
|
messageType = RESPONSE_MESSAGE;
|
||||||
}
|
}
|
||||||
@ -1,10 +1,11 @@
|
|||||||
package lion.Message;
|
package lion.Message.Main;
|
||||||
|
|
||||||
import lion.Domain.GalleryTask;
|
import lion.Domain.GalleryTask;
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class UpdateGalleryMessage extends AbstractMessage{
|
public class UpdateGalleryMessage extends AbstractMessage {
|
||||||
{
|
{
|
||||||
messageType = UPDATE_GALLERY_MESSAGE;
|
messageType = UPDATE_GALLERY_MESSAGE;
|
||||||
}
|
}
|
||||||
2
src/main/java/lion/Message/Main/lombok.config
Normal file
2
src/main/java/lion/Message/Main/lombok.config
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
config.stopBubbling=true
|
||||||
|
lombok.equalsAndHashCode.callSuper=call
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package lion.Message;
|
|
||||||
|
|
||||||
public class MaintainMessage extends AbstractMessage{
|
|
||||||
{
|
|
||||||
messageType = MAINTAIN_MESSAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,6 +5,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ByteToMessageCodec;
|
import io.netty.handler.codec.ByteToMessageCodec;
|
||||||
|
import lion.Message.Acclerator.FileTransferMessage;
|
||||||
|
import lion.Message.Main.*;
|
||||||
import lombok.extern.log4j.Log4j;
|
import lombok.extern.log4j.Log4j;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -46,6 +48,7 @@ public class MessageCodec extends ByteToMessageCodec<AbstractMessage> {
|
|||||||
case AbstractMessage.GALLERY_PAGE_QUERY_MESSAGE -> objectMapper.readValue(metadata, GalleryPageQueryMessage.class);
|
case AbstractMessage.GALLERY_PAGE_QUERY_MESSAGE -> objectMapper.readValue(metadata, GalleryPageQueryMessage.class);
|
||||||
case AbstractMessage.IDENTITY_MESSAGE -> objectMapper.readValue(metadata, IdentityMessage.class);
|
case AbstractMessage.IDENTITY_MESSAGE -> objectMapper.readValue(metadata, IdentityMessage.class);
|
||||||
case AbstractMessage.MAINTAIN_MESSAGE -> objectMapper.readValue(metadata, MaintainMessage.class);
|
case AbstractMessage.MAINTAIN_MESSAGE -> objectMapper.readValue(metadata, MaintainMessage.class);
|
||||||
|
case AbstractMessage.FILE_TRANSFER_MESSAGE -> objectMapper.readValue(metadata, FileTransferMessage.class);
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package lion.Service;
|
package lion.Service;
|
||||||
import lion.ErrorCode.ErrorCode;
|
import lion.ErrorCode.ErrorCode;
|
||||||
import lion.Message.GalleryPageQueryMessage;
|
import lion.Message.Main.GalleryPageQueryMessage;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -31,7 +31,7 @@ public class DeliveryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte deliveryPreview(String name, short page, short port){
|
public static byte deliveryPreview(String name, short page, short port){
|
||||||
if(!pageCache.containsKey(name)){
|
if(!pageCache.containsKey(name) || page > pageCache.get(name).size()){ //缓存中不存在或者页数超出缓存数量
|
||||||
byte result;
|
byte result;
|
||||||
if((result = pageCache(name)) != 0)
|
if((result = pageCache(name)) != 0)
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@ -1,26 +1,37 @@
|
|||||||
package lion.Service;
|
package lion.Service;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.DefaultEventLoop;
|
||||||
|
import io.netty.channel.EventLoop;
|
||||||
|
import io.netty.util.concurrent.DefaultPromise;
|
||||||
|
import io.netty.util.concurrent.Promise;
|
||||||
|
import lion.CustomUtil;
|
||||||
import lion.Domain.GalleryTask;
|
import lion.Domain.GalleryTask;
|
||||||
import lion.ErrorCode.ErrorCode;
|
import lion.ErrorCode.ErrorCode;
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.util.ZipUtil;
|
import cn.hutool.core.util.ZipUtil;
|
||||||
|
import lion.Message.AbstractMessage;
|
||||||
|
import lion.Message.Acclerator.FileTransferMessage;
|
||||||
|
import lombok.Data;
|
||||||
import lombok.extern.log4j.Log4j;
|
import lombok.extern.log4j.Log4j;
|
||||||
import org.im4java.core.ConvertCmd;
|
import org.im4java.core.ConvertCmd;
|
||||||
import org.im4java.core.IM4JavaException;
|
import org.im4java.core.IM4JavaException;
|
||||||
import org.im4java.core.IMOperation;
|
import org.im4java.core.IMOperation;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.net.ServerSocket;
|
||||||
import java.util.Arrays;
|
import java.net.Socket;
|
||||||
import java.util.Comparator;
|
import java.nio.file.Files;
|
||||||
import java.util.Iterator;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
|
||||||
@Log4j
|
@Log4j
|
||||||
|
@Data
|
||||||
public class DownloadCheckService {
|
public class DownloadCheckService {
|
||||||
ArrayList<GalleryTask> queue;
|
ArrayList<GalleryTask> queue;
|
||||||
|
|
||||||
@ -32,8 +43,16 @@ public class DownloadCheckService {
|
|||||||
|
|
||||||
ArrayList<GalleryTask> convert_queue;
|
ArrayList<GalleryTask> convert_queue;
|
||||||
|
|
||||||
public DownloadCheckService(ArrayList<GalleryTask> queue){
|
Channel node;
|
||||||
|
|
||||||
|
HashMap<Integer, Promise<AbstractMessage>> promises;
|
||||||
|
|
||||||
|
EventLoop eventLoop;
|
||||||
|
|
||||||
|
public DownloadCheckService(ArrayList<GalleryTask> queue, HashMap<Integer, Promise<AbstractMessage>> promises){
|
||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
|
this.promises = promises;
|
||||||
|
eventLoop = new DefaultEventLoop();
|
||||||
convert_queue = new ArrayList<>(0);
|
convert_queue = new ArrayList<>(0);
|
||||||
convert_thread = new ScheduledThreadPoolExecutor(1);
|
convert_thread = new ScheduledThreadPoolExecutor(1);
|
||||||
convert_thread.scheduleAtFixedRate(this::convert, 0, 5, TimeUnit.SECONDS);
|
convert_thread.scheduleAtFixedRate(this::convert, 0, 5, TimeUnit.SECONDS);
|
||||||
@ -98,7 +117,6 @@ public class DownloadCheckService {
|
|||||||
public void convert() {
|
public void convert() {
|
||||||
if(convert_queue.isEmpty())
|
if(convert_queue.isEmpty())
|
||||||
return;
|
return;
|
||||||
ConvertCmd convertCmd = new ConvertCmd(true);
|
|
||||||
ReentrantLock reentrantLock = new ReentrantLock();
|
ReentrantLock reentrantLock = new ReentrantLock();
|
||||||
reentrantLock.lock();
|
reentrantLock.lock();
|
||||||
ArrayList<GalleryTask> galleryTasks = new ArrayList<>(convert_queue);
|
ArrayList<GalleryTask> galleryTasks = new ArrayList<>(convert_queue);
|
||||||
@ -123,35 +141,15 @@ public class DownloadCheckService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//thumbnail
|
//thumbnail
|
||||||
IMOperation operation = new IMOperation();
|
|
||||||
operation.addImage(images[0].getAbsolutePath());
|
|
||||||
operation.resize(500, 500);
|
|
||||||
operation.format("webp");
|
|
||||||
operation.addImage(storagePath + galleryTask.getName() + "/thumbnail.webp");
|
|
||||||
try {
|
|
||||||
log.info("文件" + images[0].getName() + ",转换为thumbnail.webp");
|
log.info("文件" + images[0].getName() + ",转换为thumbnail.webp");
|
||||||
convertCmd.run(operation);
|
if(!convert_remote(galleryTask, images[0], true))
|
||||||
} catch (IOException | IM4JavaException | InterruptedException e) {
|
convert_local(galleryTask, images[0], true);
|
||||||
log.error("创建" + galleryTask.getName() + "缩略图失败");
|
|
||||||
galleryTask.setStatus(ErrorCode.COMPRESS_ERROR);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((galleryTask.getType() & GalleryTask.DOWNLOAD_PREVIEW) != 0)
|
if ((galleryTask.getType() & GalleryTask.DOWNLOAD_PREVIEW) != 0)
|
||||||
for (int i = 0; i < images.length; i++) {
|
for (int i = 0; i < images.length; i++) {
|
||||||
log.info("文件" + images[i].getName() + ",转换为webp[" + i + "/" + images.length + "]");
|
log.info("文件" + images[i].getName() + ",转换为webp[" + i + "/" + images.length + "]");
|
||||||
operation = new IMOperation();
|
if(!convert_remote(galleryTask, images[i], false))
|
||||||
operation.addImage(images[i].getAbsolutePath());
|
convert_local(galleryTask, images[i], false);
|
||||||
operation.format("webp");
|
|
||||||
operation.resize(2000, 2000);
|
|
||||||
operation.addImage(storagePath + galleryTask.getName() + "/" + images[i].getName().replace(".png", ".webp").replace(".jpg", ".webp"));
|
|
||||||
try {
|
|
||||||
convertCmd.run(operation);
|
|
||||||
} catch (IOException | InterruptedException | IM4JavaException e) {
|
|
||||||
log.error("文件" + images[i].getName() + "转换失败");
|
|
||||||
galleryTask.setStatus(ErrorCode.COMPRESS_ERROR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((galleryTask.getType() & GalleryTask.DOWNLOAD_SOURCE) != 0) {
|
if ((galleryTask.getType() & GalleryTask.DOWNLOAD_SOURCE) != 0) {
|
||||||
@ -163,4 +161,60 @@ public class DownloadCheckService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void convert_local(GalleryTask galleryTask, File file, boolean isThumbnail){
|
||||||
|
ConvertCmd convertCmd = new ConvertCmd(true);
|
||||||
|
IMOperation operation = new IMOperation();
|
||||||
|
operation.addImage(file.getAbsolutePath());
|
||||||
|
|
||||||
|
if(isThumbnail) {
|
||||||
|
operation.resize(500, 500);
|
||||||
|
operation.format("webp");
|
||||||
|
operation.addImage(storagePath + galleryTask.getName() + "/thumbnail.webp");
|
||||||
|
} else {
|
||||||
|
operation.format("webp");
|
||||||
|
operation.addImage(storagePath + galleryTask.getName() + "/" + file.getName().replace(".png", ".webp").replace(".jpg", ".webp"));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
convertCmd.run(operation);
|
||||||
|
} catch (IOException | IM4JavaException | InterruptedException e) {
|
||||||
|
log.error("文件" + file.getName() + "转换失败");
|
||||||
|
galleryTask.setStatus(ErrorCode.COMPRESS_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean convert_remote(GalleryTask galleryTask, File file, boolean isThumbnail){
|
||||||
|
if(node == null || !node.isActive() || file.length() < 1024 * 1024 * 5)
|
||||||
|
return false;
|
||||||
|
int port = CustomUtil._findIdlePort();
|
||||||
|
FileTransferMessage fileTransferMessage = new FileTransferMessage();
|
||||||
|
fileTransferMessage.messageId = CustomUtil.counter.getAndIncrement();
|
||||||
|
fileTransferMessage.setFilename(file.getName());
|
||||||
|
fileTransferMessage.setPort(port);
|
||||||
|
fileTransferMessage.setThumbnail(isThumbnail);
|
||||||
|
|
||||||
|
try(ServerSocket serverSocket = new ServerSocket(port);
|
||||||
|
InputStream inputStream = Files.newInputStream(file.toPath())){
|
||||||
|
node.writeAndFlush(fileTransferMessage).sync();
|
||||||
|
Socket socket = serverSocket.accept();
|
||||||
|
inputStream.transferTo(socket.getOutputStream());
|
||||||
|
socket.close();
|
||||||
|
}catch (IOException | InterruptedException e){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultPromise<AbstractMessage> promise = new DefaultPromise<>(eventLoop);
|
||||||
|
promises.put(fileTransferMessage.messageId, promise);
|
||||||
|
try (Socket socket = new Socket()){
|
||||||
|
boolean result = promise.await(20, TimeUnit.SECONDS);
|
||||||
|
if(!result)
|
||||||
|
return false;
|
||||||
|
fileTransferMessage = (FileTransferMessage) promise.get();
|
||||||
|
socket.connect(new InetSocketAddress("side.lionwebsite.xyz", fileTransferMessage.getPort()));
|
||||||
|
FileOutputStream fileOutputStream = new FileOutputStream(storagePath + galleryTask.getName() + "/" + fileTransferMessage.getFilename());
|
||||||
|
socket.getInputStream().transferTo(fileOutputStream);
|
||||||
|
return true;
|
||||||
|
} catch (InterruptedException | ExecutionException | IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
package lion;
|
package lion;
|
||||||
|
|
||||||
|
import io.netty.util.concurrent.Promise;
|
||||||
import lion.Domain.GalleryTask;
|
import lion.Domain.GalleryTask;
|
||||||
import lion.Message.*;
|
import lion.Message.*;
|
||||||
|
import lion.Message.Acclerator.FileTransferMessage;
|
||||||
|
import lion.Message.Main.*;
|
||||||
import lion.Service.DeleteService;
|
import lion.Service.DeleteService;
|
||||||
import lion.Service.DeliveryService;
|
import lion.Service.DeliveryService;
|
||||||
import lion.Service.DownloadCheckService;
|
import lion.Service.DownloadCheckService;
|
||||||
@ -20,6 +23,7 @@ import java.io.OutputStream;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@ -30,6 +34,8 @@ public class storageNode {
|
|||||||
|
|
||||||
Channel server;
|
Channel server;
|
||||||
|
|
||||||
|
Channel node;
|
||||||
|
|
||||||
DownloadCheckService downloadCheckService;
|
DownloadCheckService downloadCheckService;
|
||||||
|
|
||||||
ArrayList<GalleryTask> queue;
|
ArrayList<GalleryTask> queue;
|
||||||
@ -38,6 +44,10 @@ public class storageNode {
|
|||||||
|
|
||||||
ScheduledExecutorService checkThreadPool;
|
ScheduledExecutorService checkThreadPool;
|
||||||
|
|
||||||
|
HashMap<Integer, Promise<AbstractMessage>> promises;
|
||||||
|
|
||||||
|
EventLoop eventLoop;
|
||||||
|
|
||||||
int counter;
|
int counter;
|
||||||
|
|
||||||
ReentrantLock lock;
|
ReentrantLock lock;
|
||||||
@ -49,6 +59,8 @@ public class storageNode {
|
|||||||
tempQueue = new ArrayList<>(0);
|
tempQueue = new ArrayList<>(0);
|
||||||
lock = new ReentrantLock();
|
lock = new ReentrantLock();
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
promises = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
channelFuture = new ServerBootstrap()
|
channelFuture = new ServerBootstrap()
|
||||||
.channel(NioServerSocketChannel.class)
|
.channel(NioServerSocketChannel.class)
|
||||||
@ -62,12 +74,12 @@ public class storageNode {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.bind(26321);
|
.bind(26321);
|
||||||
log.info("listen port:8080");
|
|
||||||
|
|
||||||
try(Socket socket = new Socket()) {
|
try{
|
||||||
socket.connect(new InetSocketAddress("lionwebsite.xyz", 26322));
|
new Socket().connect(new InetSocketAddress("lionwebsite.xyz", 26322));
|
||||||
|
new Socket().connect(new InetSocketAddress("side.lionwebsite.xyz", 26322));
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
downloadCheckService = new DownloadCheckService(queue);
|
downloadCheckService = new DownloadCheckService(queue, promises);
|
||||||
checkThreadPool = Executors.newScheduledThreadPool(1);
|
checkThreadPool = Executors.newScheduledThreadPool(1);
|
||||||
checkThreadPool.scheduleAtFixedRate(this::mainThread, 5, 5, TimeUnit.SECONDS);
|
checkThreadPool.scheduleAtFixedRate(this::mainThread, 5, 5, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
@ -115,27 +127,42 @@ public class storageNode {
|
|||||||
ArrayList<GalleryTask> queue;
|
ArrayList<GalleryTask> queue;
|
||||||
|
|
||||||
public MyChannelInboundHandlerAdapter(ArrayList<GalleryTask> queue) {
|
public MyChannelInboundHandlerAdapter(ArrayList<GalleryTask> queue) {
|
||||||
super();
|
|
||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
|
AbstractMessage abstractMessage = (AbstractMessage) msg;
|
||||||
|
|
||||||
if(msg instanceof IdentityMessage) {
|
switch (abstractMessage.messageType){
|
||||||
|
case AbstractMessage.FILE_TRANSFER_MESSAGE -> {
|
||||||
|
FileTransferMessage fileTransferMessage = (FileTransferMessage) abstractMessage;
|
||||||
|
Promise<AbstractMessage> abstractMessagePromise = promises.get(fileTransferMessage.messageId);
|
||||||
|
if(abstractMessagePromise != null)
|
||||||
|
abstractMessagePromise.setSuccess(fileTransferMessage);
|
||||||
|
}
|
||||||
|
case AbstractMessage.IDENTITY_MESSAGE -> {
|
||||||
|
IdentityMessage identityMessage = (IdentityMessage) abstractMessage;
|
||||||
|
if(identityMessage.getIdentity().equals("lionwebsite")) {
|
||||||
server = ctx.channel();
|
server = ctx.channel();
|
||||||
log.info("server 上线");
|
log.info("server 上线");
|
||||||
//提交下载
|
} else if(identityMessage.getIdentity().equals("lionwebsiteside")){
|
||||||
}else if(msg instanceof DownloadPostMessage dpm){
|
node = ctx.channel();
|
||||||
|
log.info("node上线");
|
||||||
|
downloadCheckService.setNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case AbstractMessage.DOWNLOAD_POST_MESSAGE -> {
|
||||||
|
DownloadPostMessage dpm = (DownloadPostMessage) abstractMessage;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
queue.add(dpm.getGalleryTask());
|
queue.add(dpm.getGalleryTask());
|
||||||
System.out.println(queue);
|
System.out.println(queue);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
ctx.writeAndFlush(new ResponseMessage(dpm.messageId, (byte) 0));
|
ctx.writeAndFlush(new ResponseMessage(dpm.messageId, (byte) 0));
|
||||||
|
}
|
||||||
//删除本子 全部/预览/源文件
|
case AbstractMessage.DELETE_GALLERY_MESSAGE -> {
|
||||||
}else if(msg instanceof DeleteGalleryMessage deleteGalleryMessage){
|
DeleteGalleryMessage deleteGalleryMessage = (DeleteGalleryMessage) abstractMessage;
|
||||||
byte result = switch (deleteGalleryMessage.getDeleteType()){
|
byte result = switch (deleteGalleryMessage.getDeleteType()){
|
||||||
case DeleteGalleryMessage.DELETE_ALL ->
|
case DeleteGalleryMessage.DELETE_ALL ->
|
||||||
DeleteService.deleteAll(storagePath + deleteGalleryMessage.getGalleryName());
|
DeleteService.deleteAll(storagePath + deleteGalleryMessage.getGalleryName());
|
||||||
@ -147,34 +174,36 @@ public class storageNode {
|
|||||||
};
|
};
|
||||||
ResponseMessage responseMessage = new ResponseMessage(deleteGalleryMessage.messageId, result);
|
ResponseMessage responseMessage = new ResponseMessage(deleteGalleryMessage.messageId, result);
|
||||||
ctx.writeAndFlush(responseMessage);
|
ctx.writeAndFlush(responseMessage);
|
||||||
|
}
|
||||||
//请求预览
|
case AbstractMessage.GALLERY_REQUEST_MESSAGE -> {
|
||||||
}else if(msg instanceof GalleryRequestMessage grm){
|
GalleryRequestMessage grm = (GalleryRequestMessage) abstractMessage;
|
||||||
byte result = DeliveryService.deliveryPreview(grm.getGalleryName(), grm.getPage(), grm.getPort());
|
byte result = DeliveryService.deliveryPreview(grm.getGalleryName(), grm.getPage(), grm.getPort());
|
||||||
|
|
||||||
ResponseMessage responseMessage = new ResponseMessage();
|
ResponseMessage responseMessage = new ResponseMessage();
|
||||||
responseMessage.messageId = grm.messageId;
|
responseMessage.messageId = grm.messageId;
|
||||||
responseMessage.setResult(result);
|
responseMessage.setResult(result);
|
||||||
ctx.writeAndFlush(responseMessage);
|
ctx.writeAndFlush(responseMessage);
|
||||||
|
}
|
||||||
//更新本子 删除原有文件,然后加入到队列
|
case AbstractMessage.UPDATE_GALLERY_MESSAGE -> {
|
||||||
}else if(msg instanceof UpdateGalleryMessage ugm){
|
UpdateGalleryMessage ugm = (UpdateGalleryMessage) abstractMessage;
|
||||||
FileUtil.del(storagePath + ugm.getGalleryTask().getName());
|
FileUtil.del(storagePath + ugm.getGalleryTask().getName());
|
||||||
lock.lock();
|
lock.lock();
|
||||||
queue.add(ugm.getGalleryTask());
|
queue.add(ugm.getGalleryTask());
|
||||||
System.out.println(queue);
|
System.out.println(queue);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
ctx.writeAndFlush(new ResponseMessage(ugm.messageId, (byte) 0));
|
ctx.writeAndFlush(new ResponseMessage(ugm.messageId, (byte) 0));
|
||||||
|
}
|
||||||
}else if(msg instanceof GalleryPageQueryMessage gpqm){
|
case AbstractMessage.GALLERY_PAGE_QUERY_MESSAGE -> {
|
||||||
|
GalleryPageQueryMessage gpqm = (GalleryPageQueryMessage) abstractMessage;
|
||||||
byte result = DeliveryService.pageQuery(gpqm);
|
byte result = DeliveryService.pageQuery(gpqm);
|
||||||
gpqm.setResult(result);
|
gpqm.setResult(result);
|
||||||
ctx.writeAndFlush(gpqm);
|
ctx.writeAndFlush(gpqm);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//修复预览
|
//
|
||||||
|
// //修复预览
|
||||||
//重新生成压缩包
|
//
|
||||||
|
// //重新生成压缩包
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -182,6 +211,10 @@ public class storageNode {
|
|||||||
if(ctx.channel().equals(server)) {
|
if(ctx.channel().equals(server)) {
|
||||||
log.info("server 下线");
|
log.info("server 下线");
|
||||||
server = null;
|
server = null;
|
||||||
|
} else if(ctx.channel().equals(node)){
|
||||||
|
log.info("node 下线");
|
||||||
|
node = null;
|
||||||
|
downloadCheckService.setNode(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user