dsjang 2024-08-15
Deliver 기능 수정, msgid 관리 큐 수정
@48c5207d058447f49d3959c39ba8d909991e075c
 
src/main/java/com/munjaon/server/api/controller/MessageController.java (deleted)
--- src/main/java/com/munjaon/server/api/controller/MessageController.java
@@ -1,34 +0,0 @@
-package com.munjaon.server.api.controller;
-
-import com.munjaon.server.api.dto.base.ApiResponse;
-import com.munjaon.server.queue.dto.BasicMessageDto;
-import com.munjaon.server.queue.enums.QueueTypeWorker;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@Slf4j
-@RequestMapping("/api/message")
-@RestController
-@RequiredArgsConstructor
-public class MessageController {
-    @PostMapping("/save")
-    public ResponseEntity postSample(@RequestBody BasicMessageDto reqDto) throws ConfigurationException {
-        log.debug("BasicMessageDto : {}", reqDto);
-        if (reqDto.getServiceType() != null && reqDto.getServiceType().equals("4")) {
-            QueueTypeWorker worker = QueueTypeWorker.find("SMS");
-            if (worker != null) {
-                log.debug("queue size : {}", worker.isExistQueue("SMS01"));
-                worker.pushQueue(reqDto);
-            }
-        }
-
-        return new ResponseEntity(ApiResponse.toResponse(200, "OK", reqDto), HttpStatus.OK);
-    }
-}
 
src/main/java/com/munjaon/server/api/controller/SampleController.java (deleted)
--- src/main/java/com/munjaon/server/api/controller/SampleController.java
@@ -1,33 +0,0 @@
-package com.munjaon.server.api.controller;
-
-import com.munjaon.server.api.dto.SampleDto;
-import com.munjaon.server.api.dto.base.ApiResponse;
-import com.munjaon.server.api.service.SampleService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@Slf4j
-@RequestMapping("/api")
-@RestController
-@RequiredArgsConstructor
-public class SampleController {
-    private final SampleService sampleService;
-
-    @PostMapping("/sample")
-    public ResponseEntity postSample(@RequestBody SampleDto sample) throws ConfigurationException {
-        log.debug("sample : {}", sampleService.get());
-        System.out.println("command : " + sample.getCommand());
-
-        /* 설정 Load */
-        sampleService.printConfig();
-
-        return new ResponseEntity(ApiResponse.toResponse(200, "OK", sample), HttpStatus.OK);
-    }
-}
 
src/main/java/com/munjaon/server/api/dto/SampleDto.java (deleted)
--- src/main/java/com/munjaon/server/api/dto/SampleDto.java
@@ -1,12 +0,0 @@
-package com.munjaon.server.api.dto;
-
-import com.munjaon.server.api.dto.base.BaseDto;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.ToString;
-
-@Getter
-@Setter
-@ToString
-public class SampleDto extends BaseDto {
-}
 
src/main/java/com/munjaon/server/api/dto/base/ApiResponse.java (deleted)
--- src/main/java/com/munjaon/server/api/dto/base/ApiResponse.java
@@ -1,31 +0,0 @@
-package com.munjaon.server.api.dto.base;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-@Builder
-public class ApiResponse<T> {
-    /* 응답코드 */
-    private Integer code;
-    /* 응답 메시지 */
-    private String message;
-    /* Response 객체 */
-    private T data;
-
-    public ApiResponse(final Integer code, final String message) {
-        this.code = code;
-        this.message = message;
-    }
-
-    public static <T> ApiResponse<T> toResponse(final Integer code, final String message, final T t) {
-        return ApiResponse.<T>builder().code(code)
-                .message(message)
-                .data(t)
-                .build();
-    }
-}
 
src/main/java/com/munjaon/server/api/dto/base/BaseDto.java (deleted)
--- src/main/java/com/munjaon/server/api/dto/base/BaseDto.java
@@ -1,13 +0,0 @@
-package com.munjaon.server.api.dto.base;
-
-import lombok.Getter;
-import lombok.Setter;
-import lombok.ToString;
-
-@Getter
-@Setter
-@ToString
-public class BaseDto {
-    protected String command;
-    protected String authKey;
-}
 
src/main/java/com/munjaon/server/api/mapper/SampleMapper.java (deleted)
--- src/main/java/com/munjaon/server/api/mapper/SampleMapper.java
@@ -1,8 +0,0 @@
-package com.munjaon.server.api.mapper;
-
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface SampleMapper {
-    int get();
-}
 
