package fr.titionfire.ffsaf.ws; import io.quarkus.runtime.annotations.RegisterForReflection; import jakarta.enterprise.context.ApplicationScoped; import jakarta.websocket.*; import jakarta.websocket.server.PathParam; import jakarta.websocket.server.ServerEndpoint; import lombok.AllArgsConstructor; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.logging.Logger; import java.io.*; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @ServerEndpoint("/api/ws/file/{code}") @ApplicationScoped public class FileSocket { private static final Logger logger = Logger.getLogger(FileSocket.class); public static Map sessions = new ConcurrentHashMap<>(); @ConfigProperty(name = "upload_dir") String media; /*@Scheduled(every = "10s") void increment() { sessions.forEach((key, value) -> { if (System.currentTimeMillis() - value.time > 60000) { closeAndDelete(value); if (value.session != null && value.session.isOpen()) { try { value.session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "Timeout")); } catch (IOException e) { StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); logger.error(errors.toString()); } } sessions.remove(key); } }); }*/ @OnOpen public void onOpen(Session session, @PathParam("code") String code) { try { if (sessions.containsKey(code)) { FileRecv fileRecv = sessions.get(code); fileRecv.file = new File(media + "-ext", "record/" + fileRecv.name); fileRecv.fos = new FileOutputStream(fileRecv.file, false); logger.info("Start reception of file: " + fileRecv.file.getAbsolutePath()); } else { session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "File not found")); } } catch (IOException e) { StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); logger.error(errors.toString()); } } @OnClose public void onClose(Session session, @PathParam("code") String code) { if (sessions.containsKey(code)) { FileRecv fileRecv = sessions.get(code); if (fileRecv.fos != null) { try { fileRecv.fos.close(); } catch (IOException e) { StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); logger.error(errors.toString()); } } logger.info("File received: " + fileRecv.file.getAbsolutePath()); sessions.remove(code); } } @OnError public void onError(Session session, @PathParam("code") String code, Throwable throwable) { if (sessions.containsKey(code)) { closeAndDelete(sessions.get(code)); sessions.remove(code); } logger.error("Error on file reception: " + throwable.getMessage()); } @OnMessage public void onMessage(String message, @PathParam("code") String code) { if (message.equals("cancel")) { if (sessions.containsKey(code)) { closeAndDelete(sessions.get(code)); sessions.remove(code); } logger.error("Error file " + code + " are cancel by the client"); } } private void closeAndDelete(FileRecv fileRecv) { if (fileRecv.fos != null) { try { fileRecv.fos.close(); } catch (IOException e) { StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); logger.error(errors.toString()); } } if (fileRecv.file.exists()) { //noinspection ResultOfMethodCallIgnored fileRecv.file.delete(); } } @OnMessage public void onMessage(byte[] data, @PathParam("code") String code) { if (sessions.containsKey(code)) { FileRecv fileRecv = sessions.get(code); try { fileRecv.fos.write(data); } catch (IOException e) { StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); logger.error(errors.toString()); } } } @AllArgsConstructor @RegisterForReflection public static class FileRecv { Session session; String name; File file; FileOutputStream fos; long time; } }