Deliver 기능 수정, msgid 관리 큐 수정

This commit is contained in:
dsjang 2024-08-15 19:23:34 +09:00
parent 455962efec
commit 48c5207d05
14 changed files with 337 additions and 303 deletions

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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 {
}

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -1,8 +0,0 @@
package com.munjaon.server.api.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SampleMapper {
int get();
}

View File

@ -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"));
}
}

View File

@ -257,8 +257,8 @@ public class RunnerConfiguration {
try { try {
String serviceName = "REPORTER"; String serviceName = "REPORTER";
int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT");
ReportServerService reportServerService = new ReportServerService(serviceName, port); ReportServer reportServer = new ReportServer(serviceName, port);
reportServerService.start(); reportServer.start();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@ -1,6 +1,7 @@
package com.munjaon.server.queue.pool; package com.munjaon.server.queue.pool;
import com.munjaon.server.queue.config.QueueConstants; import com.munjaon.server.queue.config.QueueConstants;
import com.munjaon.server.server.service.PropertyLoader;
import com.munjaon.server.util.FileUtil; import com.munjaon.server.util.FileUtil;
import lombok.Getter; import lombok.Getter;
@ -47,7 +48,11 @@ public class SerialQueue {
this.channel = new RandomAccessFile(file, "rw").getChannel(); this.channel = new RandomAccessFile(file, "rw").getChannel();
if (file.length() == 0) { if (file.length() == 0) {
serialNo = 0L; String msgid = PropertyLoader.getProp("SERIAL_QUEUE", "MSGID");
if (msgid == null) {
msgid = "0";
}
serialNo = Long.parseLong(msgid);
// 헤더 초기화 // 헤더 초기화
writeData(); writeData();
} else { } else {

View File

@ -33,7 +33,7 @@ public class PropertyLoader extends Thread {
value = value.replaceAll("\\$WORK_HOME", System.getProperty("WORK_HOME")); value = value.replaceAll("\\$WORK_HOME", System.getProperty("WORK_HOME"));
} }
return value; return value == null ? null : value.trim();
} }
public synchronized static Properties load() { public synchronized static Properties load() {

View File

@ -1,9 +1,9 @@
package com.munjaon.server.server.service; package com.munjaon.server.server.service;
import com.munjaon.server.queue.pool.ReportQueue; 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.dto.ReportUserDto;
import com.munjaon.server.server.queue.ReportUserQueue; import com.munjaon.server.server.queue.ReportUserQueue;
import com.munjaon.server.server.task.ReportServerTask;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import java.io.File; import java.io.File;
@ -100,6 +100,8 @@ public class ReportServer extends Service {
if (reportUserDto == null || reportUserDto.isRunningMode()) { if (reportUserDto == null || reportUserDto.isRunningMode()) {
continue; continue;
} }
/* 사용자별 Report Thread 실행 */
new ReportServerTask(selector, key, getName(), logger).run();
} else { } else {
ReportQueue reportQueue = reportUserDto.getReportQueue(); ReportQueue reportQueue = reportUserDto.getReportQueue();
if (reportUserDto.isLogin() && reportQueue != null && reportQueue.isRemainReport()) { if (reportUserDto.isLogin() && reportQueue != null && reportQueue.isRemainReport()) {
@ -107,6 +109,7 @@ public class ReportServer extends Service {
continue; continue;
} }
/* 사용자별 Report Thread 실행 */ /* 사용자별 Report Thread 실행 */
new ReportServerTask(selector, key, getName(), logger).run();
} }
} }
} else { } else {
@ -135,9 +138,14 @@ public class ReportServer extends Service {
if (reportUserDto == null || reportUserDto.isRunningMode()) { if (reportUserDto == null || reportUserDto.isRunningMode()) {
continue; 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 실행 */ /* 사용자별 Report Thread 실행 */
// threadService.submit(selector, key, 2); new ReportServerTask(selector, key, getName(), logger).run();
} }
} else { } else {
expireConnectUser(key); expireConnectUser(key);
@ -169,7 +177,8 @@ public class ReportServer extends Service {
} }
try { try {
SocketChannel channel = (SocketChannel) key.channel(); 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) { if (userDto != null && userDto.getUserId() != null) {
reportUserQueue.removeUser(userDto.getUserId()); reportUserQueue.removeUser(userDto.getUserId());
// connectUserMap.remove(userDto.getUserId()); // connectUserMap.remove(userDto.getUserId());

View File

@ -40,7 +40,7 @@ public class CollectServerTask implements Runnable {
private long RUN_FLAG_CHECK_TIME; private long RUN_FLAG_CHECK_TIME;
/* 클라이언트 요청 데이터 수신 */ /* 클라이언트 요청 데이터 수신 */
private ByteBuffer headBuffer = ByteBuffer.allocateDirect(Header.HEADER_LENGTH);
/* 세션이 만료되었는지 체크 */ /* 세션이 만료되었는지 체크 */
private boolean isExpiredYn; private boolean isExpiredYn;
@ -75,53 +75,74 @@ public class CollectServerTask implements Runnable {
return IS_SERVER_RUN && IS_RUN_YN; 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 @Override
public void run() { public void run() {
saveSystemLog("CollectServerTask is Entered"); saveSystemLog(printTaskLog() + "[### Start ### ### ### ### ### ### ###]");
/* 최초 RUN Flag 체크 */ /* 0. 최초 RUN Flag 체크 */
reloadRunFlag(); reloadRunFlag();
/* BIND 체크 및 처리 */ /* BIND 체크 및 처리 */
while (isRun()) { while (isRun()) {
/* 만료 여부 체크 */ /* 1. 만료 여부 체크 */
if (isExpiredYn) { if (isExpiredYn) {
break; break;
} }
int size = -1;
try { try {
/* 1. Head 읽기 */ /* 3. HeadBuffer 읽기 */
ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); int size = readHeader();
try { /* 4. Body 읽기 */
size = channel.read(headBuffer);
} catch (IOException e) {}
/* 2. Body 읽기 */
if (size > 0) { if (size > 0) {
String command = Header.getCommand(headBuffer); String command = Header.getCommand(headBuffer);
switch (Integer.parseInt(command)) { switch (Integer.parseInt(command)) {
case 1: case 1: recvBind(channel, headBuffer); break;
recvBind(channel, headBuffer); case 3: recvDeliver(channel, headBuffer); break;
break; case 7: recvLinkCheck(channel); break;
case 3: default: expireConnectUser(); break;
recvDeliver(channel, headBuffer);
break;
case 7:
recvLinkCheck(channel);
break;
default:
expireConnectUser();
break;
} }
} else if (size == 0) { } else if (size == 0) {
Thread.sleep(1);
if (System.currentTimeMillis() - connectUserDto.getLastTrafficTime() > ServerConfig.DELIVER_EXEC_CYCLE_TIME) { if (System.currentTimeMillis() - connectUserDto.getLastTrafficTime() > ServerConfig.DELIVER_EXEC_CYCLE_TIME) {
this.isExpiredYn = true; this.isExpiredYn = true;
} }
Thread.sleep(1);
} else { } else {
expireConnectUser(); expireConnectUser();
} }
} catch (Exception e) { } catch (Exception e) {
size = -1; /* 세션 만료 여부 */
this.isExpiredYn = true;
e.printStackTrace(); e.printStackTrace();
} }
/* RUN Flag 체크 */ /* RUN Flag 체크 */
@ -129,31 +150,22 @@ public class CollectServerTask implements Runnable {
} }
/* 중요 : 사용자 Thread 실행모드 Off */ /* 중요 : 사용자 Thread 실행모드 Off */
connectUserDto.setRunningMode(false); connectUserDto.setRunningMode(false);
saveSystemLog("CollectServerTask is Finished"); saveSystemLog(printTaskLog() + "[### End ### ### ### ### ### ### ###]");
} }
private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
/* 서비스 중지여부 체크 */ /* 서비스 중지여부 체크 */
if (isExpireService()) { if (isExpireService()) {
expireConnectUser(); expireConnectUser();
saveSystemLog(printTaskLog() + "[isExpireService : Expired ... ... ... ... ... ... ...]");
return; return;
} }
switch (this.serviceType) { switch (this.serviceType) {
case "SMS": case "SMS": recvSmsDeliver(channel, headBuffer); break;
recvSmsDeliver(channel, headBuffer); case "LMS": recvLmsDeliver(channel, headBuffer); break;
break; case "MMS": recvMmsDeliver(channel, headBuffer); break;
case "LMS": case "KAT": recvKatDeliver(channel, headBuffer); break;
recvLmsDeliver(channel, headBuffer); case "KFT": recvKftDeliver(channel, headBuffer); break;
break;
case "MMS":
recvMmsDeliver(channel, headBuffer);
break;
case "KAT":
recvKatDeliver(channel, headBuffer);
break;
case "KFT":
recvKftDeliver(channel, headBuffer);
break;
default:break; default:break;
} }
} }
@ -161,7 +173,6 @@ public class CollectServerTask implements Runnable {
private boolean isExpireService() { private boolean isExpireService() {
ConnectUserDto checkConnectUserDto = collectUserQueue.getUser(this.serviceType, this.connectUserDto.getUserId()); ConnectUserDto checkConnectUserDto = collectUserQueue.getUser(this.serviceType, this.connectUserDto.getUserId());
MemberDto memberDto = checkConnectUserDto.getMemberDto(); MemberDto memberDto = checkConnectUserDto.getMemberDto();
saveSystemLog("[isExpireService : " + memberDto.toString() + "]");
if (memberDto == null) { if (memberDto == null) {
return true; return true;
} }
@ -233,7 +244,7 @@ public class CollectServerTask implements Runnable {
messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice())); messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice()));
} }
saveLog("[SMS] [MESSAGE : " + messageDto.toString() + "]"); saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("SMS"); QueueTypeWorker worker = QueueTypeWorker.find("SMS");
if (worker != null) { if (worker != null) {
worker.pushQueue(messageDto); worker.pushQueue(messageDto);
@ -266,7 +277,7 @@ public class CollectServerTask implements Runnable {
messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice())); messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice()));
} }
saveSystemLog("[LMS] [MESSAGE : " + messageDto.toString() + "]"); saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("LMS"); QueueTypeWorker worker = QueueTypeWorker.find("LMS");
if (worker != null) { if (worker != null) {
worker.pushQueue(messageDto); worker.pushQueue(messageDto);
@ -315,7 +326,7 @@ public class CollectServerTask implements Runnable {
} else if (i == 2) { } else if (i == 2) {
messageDto.setUserFileName03(imagePath + File.separator + fileName); 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 @@ public class CollectServerTask implements Runnable {
messageDto.setUnitCost(String.valueOf(mmsPrice)); messageDto.setUnitCost(String.valueOf(mmsPrice));
} }
saveSystemLog("[MMS] [MESSAGE : " + messageDto.toString() + "]"); saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("MMS"); QueueTypeWorker worker = QueueTypeWorker.find("MMS");
if (worker != null) { if (worker != null) {
worker.pushQueue(messageDto); worker.pushQueue(messageDto);
@ -377,7 +388,7 @@ public class CollectServerTask implements Runnable {
JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
saveSystemLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); saveSystemLog(printTaskLog() + "[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
/* 사용자 단가, 발송망 설정 */ /* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null; MemberDto savedMemberDto = null;
@ -389,7 +400,7 @@ public class CollectServerTask implements Runnable {
messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice())); messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice()));
} }
saveSystemLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]"); saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("KAT"); QueueTypeWorker worker = QueueTypeWorker.find("KAT");
if (worker != null) { if (worker != null) {
worker.pushQueue(messageDto); worker.pushQueue(messageDto);
@ -432,7 +443,7 @@ public class CollectServerTask implements Runnable {
JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
saveSystemLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); saveSystemLog(printTaskLog() + "[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
/* 사용자 단가, 발송망 설정 */ /* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null; MemberDto savedMemberDto = null;
@ -444,7 +455,7 @@ public class CollectServerTask implements Runnable {
messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice())); messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice()));
} }
saveSystemLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]"); saveLog(printTaskLog() + "[MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("KFT"); QueueTypeWorker worker = QueueTypeWorker.find("KFT");
if (worker != null) { if (worker != null) {
worker.pushQueue(messageDto); worker.pushQueue(messageDto);
@ -485,7 +496,7 @@ public class CollectServerTask implements Runnable {
if (svc != null) { if (svc != null) {
memberDto = svc.get(id); memberDto = svc.get(id);
} }
saveSystemLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); saveSystemLog(printTaskLog() + "[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]");
/* Bind Check */ /* Bind Check */
resultCode = checkBind(memberDto, this.serviceType, id, pwd); resultCode = checkBind(memberDto, this.serviceType, id, pwd);
@ -493,9 +504,9 @@ public class CollectServerTask implements Runnable {
if ("00".equals(resultCode)) { if ("00".equals(resultCode)) {
boolean isPermit = false; boolean isPermit = false;
if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) {
saveSystemLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP()); saveSystemLog(printTaskLog() + "[REMOTE IP : " + connectUserDto.getRemoteIP() + "]");
saveSystemLog("Customize Toolbar... : " + memberDto.getAllowIpBasic()); saveSystemLog(printTaskLog() + "[ALLOW IP BASIC : " + memberDto.getAllowIpBasic() + "]");
saveSystemLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend()); saveSystemLog(printTaskLog() + "[ALLOW IP EXTEND : " + memberDto.getAllowIpExtend() + "]");
if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) {
isPermit = true; isPermit = true;
} }
@ -526,7 +537,7 @@ public class CollectServerTask implements Runnable {
} }
try { try {
saveSystemLog("[BIND RESULT : " + resultCode + "]"); saveSystemLog(printTaskLog() + "[BIND RESULT : " + resultCode + "]");
channel.write(Bind.makeBindAckBuffer(resultCode)); channel.write(Bind.makeBindAckBuffer(resultCode));
if ("00".equals(resultCode) == false) { if ("00".equals(resultCode) == false) {
expireConnectUser(); expireConnectUser();
@ -623,7 +634,7 @@ public class CollectServerTask implements Runnable {
private void saveLog(Object obj, boolean isConsoleOutput) { private void saveLog(Object obj, boolean isConsoleOutput) {
if (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) { if (logger == null) {

View File

@ -1,13 +1,13 @@
package com.munjaon.server.server.task; 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.queue.pool.ReportQueue;
import com.munjaon.server.server.config.ServerConfig; import com.munjaon.server.server.config.ServerConfig;
import com.munjaon.server.server.dto.ReportDto; import com.munjaon.server.server.dto.ReportDto;
import com.munjaon.server.server.dto.ReportUserDto; import com.munjaon.server.server.dto.ReportUserDto;
import com.munjaon.server.server.packet.Header; import com.munjaon.server.server.packet.*;
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.queue.ReportUserQueue; import com.munjaon.server.server.queue.ReportUserQueue;
import com.munjaon.server.server.service.PropertyLoader; import com.munjaon.server.server.service.PropertyLoader;
import com.munjaon.server.util.LogUtil; import com.munjaon.server.util.LogUtil;
@ -37,9 +37,13 @@ public class ReportServerTask implements Runnable {
private boolean IS_SERVER_RUN; // 서버가 구동중인지 여부 private boolean IS_SERVER_RUN; // 서버가 구동중인지 여부
private boolean IS_RUN_YN; private boolean IS_RUN_YN;
private long RUN_FLAG_CHECK_TIME; private long RUN_FLAG_CHECK_TIME;
private long SEND_CYCLE_CHECK_TIME;
/* 세션이 만료되었는지 체크 */ /* 세션이 만료되었는지 체크 */
private boolean isExpiredYn; private boolean isExpiredYn;
/* 클라이언트 요청 데이터 수신 */
private ByteBuffer headBuffer = ByteBuffer.allocateDirect(Header.HEADER_LENGTH);
private ReportDto reportDto; // 전송 리포트
/* Packet을 전송했는지 여부 */ /* Packet을 전송했는지 여부 */
private boolean isPacketSendYn; private boolean isPacketSendYn;
@ -74,20 +78,37 @@ public class ReportServerTask implements Runnable {
return IS_SERVER_RUN && IS_RUN_YN; 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 @Override
public void run() { public void run() {
saveSystemLog("ReportServerTask is Entered"); saveSystemLog(printTaskLog() + "[### Start ### ### ### ### ### ### ###]");
/* 최초 RUN Flag 체크 */ /* 최초 RUN Flag 체크 */
reloadRunFlag(); reloadRunFlag();
try {
/* BIND 체크 및 처리 */ /* BIND 체크 및 처리 */
while (isRun()) { bindInterest();
SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
while (reportUserDto.isLogin() && isRun()) {
/* 만료 여부 체크 */ /* 만료 여부 체크 */
if (isExpiredYn) { if (isExpiredYn) {
break; break;
} }
// saveSystemLog("ReportServerTask is Running");
try { try {
sendInterest(); sendInterest();
recvInterest();
/* RUN Flag 체크 */ /* RUN Flag 체크 */
reloadRunFlag(); reloadRunFlag();
} catch (Exception e) { } catch (Exception e) {
@ -95,83 +116,240 @@ public class ReportServerTask implements Runnable {
e.printStackTrace(); e.printStackTrace();
} }
} }
} catch (Exception e) {
/* 세션 만료 여부 */
this.isExpiredYn = true;
e.printStackTrace();
}
/* 중요 : 사용자 Thread 실행모드 Off */ /* 중요 : 사용자 Thread 실행모드 Off */
reportUserDto.setRunningMode(false); reportUserDto.setRunningMode(false);
saveSystemLog("ReportServerTask is Finished"); saveSystemLog(printTaskLog() + "[### End ### ### ### ### ### ### ###]");
} }
// private void recvInterest() { private void initHeaderBuffer() {
// while (isPacketSendYn) { this.headBuffer.clear();
// for (int loopCnt = 0; loopCnt < Header.HEADER_LENGTH; loopCnt++) {
// } this.headBuffer.put(Packet.SET_DEFAULT_BYTE);
// int size = -1; }
// try { this.headBuffer.position(0);
// /* 1. Head 읽기 */ }
// ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH);
// try { private int readHeader() {
// size = channel.read(headBuffer); initHeaderBuffer();
// } catch (IOException e) {} int size = -1;
// /* 2. Body 읽기 */ try {
// if (size > 0) { size = channel.read(headBuffer);
// String command = Header.getCommand(headBuffer); } catch (IOException e) {
// switch (Integer.parseInt(command)) { throw new RuntimeException(e);
// case 1: }
// recvBind(channel, headBuffer);
// break; return size;
// case 3: }
// recvDeliver(channel, headBuffer);
// break; private void bindInterest() throws IOException {
// case 7: // if (reportUserDto.isLogin() && !isRun()) {
// recvLinkCheck(channel); if (reportUserDto.isLogin()) {
// break; return;
// default: }
// expireConnectUser(); long bind_check_start_time = System.currentTimeMillis();
// break; while(true) {
// } /* 1. Head 읽기 */
// } else if (size == 0) { int size = readHeader();
// Thread.sleep(1); /* 2. Body 읽기 */
// if (System.currentTimeMillis() - reportUserDto.getLastTrafficTime() > ServerConfig.REPORT_EXEC_CYCLE_TIME) { if (size > 0) {
// this.isExpiredYn = true; String command = Header.getCommand(this.headBuffer);
// } switch (Integer.parseInt(command)) {
// } else { case 1 : recvBind(channel, headBuffer); break;
// expireConnectUser(); default: expireConnectUser(); break;
// } }
// } catch (Exception e) { /* 패킷 수신한 경우 무조건 루프를 빠져나간다 */
// size = -1; break;
// e.printStackTrace(); }
// } /* 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 { private void sendInterest() throws IOException {
if (reportUserDto.isLogin() == false) { if (reportUserDto.isLogin() == false) {
return; return;
} }
if (reportUserDto.isAlive() == 1) { if (reportUserDto.isAlive() == 2) {
expireConnectUser();
} else if (reportUserDto.isAlive() == 2) {
channel.write(LinkCheck.makeLinkCheckBuffer()); channel.write(LinkCheck.makeLinkCheckBuffer());
SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
/* Packet을 전송했는지 여부 */ /* Packet을 전송했는지 여부 */
isPacketSendYn = true; isPacketSendYn = true;
} else { } else {
if (this.reportQueue != null && this.reportQueue.isRemainReport()) { if (this.reportQueue != null && this.reportQueue.isRemainReport()) {
try { try {
ReportDto reportDto = this.reportQueue.popReportFromQueue(); this.reportDto = this.reportQueue.popReportFromQueue();
if (reportDto == null) { if (reportDto == null) {
return; return;
} }
saveSystemLog("[REPORT : " + reportDto.toString() + "]"); saveSystemLog(printTaskLog() + "[REPORT SEND : " + reportDto.toString() + "]");
ByteBuffer reportBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH); ByteBuffer reportBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH);
Packet.setDefaultByte(reportBuffer); Packet.setDefaultByte(reportBuffer);
Header.putHeader(reportBuffer, Header.COMMAND_REPORT, Report.REPORT_BODY_LENGTH); Header.putHeader(reportBuffer, Header.COMMAND_REPORT, Report.REPORT_BODY_LENGTH);
Report.putReport(reportBuffer, reportDto); Report.putReport(reportBuffer, reportDto);
channel.write(reportBuffer); channel.write(reportBuffer);
/* Packet을 전송했는지 여부 */ /* Packet을 전송했는지 여부 */
SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
isPacketSendYn = true; isPacketSendYn = true;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
/* 쓰레드 완료 시점 체크 */
if (System.currentTimeMillis() - SEND_CYCLE_CHECK_TIME > ServerConfig.REPORT_EXEC_CYCLE_TIME) {
this.isExpiredYn = true;
}
} }
private void expireConnectUser() { private void expireConnectUser() {
@ -180,6 +358,7 @@ public class ReportServerTask implements Runnable {
} }
try { try {
SocketChannel channel = (SocketChannel) key.channel(); SocketChannel channel = (SocketChannel) key.channel();
saveSystemLog("[ReportServerTask]Expire connect user: " + reportUserDto);
if (reportUserDto != null) { if (reportUserDto != null) {
if (reportUserDto.getUserId() != null) { if (reportUserDto.getUserId() != null) {
reportUserQueue.removeUser(reportUserDto.getUserId()); reportUserQueue.removeUser(reportUserDto.getUserId());
@ -207,7 +386,7 @@ public class ReportServerTask implements Runnable {
private void saveLog(Object obj, boolean isConsoleOutput) { private void saveLog(Object obj, boolean isConsoleOutput) {
if (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) { if (logger == null) {

View File

@ -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>