src/main/java/com/munjaon/server/api/service/SampleService.java (deleted)
--- src/main/java/com/munjaon/server/api/service/SampleService.java
@@ -1,31 +0,0 @@
-package com.munjaon.server.api.service;
-
-import com.munjaon.server.api.mapper.SampleMapper;
-import com.munjaon.server.cache.service.MemberService;
-import com.munjaon.server.config.ServerConfig;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.springframework.stereotype.Service;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class SampleService {
-    private final SampleMapper sampleMapper;
-
-    private final ServerConfig serverConfig;
-
-    private final MemberService memberService;
-
-    public int get() {
-        return sampleMapper.get();
-    }
-
-    public void printConfig() throws ConfigurationException {
-        log.info("server.run : {}", serverConfig.getString("server.run"));
-        log.info("sms.queue.count : {}", serverConfig.getInt("sms.queue.count"));
-        log.info("member list : {}", memberService.list());
-        log.info("member get : {}", memberService.get("006star"));
-    }
-}
src/main/java/com/munjaon/server/config/RunnerConfiguration.java
--- src/main/java/com/munjaon/server/config/RunnerConfiguration.java
+++ src/main/java/com/munjaon/server/config/RunnerConfiguration.java
@@ -257,8 +257,8 @@
         try {
             String serviceName = "REPORTER";
             int port = serverConfig.getInt(serviceName + ".SERVICE_PORT");
-            ReportServerService reportServerService = new ReportServerService(serviceName, port);
-            reportServerService.start();
+            ReportServer reportServer = new ReportServer(serviceName, port);
+            reportServer.start();
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
src/main/java/com/munjaon/server/queue/pool/SerialQueue.java
--- src/main/java/com/munjaon/server/queue/pool/SerialQueue.java
+++ src/main/java/com/munjaon/server/queue/pool/SerialQueue.java
@@ -1,6 +1,7 @@
 package com.munjaon.server.queue.pool;
 
 import com.munjaon.server.queue.config.QueueConstants;
+import com.munjaon.server.server.service.PropertyLoader;
 import com.munjaon.server.util.FileUtil;
 import lombok.Getter;
 
@@ -47,7 +48,11 @@
             this.channel = new RandomAccessFile(file, "rw").getChannel();
 
             if (file.length() == 0) {
-                serialNo = 0L;
+                String msgid = PropertyLoader.getProp("SERIAL_QUEUE", "MSGID");
+                if (msgid == null) {
+                    msgid = "0";
+                }
+                serialNo = Long.parseLong(msgid);
                 // 헤더 초기화
                 writeData();
             } else {
src/main/java/com/munjaon/server/server/service/PropertyLoader.java
--- src/main/java/com/munjaon/server/server/service/PropertyLoader.java
+++ src/main/java/com/munjaon/server/server/service/PropertyLoader.java
@@ -33,7 +33,7 @@
             value = value.replaceAll("\\$WORK_HOME", System.getProperty("WORK_HOME"));
         }
 
-        return value;
+        return value == null ? null : value.trim();
     }
 
     public synchronized static Properties load() {
src/main/java/com/munjaon/server/server/service/ReportServer.java
--- src/main/java/com/munjaon/server/server/service/ReportServer.java
+++ src/main/java/com/munjaon/server/server/service/ReportServer.java
@@ -1,9 +1,9 @@
 package com.munjaon.server.server.service;
 
 import com.munjaon.server.queue.pool.ReportQueue;
-import com.munjaon.server.server.dto.ConnectUserDto;
 import com.munjaon.server.server.dto.ReportUserDto;
 import com.munjaon.server.server.queue.ReportUserQueue;
+import com.munjaon.server.server.task.ReportServerTask;
 import org.json.simple.JSONObject;
 
 import java.io.File;
@@ -100,6 +100,8 @@
                     if (reportUserDto == null || reportUserDto.isRunningMode()) {
                         continue;
                     }
+                    /* 사용자별 Report Thread 실행 */
+                    new ReportServerTask(selector, key, getName(), logger).run();
                 } else {
                     ReportQueue reportQueue = reportUserDto.getReportQueue();
                     if (reportUserDto.isLogin() && reportQueue != null && reportQueue.isRemainReport()) {
@@ -107,6 +109,7 @@
                             continue;
                         }
                         /* 사용자별 Report Thread 실행 */
+                        new ReportServerTask(selector, key, getName(), logger).run();
                     }
                 }
             } else {
@@ -135,9 +138,14 @@
                     if (reportUserDto == null || reportUserDto.isRunningMode()) {
                         continue;
                     }
-                    saveSystemLog("isReadable");
+                    if (reportUserDto.isLogin()) {
+                        saveSystemLog("[REPORT SERVER READ] [ID : " + reportUserDto.getUserId() + "]");
+                    } else {
+                        saveSystemLog("[REPORT SERVER READ] [FIRST CONNECTION ... ... ... ... ... ... ...]");
+                    }
+                    reportUserDto.setRunningMode(true);
                     /* 사용자별 Report Thread 실행 */
-//                    threadService.submit(selector, key, 2);
+                    new ReportServerTask(selector, key, getName(), logger).run();
                 }
             } else {
                 expireConnectUser(key);
@@ -169,7 +177,8 @@
         }
         try {
             SocketChannel channel = (SocketChannel) key.channel();
-            ConnectUserDto userDto = (ConnectUserDto) key.attachment();
+            ReportUserDto userDto = (ReportUserDto) key.attachment();
+            saveSystemLog("Expire connect user: " + userDto);
             if (userDto != null && userDto.getUserId() != null) {
                 reportUserQueue.removeUser(userDto.getUserId());
 //                connectUserMap.remove(userDto.getUserId());
src/main/java/com/munjaon/server/server/task/CollectServerTask.java
--- src/main/java/com/munjaon/server/server/task/CollectServerTask.java
+++ src/main/java/com/munjaon/server/server/task/CollectServerTask.java
@@ -40,7 +40,7 @@
     private long RUN_FLAG_CHECK_TIME;
 
     /* 클라이언트 요청 데이터 수신  */
-
+    private ByteBuffer headBuffer = ByteBuffer.allocateDirect(Header.HEADER_LENGTH);
     /* 세션이 만료되었는지 체크 */
     private boolean isExpiredYn;
 
@@ -75,53 +75,74 @@
         return IS_SERVER_RUN && IS_RUN_YN;
     }
 
+    /* 로그 헤더 생성 */
+    private String printTaskLog() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("[CollectServerTask]");
+        builder.append("[SERVICE_TYPE : ").append(serviceType).append("]");
+        if (connectUserDto.isLogin()) {
+            builder.append("[ID : ").append(connectUserDto.getUserId()).append("]");
+        } else {
+            builder.append("[FIRST CONNECTION ... ... ... ... ... ... ...]");
+        }
+
+        return builder.toString();
+    }
+
+    private void initHeaderBuffer() {
+        this.headBuffer.clear();
+        for (int loopCnt = 0; loopCnt < Header.HEADER_LENGTH; loopCnt++) {
+            this.headBuffer.put(Packet.SET_DEFAULT_BYTE);
+        }
+        this.headBuffer.position(0);
+    }
+
+    private int readHeader() {
+        initHeaderBuffer();
+        int size = -1;
+        try {
+            size =  channel.read(headBuffer);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return size;
+    }
+
     @Override
     public void run() {
-        saveSystemLog("CollectServerTask is Entered");
-        /* 최초 RUN Flag 체크 */
+        saveSystemLog(printTaskLog() + "[### Start ### ### ### ### ### ### ###]");
+        /* 0. 최초 RUN Flag 체크 */
         reloadRunFlag();
         /* BIND 체크 및 처리 */
         while (isRun()) {
-            /* 만료 여부 체크 */
+            /* 1. 만료 여부 체크 */
             if (isExpiredYn) {
                 break;
             }
-
-            int size = -1;
             try {
-                /* 1. Head 읽기 */
-                ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH);
-                try {
-                    size = channel.read(headBuffer);
-                } catch (IOException e) {}
-                /* 2. Body 읽기 */
+                /* 3. HeadBuffer 읽기 */
+                int size = readHeader();
+                /* 4. Body 읽기 */
                 if (size > 0) {
                     String command = Header.getCommand(headBuffer);
                     switch (Integer.parseInt(command)) {
-                        case 1:
-                            recvBind(channel, headBuffer);
-                            break;
-                        case 3:
-                            recvDeliver(channel, headBuffer);
-                            break;
-                        case 7:
-                            recvLinkCheck(channel);
-                            break;
-                        default:
-                            expireConnectUser();
-                            break;
+                        case 1: recvBind(channel, headBuffer); break;
+                        case 3: recvDeliver(channel, headBuffer); break;
+                        case 7: recvLinkCheck(channel); break;
+                        default: expireConnectUser(); break;
                     }
                 } else if (size == 0) {
-                    Thread.sleep(1);
                     if (System.currentTimeMillis() - connectUserDto.getLastTrafficTime() > ServerConfig.DELIVER_EXEC_CYCLE_TIME) {
                         this.isExpiredYn = true;
                     }
+                    Thread.sleep(1);
                 } else {
                     expireConnectUser();
                 }
-
             } catch (Exception e) {
-                size = -1;
+                /* 세션 만료 여부 */
+                this.isExpiredYn = true;
                 e.printStackTrace();
             }
             /* RUN Flag 체크 */
@@ -129,31 +150,22 @@
         }
         /* 중요 : 사용자 Thread 실행모드 Off */
         connectUserDto.setRunningMode(false);
-        saveSystemLog("CollectServerTask is Finished");
+        saveSystemLog(printTaskLog() + "[### End ### ### ### ### ### ### ###]");
     }
 
     private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
         /* 서비스 중지여부 체크 */
         if (isExpireService()) {
             expireConnectUser();
+            saveSystemLog(printTaskLog() + "[isExpireService : Expired ... ... ... ... ... ... ...]");
             return;
         }
         switch (this.serviceType) {
-            case "SMS":
-                recvSmsDeliver(channel, headBuffer);
-                break;
-            case "LMS":
-                recvLmsDeliver(channel, headBuffer);
-                break;
-            case "MMS":
-                recvMmsDeliver(channel, headBuffer);
-                break;
-            case "KAT":
-                recvKatDeliver(channel, headBuffer);
-                break;
-            case "KFT":
-                recvKftDeliver(channel, headBuffer);
-                break;
+            case "SMS": recvSmsDeliver(channel, headBuffer); break;
+            case "LMS": recvLmsDeliver(channel, headBuffer); break;
+            case "MMS": recvMmsDeliver(channel, headBuffer); break;
+            case "KAT": recvKatDeliver(channel, headBuffer); break;
+            case "KFT": recvKftDeliver(channel, headBuffer); break;
             default:break;
         }
     }
@@ -161,7 +173,6 @@
     private boolean isExpireService() {
         ConnectUserDto checkConnectUserDto = collectUserQueue.getUser(this.serviceType, this.connectUserDto.getUserId());
         MemberDto memberDto = checkConnectUserDto.getMemberDto();
-        saveSystemLog("[isExpireService : " + memberDto.toString() + "]");
         if (memberDto == null) {
             return true;
         }
@@ -233,7 +244,7 @@
                 messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice()));
             }
 
-            saveLog("[SMS] [MESSAGE : " + messageDto.toString() + "]");
+            saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
             QueueTypeWorker worker = QueueTypeWorker.find("SMS");
             if (worker != null) {
                 worker.pushQueue(messageDto);
@@ -266,7 +277,7 @@
                 messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice()));
             }
 
-            saveSystemLog("[LMS] [MESSAGE : " + messageDto.toString() + "]");
+            saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
             QueueTypeWorker worker = QueueTypeWorker.find("LMS");
             if (worker != null) {
                 worker.pushQueue(messageDto);
@@ -315,7 +326,7 @@
                 } else if (i == 2) {
                     messageDto.setUserFileName03(imagePath + File.separator + fileName);
                 }
-                saveSystemLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]");
+                saveSystemLog(printTaskLog() + "[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]");
             }
 
             /* 사용자 단가, 발송망 설정 */
@@ -336,7 +347,7 @@
                 messageDto.setUnitCost(String.valueOf(mmsPrice));
             }
 
-            saveSystemLog("[MMS] [MESSAGE : " + messageDto.toString() + "]");
+            saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
             QueueTypeWorker worker = QueueTypeWorker.find("MMS");
             if (worker != null) {
                 worker.pushQueue(messageDto);
@@ -377,7 +388,7 @@
             JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
 
             messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
-            saveSystemLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
+            saveSystemLog(printTaskLog() + "[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
 
             /* 사용자 단가, 발송망 설정 */
             MemberDto savedMemberDto = null;
@@ -389,7 +400,7 @@
                 messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice()));
             }
 
-            saveSystemLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]");
+            saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
             QueueTypeWorker worker = QueueTypeWorker.find("KAT");
             if (worker != null) {
                 worker.pushQueue(messageDto);
@@ -432,7 +443,7 @@
             JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
 
             messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
-            saveSystemLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
+            saveSystemLog(printTaskLog() + "[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
 
             /* 사용자 단가, 발송망 설정 */
             MemberDto savedMemberDto = null;
@@ -444,7 +455,7 @@
                 messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice()));
             }
 
-            saveSystemLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]");
+            saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
             QueueTypeWorker worker = QueueTypeWorker.find("KFT");
             if (worker != null) {
                 worker.pushQueue(messageDto);
@@ -485,7 +496,7 @@
             if (svc != null) {
                 memberDto = svc.get(id);
             }
-            saveSystemLog("[BIND REQUEST] [ID : " + id + ", PWD : " +  pwd + "]");
+            saveSystemLog(printTaskLog() + "[BIND REQUEST] [ID : " + id + ", PWD : " +  pwd + "]");
             /* Bind Check */
             resultCode = checkBind(memberDto, this.serviceType, id, pwd);
 
@@ -493,9 +504,9 @@
             if ("00".equals(resultCode)) {
                 boolean isPermit = false;
                 if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) {
-                    saveSystemLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP());
-                    saveSystemLog("Customize Toolbar... : " + memberDto.getAllowIpBasic());
-                    saveSystemLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend());
+                    saveSystemLog(printTaskLog() + "[REMOTE IP : " + connectUserDto.getRemoteIP() + "]");
+                    saveSystemLog(printTaskLog() + "[ALLOW IP BASIC : " + memberDto.getAllowIpBasic() + "]");
+                    saveSystemLog(printTaskLog() + "[ALLOW IP EXTEND : " + memberDto.getAllowIpExtend() + "]");
                     if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) {
                         isPermit = true;
                     }
@@ -526,7 +537,7 @@
         }
 
         try {
-            saveSystemLog("[BIND RESULT : " + resultCode + "]");
+            saveSystemLog(printTaskLog() + "[BIND RESULT : " + resultCode + "]");
             channel.write(Bind.makeBindAckBuffer(resultCode));
             if ("00".equals(resultCode) == false) {
                 expireConnectUser();
@@ -623,7 +634,7 @@
 
     private void saveLog(Object obj, boolean isConsoleOutput) {
         if (isConsoleOutput) {
-            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj);
+            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{" + this.serviceName + "}} " + obj);
         }
 
         if (logger == null) {
src/main/java/com/munjaon/server/server/task/ReportServerTask.java
--- src/main/java/com/munjaon/server/server/task/ReportServerTask.java
+++ src/main/java/com/munjaon/server/server/task/ReportServerTask.java
@@ -1,13 +1,13 @@
 package com.munjaon.server.server.task;
 
+import com.munjaon.server.cache.dto.MemberDto;
+import com.munjaon.server.cache.enums.CacheService;
+import com.munjaon.server.cache.service.MemberService;
 import com.munjaon.server.queue.pool.ReportQueue;
 import com.munjaon.server.server.config.ServerConfig;
 import com.munjaon.server.server.dto.ReportDto;
 import com.munjaon.server.server.dto.ReportUserDto;
-import com.munjaon.server.server.packet.Header;
-import com.munjaon.server.server.packet.LinkCheck;
-import com.munjaon.server.server.packet.Packet;
-import com.munjaon.server.server.packet.Report;
+import com.munjaon.server.server.packet.*;
 import com.munjaon.server.server.queue.ReportUserQueue;
 import com.munjaon.server.server.service.PropertyLoader;
 import com.munjaon.server.util.LogUtil;
@@ -37,9 +37,13 @@
     private boolean IS_SERVER_RUN;          // 서버가 구동중인지 여부
     private boolean IS_RUN_YN;
     private long RUN_FLAG_CHECK_TIME;
+    private long SEND_CYCLE_CHECK_TIME;
 
     /* 세션이 만료되었는지 체크 */
     private boolean isExpiredYn;
+    /* 클라이언트 요청 데이터 수신  */
+    private ByteBuffer headBuffer = ByteBuffer.allocateDirect(Header.HEADER_LENGTH);
+    private ReportDto reportDto;    // 전송 리포트
     /* Packet을 전송했는지 여부 */
     private boolean isPacketSendYn;
 
@@ -74,103 +78,277 @@
         return IS_SERVER_RUN && IS_RUN_YN;
     }
 
+    /* 로그 헤더 생성 */
+    private String printTaskLog() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("[ReportServerTask]");
+        if (reportUserDto.isLogin()) {
+            builder.append("[ID : ").append(reportUserDto.getUserId()).append("]");
+        } else {
+            builder.append("[FIRST CONNECTION ... ... ... ... ... ... ...]");
+        }
+
+        return builder.toString();
+    }
+
     @Override
     public void run() {
-        saveSystemLog("ReportServerTask is Entered");
+        saveSystemLog(printTaskLog() + "[### Start ### ### ### ### ### ### ###]");
         /* 최초 RUN Flag 체크 */
         reloadRunFlag();
-        /* BIND 체크 및 처리 */
-        while (isRun()) {
-            /* 만료 여부 체크 */
-            if (isExpiredYn) {
-                break;
+        try {
+            /* BIND 체크 및 처리 */
+            bindInterest();
+            SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
+            while (reportUserDto.isLogin() && isRun()) {
+                /* 만료 여부 체크 */
+                if (isExpiredYn) {
+                    break;
+                }
+//                saveSystemLog("ReportServerTask is Running");
+                try {
+                    sendInterest();
+                    recvInterest();
+                    /* RUN Flag 체크 */
+                    reloadRunFlag();
+                } catch (Exception e) {
+                    this.isExpiredYn = true;
+                    e.printStackTrace();
+                }
             }
-
-            try {
-                sendInterest();
-                /* RUN Flag 체크 */
-                reloadRunFlag();
-            } catch (Exception e) {
-                this.isExpiredYn = true;
-                e.printStackTrace();
-            }
+        } catch (Exception e) {
+            /* 세션 만료 여부 */
+            this.isExpiredYn = true;
+            e.printStackTrace();
         }
         /* 중요 : 사용자 Thread 실행모드 Off */
         reportUserDto.setRunningMode(false);
-        saveSystemLog("ReportServerTask is Finished");
+        saveSystemLog(printTaskLog() + "[### End ### ### ### ### ### ### ###]");
     }
 
-//    private void recvInterest() {
-//        while (isPacketSendYn) {
-//
-//        }
-//        int size = -1;
-//        try {
-//            /* 1. Head 읽기 */
-//            ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH);
-//            try {
-//                size = channel.read(headBuffer);
-//            } catch (IOException e) {}
-//            /* 2. Body 읽기 */
-//            if (size > 0) {
-//                String command = Header.getCommand(headBuffer);
-//                switch (Integer.parseInt(command)) {
-//                    case 1:
-//                        recvBind(channel, headBuffer);
-//                        break;
-//                    case 3:
-//                        recvDeliver(channel, headBuffer);
-//                        break;
-//                    case 7:
-//                        recvLinkCheck(channel);
-//                        break;
-//                    default:
-//                        expireConnectUser();
-//                        break;
-//                }
-//            } else if (size == 0) {
-//                Thread.sleep(1);
-//                if (System.currentTimeMillis() - reportUserDto.getLastTrafficTime() > ServerConfig.REPORT_EXEC_CYCLE_TIME) {
-//                    this.isExpiredYn = true;
-//                }
-//            } else {
-//                expireConnectUser();
-//            }
-//        } catch (Exception e) {
-//            size = -1;
-//            e.printStackTrace();
-//        }
-//    }
+    private void initHeaderBuffer() {
+        this.headBuffer.clear();
+        for (int loopCnt = 0; loopCnt < Header.HEADER_LENGTH; loopCnt++) {
+            this.headBuffer.put(Packet.SET_DEFAULT_BYTE);
+        }
+        this.headBuffer.position(0);
+    }
+
+    private int readHeader() {
+        initHeaderBuffer();
+        int size = -1;
+        try {
+            size =  channel.read(headBuffer);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return size;
+    }
+
+    private void bindInterest() throws IOException {
+//        if (reportUserDto.isLogin() && !isRun()) {
+        if (reportUserDto.isLogin()) {
+            return;
+        }
+        long bind_check_start_time = System.currentTimeMillis();
+        while(true) {
+            /* 1. Head 읽기 */
+            int size = readHeader();
+            /* 2. Body 읽기 */
+            if (size > 0) {
+                String command = Header.getCommand(this.headBuffer);
+                switch (Integer.parseInt(command)) {
+                    case 1 : recvBind(channel, headBuffer); break;
+                    default: expireConnectUser(); break;
+                }
+                /* 패킷 수신한 경우 무조건 루프를 빠져나간다 */
+                break;
+            }
+            /* 3초 이내에 로그인 실패시 종료 */
+            if (System.currentTimeMillis() - bind_check_start_time > ServerConfig.LIMIT_BIND_TIMEOUT) {
+                expireConnectUser();
+                break;
+            }
+        }
+    }
+
+    private void recvBind(SocketChannel channel, ByteBuffer headBuffer) {
+        String resultCode = "00";
+        try {
+            ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH);
+            ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH);
+            channel.read(bodyBuffer);
+            Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer);
+
+            String id = Bind.getBindId(bindBuffer);
+            String pwd = Bind.getBindPwd(bindBuffer);
+
+            MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService();
+            MemberDto memberDto = null;
+            if (svc != null) {
+                memberDto = svc.get(id);
+            }
+            saveSystemLog(printTaskLog() + "[BIND REQUEST] [ID : " + id + ", PWD : " +  pwd + "]");
+            /* Bind Check */
+            resultCode = checkBind(memberDto, id, pwd);
+
+            /* 접속 IP 체크 */
+            if ("00".equals(resultCode)) {
+                boolean isPermit = false;
+                if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) {
+                    saveSystemLog(printTaskLog() + "[REMOTE IP : " + reportUserDto.getRemoteIP() + "]");
+                    saveSystemLog(printTaskLog() + "[ALLOW IP BASIC : " + memberDto.getAllowIpBasic() + "]");
+                    saveSystemLog(printTaskLog() + "[ALLOW IP EXTEND : " + memberDto.getAllowIpExtend() + "]");
+                    if (memberDto.getAllowIpBasic() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) {
+                        isPermit = true;
+                    }
+                    if (memberDto.getAllowIpExtend() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) {
+                        isPermit = true;
+                    }
+                } else {
+                    isPermit = true;
+                }
+                if (isPermit) {
+                    resultCode = "00";
+                } else {
+                    resultCode = "40";
+                }
+            }
+
+            if ("00".equals(resultCode)) {
+                reportUserDto.setUserId(id);
+                reportUserDto.setLogin(true);
+                reportUserDto.setMemberDto(memberDto);
+                /* 리포트 큐 생성 */
+                ReportQueue reportQueue = new ReportQueue(reportUserDto.getQueuePath(), reportUserDto.getUserId());
+                reportUserDto.setReportQueue(reportQueue);
+                /* 사용자 Pool에 저장 */
+                reportUserQueue.putUser(reportUserDto);
+                /* 세션통신 시간 업데이트 */
+                reportUserDto.updateLastTrafficTime();
+            }
+        } catch (Exception e) {
+            resultCode = "10";
+            e.printStackTrace();
+        }
+
+        try {
+            saveSystemLog(printTaskLog() + "[BIND RESULT : " + resultCode + "]");
+            channel.write(Bind.makeBindAckBuffer(resultCode));
+            if ("00".equals(resultCode) == false) {
+                expireConnectUser();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private String checkBind(MemberDto memberDto, String id, String pwd) {
+        if (id == null || pwd == null) {
+            return "50";
+        }
+        if (reportUserQueue.isExist(id)) {
+            return "60";
+        }
+        if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
+            return "20";
+        }
+        /* 회원 사용 상태 */
+        if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
+            return "30";
+        }
+
+        return "00";
+    }
+
+    private void recvInterest() throws IOException, InterruptedException, Exception {
+        while (isPacketSendYn) {
+            /* 1. Head 읽기 */
+            ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH);
+            int size = channel.read(headBuffer);
+            if (size > 0) {
+                String command = Header.getCommand(headBuffer);
+                switch (Integer.parseInt(command)) {
+                    case 6 : recvReport(channel, headBuffer); break;
+                    case 8 : recvLinkCheck(channel, headBuffer); break;
+                    default: saveSystemLog(printTaskLog() + "[INVALID REQUEST][command : " + command + ";");
+                        expireConnectUser(); break;
+                }
+            } else if (size == 0) {
+                Thread.sleep(1);
+                if (System.currentTimeMillis() - reportUserDto.getLastTrafficTime() > ServerConfig.REPORT_EXEC_CYCLE_TIME) {
+                    this.isExpiredYn = true;
+                    break;
+                }
+            } else {
+                saveSystemLog(printTaskLog() + "[recvInterest : size is zero]");
+                expireConnectUser();
+                throw new IOException("[recvInterest : size is zero]");
+            }
+        }
+    }
+
+    private void recvLinkCheck(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
+        ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH);
+        int size = channel.read(bodyBuffer);
+        if (size > 0) {
+            saveSystemLog(printTaskLog() + "[RECEIVER LINK CHECK ACK ... ... ... ... ... ... ...]");
+            reportUserDto.updateLastTrafficTime();
+            this.isPacketSendYn = false;
+        }
+    }
+
+    private void recvReport(SocketChannel channel, ByteBuffer headBuffer) throws Exception {
+        ByteBuffer bodyBuffer = ByteBuffer.allocate(Report.REPORT_ACK_BODY_LENGTH);
+        int size = channel.read(bodyBuffer);
+        if (size != Report.REPORT_ACK_BODY_LENGTH) {
+            return;
+        }
+
+        saveSystemLog(printTaskLog() + "[RECEIVE REPORT ACK ... ... ... ... ... ... ...]");
+        ReportQueue reportQueue = reportUserDto.getReportQueue();
+        reportUserDto.updateLastTrafficTime();
+        this.isPacketSendYn = false;
+        if (reportQueue != null && this.reportDto != null) {
+            saveSystemLog(printTaskLog() + "[RECEIVE REPORT : " + this.reportDto.toString() + "]");
+            reportQueue.addReadCounter();
+        }
+    }
 
     private void sendInterest() throws IOException {
         if (reportUserDto.isLogin() == false) {
             return;
         }
-        if (reportUserDto.isAlive() == 1) {
-            expireConnectUser();
-        } else if (reportUserDto.isAlive() == 2) {
+        if (reportUserDto.isAlive() == 2) {
             channel.write(LinkCheck.makeLinkCheckBuffer());
+            SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
             /* Packet을 전송했는지 여부 */
             isPacketSendYn = true;
         } else {
             if (this.reportQueue != null && this.reportQueue.isRemainReport()) {
                 try {
-                    ReportDto reportDto = this.reportQueue.popReportFromQueue();
+                    this.reportDto = this.reportQueue.popReportFromQueue();
                     if (reportDto == null) {
                         return;
                     }
-                    saveSystemLog("[REPORT : " + reportDto.toString() + "]");
+                    saveSystemLog(printTaskLog() + "[REPORT SEND : " + reportDto.toString() + "]");
                     ByteBuffer reportBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH);
                     Packet.setDefaultByte(reportBuffer);
                     Header.putHeader(reportBuffer, Header.COMMAND_REPORT, Report.REPORT_BODY_LENGTH);
                     Report.putReport(reportBuffer, reportDto);
                     channel.write(reportBuffer);
                     /* Packet을 전송했는지 여부 */
+                    SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
                     isPacketSendYn = true;
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
+        }
+        /* 쓰레드 완료 시점 체크 */
+        if (System.currentTimeMillis() - SEND_CYCLE_CHECK_TIME > ServerConfig.REPORT_EXEC_CYCLE_TIME) {
+            this.isExpiredYn = true;
         }
     }
 
@@ -180,6 +358,7 @@
         }
         try {
             SocketChannel channel = (SocketChannel) key.channel();
+            saveSystemLog("[ReportServerTask]Expire connect user: " + reportUserDto);
             if (reportUserDto != null) {
                 if (reportUserDto.getUserId() != null) {
                     reportUserQueue.removeUser(reportUserDto.getUserId());
@@ -207,7 +386,7 @@
 
     private void saveLog(Object obj, boolean isConsoleOutput) {
         if (isConsoleOutput) {
-            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj);
+            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{" + this.serviceName + "}} " + obj);
         }
 
         if (logger == null) {
 
src/main/resources/sqlmap/sample_sql.xml (deleted)
--- src/main/resources/sqlmap/sample_sql.xml
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.munjaon.server.api.mapper.SampleMapper">
-    <select id="get" resultType="int">
-        /* SampleMapper.get */
-        SELECT 1
-    </select>
-</mapper>(No newline at end of file)
Add a comment
List