발송 성능 개선, 리포트 수신 관련 기능 개선

This commit is contained in:
dsjang 2024-08-12 06:00:51 +09:00
parent aa4fc21692
commit 455962efec
45 changed files with 2833 additions and 165 deletions

View File

@ -6,7 +6,6 @@ import com.munjaon.server.server.service.*;
import com.munjaon.server.util.ServiceUtil; import com.munjaon.server.util.ServiceUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -24,16 +23,16 @@ public class RunnerConfiguration {
System.setProperty("PROPS", serverConfig.getServerProperyFile()); System.setProperty("PROPS", serverConfig.getServerProperyFile());
System.setProperty("ROOTPATH", serverConfig.getServerRootPath()); System.setProperty("ROOTPATH", serverConfig.getServerRootPath());
PropertyLoader.load(); PropertyLoader.load();
/* Serial queue 초기화 */
SerialQueuePool queueInstance = SerialQueuePool.getInstance();
try { try {
String[] array = serverConfig.getStringArray("test.list"); SerialQueue serialQueue = new SerialQueue();
if (array != null && array.length > 0) { queueInstance.setSerialQueue(serialQueue);
for (String s : array) { } catch (Exception e) {
System.out.println("List : " + s); e.printStackTrace();
}
}
} catch (ConfigurationException e) {
throw new RuntimeException(e);
} }
return args -> System.out.println("Runner Bean #1 : " + serverConfig.getServerProperyFile()); return args -> System.out.println("Runner Bean #1 : " + serverConfig.getServerProperyFile());
} }
@ -180,8 +179,8 @@ public class RunnerConfiguration {
String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE");
int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT");
// CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port);
CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); CollectServer collectServer = new CollectServer(serviceName, serviceType, port);
collectServerService.start(); collectServer.start();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -196,8 +195,8 @@ public class RunnerConfiguration {
String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE");
int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT");
// CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port);
CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); CollectServer collectServer = new CollectServer(serviceName, serviceType, port);
collectServerService.start(); collectServer.start();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -212,8 +211,8 @@ public class RunnerConfiguration {
String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE");
int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT");
// CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port);
CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); CollectServer collectServer = new CollectServer(serviceName, serviceType, port);
collectServerService.start(); collectServer.start();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -228,8 +227,8 @@ public class RunnerConfiguration {
String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE");
int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT");
// CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port);
CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); CollectServer collectServer = new CollectServer(serviceName, serviceType, port);
collectServerService.start(); collectServer.start();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -244,8 +243,8 @@ public class RunnerConfiguration {
String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE"); String serviceType = serverConfig.getString(serviceName + ".SERVICE_TYPE");
int port = serverConfig.getInt(serviceName + ".SERVICE_PORT"); int port = serverConfig.getInt(serviceName + ".SERVICE_PORT");
// CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port); // CollectBackServerService collectServerService = new CollectBackServerService(serviceName, serviceType, port);
CollectServerService collectServerService = new CollectServerService(serviceName, serviceType, port); CollectServer collectServer = new CollectServer(serviceName, serviceType, port);
collectServerService.start(); collectServer.start();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@ -6,6 +6,7 @@ import com.munjaon.server.queue.service.*;
import lombok.Getter; import lombok.Getter;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
@Getter @Getter
public enum QueueTypeWorker { public enum QueueTypeWorker {
@ -46,6 +47,12 @@ public enum QueueTypeWorker {
return smsQueueService.saveMessageToTable(data); return smsQueueService.saveMessageToTable(data);
} }
@Override
public int saveMessageForList(List<BasicMessageDto> list) {
SmsQueueService smsQueueService = (SmsQueueService) QueueService.SMS_QUEUE_SERVICE.getService();
return smsQueueService.saveMessageForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
SmsQueueService smsQueueService = (SmsQueueService) QueueService.SMS_QUEUE_SERVICE.getService(); SmsQueueService smsQueueService = (SmsQueueService) QueueService.SMS_QUEUE_SERVICE.getService();
@ -107,6 +114,12 @@ public enum QueueTypeWorker {
return lmsQueueService.saveMessageToTable(data); return lmsQueueService.saveMessageToTable(data);
} }
@Override
public int saveMessageForList(List<BasicMessageDto> list) {
LmsQueueService lmsQueueService = (LmsQueueService) QueueService.LMS_QUEUE_SERVICE.getService();
return lmsQueueService.saveMessageForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
LmsQueueService lmsQueueService = (LmsQueueService) QueueService.LMS_QUEUE_SERVICE.getService(); LmsQueueService lmsQueueService = (LmsQueueService) QueueService.LMS_QUEUE_SERVICE.getService();
@ -168,6 +181,12 @@ public enum QueueTypeWorker {
return mmsQueueService.saveMessageToTable(data); return mmsQueueService.saveMessageToTable(data);
} }
@Override
public int saveMessageForList(List<BasicMessageDto> list) {
MmsQueueService mmsQueueService = (MmsQueueService) QueueService.MMS_QUEUE_SERVICE.getService();
return mmsQueueService.saveMessageForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
MmsQueueService mmsQueueService = (MmsQueueService) QueueService.MMS_QUEUE_SERVICE.getService(); MmsQueueService mmsQueueService = (MmsQueueService) QueueService.MMS_QUEUE_SERVICE.getService();
@ -229,6 +248,12 @@ public enum QueueTypeWorker {
return kakaoAlarmQueueService.saveMessageToTable(data); return kakaoAlarmQueueService.saveMessageToTable(data);
} }
@Override
public int saveMessageForList(List<BasicMessageDto> list) {
KakaoAlarmQueueService kakaoAlarmQueueService = (KakaoAlarmQueueService) QueueService.KAT_QUEUE_SERVICE.getService();
return kakaoAlarmQueueService.saveMessageForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
KakaoAlarmQueueService kakaoAlarmQueueService = (KakaoAlarmQueueService) QueueService.KAT_QUEUE_SERVICE.getService(); KakaoAlarmQueueService kakaoAlarmQueueService = (KakaoAlarmQueueService) QueueService.KAT_QUEUE_SERVICE.getService();
@ -290,6 +315,12 @@ public enum QueueTypeWorker {
return kakaoFriendQueueService.saveMessageToTable(data); return kakaoFriendQueueService.saveMessageToTable(data);
} }
@Override
public int saveMessageForList(List<BasicMessageDto> list) {
KakaoFriendQueueService kakaoFriendQueueService = (KakaoFriendQueueService) QueueService.KFT_QUEUE_SERVICE.getService();
return kakaoFriendQueueService.saveMessageForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
KakaoFriendQueueService kakaoFriendQueueService = (KakaoFriendQueueService) QueueService.KFT_QUEUE_SERVICE.getService(); KakaoFriendQueueService kakaoFriendQueueService = (KakaoFriendQueueService) QueueService.KFT_QUEUE_SERVICE.getService();
@ -337,6 +368,7 @@ public enum QueueTypeWorker {
public abstract void addQueue(WriteQueue queue); public abstract void addQueue(WriteQueue queue);
public abstract void pushQueue(BasicMessageDto data); public abstract void pushQueue(BasicMessageDto data);
public abstract int saveMessageToTable(BasicMessageDto data); public abstract int saveMessageToTable(BasicMessageDto data);
public abstract int saveMessageForList(List<BasicMessageDto> list);
public abstract void memoryEnQueue(BasicMessageDto data); public abstract void memoryEnQueue(BasicMessageDto data);
public abstract BasicMessageDto memoryDeQueue(); public abstract BasicMessageDto memoryDeQueue();

View File

@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper;
import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.dto.BasicMessageDto;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper @Mapper
public interface KatMapper { public interface KatMapper {
int insert(BasicMessageDto messageDto); int insert(BasicMessageDto messageDto);
int insertForList(List<BasicMessageDto> list);
int insertGroupForList(List<BasicMessageDto> list);
} }

View File

@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper;
import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.dto.BasicMessageDto;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper @Mapper
public interface KftMapper { public interface KftMapper {
int insert(BasicMessageDto messageDto); int insert(BasicMessageDto messageDto);
int insertForList(List<BasicMessageDto> list);
int insertGroupForList(List<BasicMessageDto> list);
} }

View File

@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper;
import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.dto.BasicMessageDto;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper @Mapper
public interface LmsMapper { public interface LmsMapper {
int insert(BasicMessageDto messageDto); int insert(BasicMessageDto messageDto);
int insertForList(List<BasicMessageDto> list);
int insertGroupForList(List<BasicMessageDto> list);
} }

View File

@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper;
import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.dto.BasicMessageDto;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper @Mapper
public interface MmsMapper { public interface MmsMapper {
int insert(BasicMessageDto messageDto); int insert(BasicMessageDto messageDto);
int insertForList(List<BasicMessageDto> list);
int insertGroupForList(List<BasicMessageDto> list);
} }

View File

@ -3,7 +3,11 @@ package com.munjaon.server.queue.mapper;
import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.dto.BasicMessageDto;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper @Mapper
public interface SmsMapper { public interface SmsMapper {
int insert(BasicMessageDto messageDto); int insert(BasicMessageDto messageDto);
int insertForList(List<BasicMessageDto> list);
int insertGroupForList(List<BasicMessageDto> list);
} }

View File

@ -89,27 +89,28 @@ public class ReportQueue {
} }
public boolean isTruncateQueue(int maxWriteCount) { public boolean isTruncateQueue(int maxWriteCount) {
boolean truncate = false;
synchronized (lockObject) { synchronized (lockObject) {
if (this.writeCounter >= maxWriteCount) { if (this.writeCounter >= maxWriteCount) {
if (this.writeCounter == this.readCounter) { if (this.writeCounter == this.readCounter) {
truncate = true; return true;
} }
return false;
} }
return false;
} }
return truncate;
} }
public boolean isWriteLimit(int maxWriteCount) { public boolean isWriteLimit(int maxWriteCount) {
boolean isLimit = false;
synchronized (lockObject) { synchronized (lockObject) {
if (this.writeCounter >= maxWriteCount) { if (this.writeCounter >= maxWriteCount) {
isLimit = true; return true;
} }
return false;
} }
}
return isLimit; public boolean isRemainReport() {
return this.writeCounter > this.readCounter;
} }
public void truncateQueue() throws Exception { public void truncateQueue() throws Exception {
@ -124,26 +125,24 @@ public class ReportQueue {
} }
private void readHeader() throws Exception { private void readHeader() throws Exception {
synchronized (lockObject) { initHeadBuffer();
initHeadBuffer(); this.channel.position(0);
this.channel.position(0); this.channel.read(this.headBuffer);
this.channel.read(this.headBuffer); this.byteArray = new byte[ReportConfig.USER_ID_LENGTH];
this.byteArray = new byte[ReportConfig.USER_ID_LENGTH]; // USER_ID
// USER_ID this.headBuffer.position(ReportConfig.USER_ID_POSITION);
this.headBuffer.position(ReportConfig.USER_ID_POSITION); this.headBuffer.get(this.byteArray);
this.headBuffer.get(this.byteArray); this.userId = (new String(this.byteArray)).trim();
this.userId = (new String(this.byteArray)).trim(); // 쓰기 카운트 가져오기
// 쓰기 카운트 가져오기 this.byteArray = new byte[ReportConfig.WRITE_COUNT_LENGTH];
this.byteArray = new byte[ReportConfig.WRITE_COUNT_LENGTH]; this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION);
this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION); this.headBuffer.get(this.byteArray);
this.headBuffer.get(this.byteArray); this.writeCounter = Integer.parseInt((new String(this.byteArray)).trim());
this.writeCounter = Integer.parseInt((new String(this.byteArray)).trim()); // 읽기 카운트 가져오기
// 읽기 카운트 가져오기 this.byteArray = new byte[ReportConfig.READ_COUNT_LENGTH];
this.byteArray = new byte[ReportConfig.READ_COUNT_LENGTH]; this.headBuffer.position(ReportConfig.READ_COUNT_POSITION);
this.headBuffer.position(ReportConfig.READ_COUNT_POSITION); this.headBuffer.get(this.byteArray);
this.headBuffer.get(this.byteArray); this.readCounter = Integer.parseInt((new String(this.byteArray)).trim());
this.readCounter = Integer.parseInt((new String(this.byteArray)).trim());
}
} }
public void addReadCounter() throws Exception { public void addReadCounter() throws Exception {
@ -151,30 +150,20 @@ public class ReportQueue {
/* 읽기 카운트 증가 */ /* 읽기 카운트 증가 */
this.readCounter = this.readCounter + 1; this.readCounter = this.readCounter + 1;
initHeadBuffer(); writeHeader();
this.channel.position(ReportConfig.USER_ID_POSITION);
this.headBuffer.put(this.userId.getBytes());
this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION);
this.headBuffer.put(Integer.toString(this.writeCounter).getBytes());
this.headBuffer.position(ReportConfig.READ_COUNT_POSITION);
this.headBuffer.put(Integer.toString(this.readCounter).getBytes());
this.headBuffer.flip();
this.channel.write(this.headBuffer);
} }
} }
private void writeHeader() throws Exception { private void writeHeader() throws Exception {
synchronized (lockObject) { initHeadBuffer();
initHeadBuffer(); this.channel.position(ReportConfig.USER_ID_POSITION);
this.channel.position(ReportConfig.USER_ID_POSITION); this.headBuffer.put(this.userId.getBytes());
this.headBuffer.put(this.userId.getBytes()); this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION);
this.headBuffer.position(ReportConfig.WRITE_COUNT_POSITION); this.headBuffer.put(Integer.toString(this.writeCounter).getBytes());
this.headBuffer.put(Integer.toString(this.writeCounter).getBytes()); this.headBuffer.position(ReportConfig.READ_COUNT_POSITION);
this.headBuffer.position(ReportConfig.READ_COUNT_POSITION); this.headBuffer.put(Integer.toString(this.readCounter).getBytes());
this.headBuffer.put(Integer.toString(this.readCounter).getBytes()); this.headBuffer.flip();
this.headBuffer.flip(); this.channel.write(this.headBuffer);
this.channel.write(this.headBuffer);
}
} }
private void initHeadBuffer() { private void initHeadBuffer() {

View File

@ -0,0 +1,125 @@
package com.munjaon.server.queue.pool;
import com.munjaon.server.queue.config.QueueConstants;
import com.munjaon.server.util.FileUtil;
import lombok.Getter;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class SerialQueue {
/** Queue Header Buffer */
private ByteBuffer dataBuffer = null;
/** Header 에서 사용하는 변수 */
private byte[] dataArray = null;
/* 채번 큐 크기 */
private final int SERIAL_QUEUE_SIZE = 14;
/* 큐경로 */
@Getter
private String queuePath;
@Getter
private final String queueName = "SERIAL_QUEUE.queue";
@Getter
private Long serialNo = 0L;
/** Queue File Channel */
private FileChannel channel = null;
public SerialQueue() throws Exception {
initQueue();
}
private void initQueuePath() {
/* 1. 큐경로 */
this.queuePath = System.getProperty("ROOTPATH") + File.separator + "queue" + File.separator + "SERIAL_QUEUE";
/* 2. 경로 체크 및 생성 */
FileUtil.mkdirs(this.queuePath);
}
private void initQueue() throws Exception {
this.dataBuffer = ByteBuffer.allocateDirect(SERIAL_QUEUE_SIZE);
try{
/* 1. 큐경로 초기화 */
initQueuePath();
File file = new File(this.queuePath + File.separator + queueName);
this.channel = new RandomAccessFile(file, "rw").getChannel();
if (file.length() == 0) {
serialNo = 0L;
// 헤더 초기화
writeData();
} else {
readData();
}
// backupQueue();
} catch(Exception e) {
throw e;
} finally {
//lock.release();
}
}
private void readData() throws Exception {
try {
initDataBuffer();
this.channel.position(0);
this.channel.read(this.dataBuffer);
this.dataArray = new byte[SERIAL_QUEUE_SIZE];
this.dataBuffer.position(0);
this.dataBuffer.get(this.dataArray);
String no = QueueConstants.getString(this.dataArray);
serialNo = Long.parseLong(no);
System.out.println("SERIAL QUEUE NO: " + serialNo);
} catch(Exception e) {
throw e;
}
}
public String getSerialNumber() throws Exception {
this.serialNo = this.serialNo + 1;
writeData();
return String.valueOf(this.serialNo);
}
private void writeData() throws Exception {
try {
initDataBuffer();
this.channel.position(0);
this.dataBuffer.put(String.valueOf(serialNo).getBytes());
this.dataBuffer.flip();
this.channel.write(this.dataBuffer);
} catch(Exception e) {
throw e;
}
}
private void initDataBuffer(){
this.dataBuffer.clear();
for(int loopCnt = 0; loopCnt < SERIAL_QUEUE_SIZE; loopCnt++){
this.dataBuffer.put(QueueConstants.SET_DEFAULT_BYTE);
}
this.dataBuffer.position(0);
}
public void close() throws IOException {
try {
if (isOpen()) {
channel.close();
}
} catch(IOException e) {
throw e;
}
}
public boolean isOpen() {
if (this.channel == null) {
return false;
}
return this.channel.isOpen();
}
}

View File

@ -0,0 +1,54 @@
package com.munjaon.server.queue.pool;
public class SerialQueuePool {
/** Lock Object */
protected final Object lockMonitor = new Object();
/* Serial Queue */
private SerialQueue serialQueue;
private static SerialQueuePool queueInstance;
private SerialQueuePool() {}
public synchronized static SerialQueuePool getInstance() {
if (queueInstance == null) {
queueInstance = new SerialQueuePool();
}
return queueInstance;
}
public String getSerialNumber() throws Exception {
synchronized (lockMonitor) {
if (serialQueue == null || serialQueue.isOpen() == false) {
try {
lockMonitor.wait();
} catch(InterruptedException e) {
// 아무 처리도 하지 않는다.
}
}
return serialQueue.getSerialNumber();
}
}
public void setSerialQueue(SerialQueue serialQueue) {
synchronized(lockMonitor){
if (serialQueue != null){
this.serialQueue = serialQueue;
lockMonitor.notifyAll();
}
}
}
public boolean isReady() {
synchronized (lockMonitor) {
if (serialQueue != null && serialQueue.isOpen()) {
return true;
} else {
return false;
}
}
}
}

View File

@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@ -63,6 +66,13 @@ public class KakaoAlarmQueueService implements QueueAction {
return katMapper.insert(data); return katMapper.insert(data);
} }
@Override
@Transactional
public int saveMessageForList(List<BasicMessageDto> list) {
katMapper.insertGroupForList(list);
return katMapper.insertForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
memoryQueue.memoryEnQueue(data); memoryQueue.memoryEnQueue(data);

View File

@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@ -63,6 +66,13 @@ public class KakaoFriendQueueService implements QueueAction {
return kftMapper.insert(data); return kftMapper.insert(data);
} }
@Override
@Transactional
public int saveMessageForList(List<BasicMessageDto> list) {
kftMapper.insertGroupForList(list);
return kftMapper.insertForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
memoryQueue.memoryEnQueue(data); memoryQueue.memoryEnQueue(data);

View File

@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@ -63,6 +66,13 @@ public class LmsQueueService implements QueueAction {
return lmsMapper.insert(data); return lmsMapper.insert(data);
} }
@Override
@Transactional
public int saveMessageForList(List<BasicMessageDto> list) {
lmsMapper.insertGroupForList(list);
return lmsMapper.insertForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
memoryQueue.memoryEnQueue(data); memoryQueue.memoryEnQueue(data);

View File

@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@ -63,6 +66,13 @@ public class MmsQueueService implements QueueAction {
return mmsMapper.insert(data); return mmsMapper.insert(data);
} }
@Override
@Transactional
public int saveMessageForList(List<BasicMessageDto> list) {
mmsMapper.insertGroupForList(list);
return mmsMapper.insertForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
memoryQueue.memoryEnQueue(data); memoryQueue.memoryEnQueue(data);

View File

@ -3,6 +3,8 @@ package com.munjaon.server.queue.service;
import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.dto.BasicMessageDto;
import com.munjaon.server.queue.pool.WriteQueue; import com.munjaon.server.queue.pool.WriteQueue;
import java.util.List;
public interface QueueAction { public interface QueueAction {
int getQueueSize(); int getQueueSize();
boolean isExistQueue(String name); boolean isExistQueue(String name);
@ -10,6 +12,7 @@ public interface QueueAction {
void addQueue(WriteQueue queue); void addQueue(WriteQueue queue);
void pushQueue(BasicMessageDto data); void pushQueue(BasicMessageDto data);
int saveMessageToTable(BasicMessageDto data); int saveMessageToTable(BasicMessageDto data);
int saveMessageForList(List<BasicMessageDto> list);
void memoryEnQueue(BasicMessageDto data); void memoryEnQueue(BasicMessageDto data);
BasicMessageDto memoryDeQueue(); BasicMessageDto memoryDeQueue();

View File

@ -9,6 +9,9 @@ import com.munjaon.server.queue.pool.WriteQueue;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@ -54,6 +57,7 @@ public class SmsQueueService implements QueueAction {
} }
@Override @Override
@Transactional
public int saveMessageToTable(BasicMessageDto data) { public int saveMessageToTable(BasicMessageDto data) {
String serialNo = serialNoService.getSerialNo(); String serialNo = serialNoService.getSerialNo();
String groupSerialNo = serialNo.replace("MSGID", "MGRP"); String groupSerialNo = serialNo.replace("MSGID", "MGRP");
@ -63,6 +67,13 @@ public class SmsQueueService implements QueueAction {
return smsMapper.insert(data); return smsMapper.insert(data);
} }
@Override
@Transactional
public int saveMessageForList(List<BasicMessageDto> list) {
smsMapper.insertGroupForList(list);
return smsMapper.insertForList(list);
}
@Override @Override
public void memoryEnQueue(BasicMessageDto data) { public void memoryEnQueue(BasicMessageDto data) {
memoryQueue.memoryEnQueue(data); memoryQueue.memoryEnQueue(data);

View File

@ -4,6 +4,7 @@ import com.munjaon.server.cache.service.MemberService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@ -19,7 +20,7 @@ public class CacheScheduleService {
/* 사용자 설정 테이블 마지막 업데이트 시간 */ /* 사용자 설정 테이블 마지막 업데이트 시간 */
private String config_last_modified_time = null; private String config_last_modified_time = null;
// @Scheduled(cron="0/5 * * * * *") @Scheduled(cron="0/5 * * * * *")
public void doService() throws Exception { public void doService() throws Exception {
doMemberService(); doMemberService();
} }

View File

@ -4,10 +4,16 @@ public final class ServerConfig {
/* 서버 타임아웃 체크 시간 */ /* 서버 타임아웃 체크 시간 */
public static final int CYCLE_SOCKET_TIMEOUT = 3000; public static final int CYCLE_SOCKET_TIMEOUT = 3000;
/* 서버 연결후 로그인 만료 시간 */ /* 서버 연결후 로그인 만료 시간 */
public static final int LIMIT_BIND_TIMEOUT = 5000; public static final int LIMIT_BIND_TIMEOUT = 3000;
/* Session Check 만료 시간 */ /* Session Check 만료 시간 */
public static final int LIMIT_LINK_CHECK_TIMEOUT = 10000; public static final int LIMIT_LINK_CHECK_TIMEOUT = 10000;
/* 서버 프로퍼티 reload interval 시간 */ /* 서버 프로퍼티 reload interval 시간 */
public static final Long INTERVAL_PROPERTY_RELOAD_TIME = 3000L; public static final Long INTERVAL_PROPERTY_RELOAD_TIME = 3000L;
/* 사용자 정보 조회 체크 시간 */
public static final long USER_STATUS_CYCLE_TIME = 60000;
/* Deliver Thread 실행 시간 */
public static final long DELIVER_EXEC_CYCLE_TIME = 5000;
/* Report Thread 실행 시간 */
public static final long REPORT_EXEC_CYCLE_TIME = 5000;
} }

View File

@ -24,7 +24,10 @@ public class ConnectUserDto {
private String remoteIP; private String remoteIP;
/* 요금제(선불 : P / 후불 : A) */ /* 요금제(선불 : P / 후불 : A) */
private final String feeType = "A"; private final String feeType = "A";
private int command; //요청 command /* 요청 command */
private int command;
/* 요청을 처리중인지 여부 */
private boolean isRunningMode;
private MemberDto memberDto; private MemberDto memberDto;

View File

@ -21,6 +21,9 @@ public class ReportUserDto {
private ReportQueue reportQueue; //ReportQueue private ReportQueue reportQueue; //ReportQueue
private MemberDto memberDto; //사용자 정보 private MemberDto memberDto; //사용자 정보
private int command; //요청 command private int command; //요청 command
private int maxWriteCount; //요청 command
/* 요청을 처리중인지 여부 */
private boolean isRunningMode;
public int isAlive() { public int isAlive() {
if (isLogin) { if (isLogin) {

View File

@ -1,34 +1,31 @@
package com.munjaon.server.server.sample; package com.munjaon.server.server.sample;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main { public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException { public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService e = Executors.newFixedThreadPool(5); ExecutorService e = Executors.newFixedThreadPool(5);
// 리턴 값이 필요 없는 경우 // 리턴 값이 필요 없는 경우
// for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
// e.execute(new MyRunnable(i * 20)); e.execute(new MyRunnable(i * 20));
// } }
// 작업을 기다려야 경우 // 작업을 기다려야 경우
//e.shutdown(); e.shutdown();
// 리턴 값이 필요한 경우 // 리턴 값이 필요한 경우
List<Future<Integer>> l = new ArrayList<>(); // List<Future<Integer>> l = new ArrayList<>();
for (int i = 0; i < 5; i++) { // for (int i = 0; i < 5; i++) {
Future<Integer> f = e.submit(new MyCallable(i * 20)); // Future<Integer> f = e.submit(new MyCallable(i * 20));
l.add(f); // l.add(f);
} // }
//
// 작업이 완료 되길 기다려야 경우 // // 작업이 완료 되길 기다려야 경우
int n = 0; // int n = 0;
for (int i = 0; i < 5; i++) { // for (int i = 0; i < 5; i++) {
Future<Integer> f = l.get(i); // Future<Integer> f = l.get(i);
n += f.get(); // n += f.get();
} // }
} }
} }

View File

@ -7,8 +7,9 @@ public class MyRunnable implements Runnable {
} }
public void run() { public void run() {
System.out.println("SendReadTask start : " + Thread.currentThread().getName());
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
System.out.println(s + " : MyRunnable"); System.out.println(s + " : MyRunnable : " + Thread.currentThread().getName());
System.out.println(i + s); System.out.println(i + s);
try { try {
Thread.sleep(1000L); Thread.sleep(1000L);

View File

@ -0,0 +1,184 @@
package com.munjaon.server.server.service;
import com.munjaon.server.queue.enums.QueueTypeWorker;
import com.munjaon.server.server.config.ServerConfig;
import com.munjaon.server.server.dto.ConnectUserDto;
import com.munjaon.server.server.queue.CollectUserQueue;
import com.munjaon.server.server.task.CollectServerTask;
import com.munjaon.server.server.task.StatusCheckTask;
import org.json.simple.JSONObject;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class CollectServer extends Service {
private final InetSocketAddress listenAddress;
private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance();
private Selector selector;
private final String serviceType;
private long USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis();
public CollectServer(String serviceName, String serviceType, int port) {
super(serviceName);
this.listenAddress = new InetSocketAddress(port);
this.serviceType = serviceType;
}
@Override
public void checkReady() {
QueueTypeWorker worker = QueueTypeWorker.find(this.serviceType);
if (worker != null && worker.getQueueSize() > 0) {
this.IS_READY_YN = true;
saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS READY ... ...");
} else {
this.IS_READY_YN = false;
saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS NOT READY ... ...");
}
}
@Override
public void initResources() {
try {
saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZING ... ...");
initCollectChannel();
saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZED ... ...");
} catch (IOException e) {
saveSystemLog(e);
throw new RuntimeException(e);
}
}
private void initCollectChannel() throws IOException {
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZING ... ...");
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER PORT [" + listenAddress.getPort() + "]");
selector = Selector.open();
/* 채널 생성 */
ServerSocketChannel serverChannel = ServerSocketChannel.open();
/* non-Blocking 설정 */
serverChannel.configureBlocking(false);
/* 서버 ip, port 설정 */
serverChannel.socket().bind(listenAddress);
/* 채널에 accept 대기 설정 */
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZED ... ...");
}
private void closeCollectChannel() throws IOException {
selector.close();
}
@Override
public void releaseResources() {
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASING ... ...");
try {
closeCollectChannel();
} catch (IOException e) {
saveSystemLog(e);
throw new RuntimeException(e);
}
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASED ... ...");
}
@Override
public void doService() {
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STARTED ... ...");
while (isRun()) {
try {
execInterest();
execUserStatus();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STOPPED ... ...");
}
private void execInterest() throws IOException {
if (selector.select(1000) == 0) {
return ;
}
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
/* 키 셋에서 제거. */
keys.remove();
if (key.isValid()) {
if (key.isAcceptable()) { // 접속일 경우..
saveSystemLog("CONNECTION IS ACCEPTABLE ... ...");
accept(selector, key);
} else if (key.isReadable()) { // 수신일 경우..
ConnectUserDto connectUserDto = (ConnectUserDto) key.attachment();
if (connectUserDto == null || connectUserDto.isRunningMode()) {
continue;
}
/* 사용자별 Collect Thread 실행 */
new CollectServerTask(selector, key, getName(), this.serviceType, logger).run();
}
} else {
expireConnectUser(key);
}
}
}
private void execUserStatus() throws IOException {
if (System.currentTimeMillis() - USER_STATUS_LAST_CHECK_TIME > ServerConfig.USER_STATUS_CYCLE_TIME) {
new StatusCheckTask(this.serviceType, logger).run();
USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis();
}
}
private void accept(Selector selector, SelectionKey key) {
try {
/* 키 채널을 가져온다. */
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
/* accept을 해서 Socket 채널을 가져온다. */
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
/* 소켓 취득 */
Socket socket = channel.socket();
InetAddress inetAddress = socket.getInetAddress();
saveSystemLog("[CLIENT CONNECTION IP : " + inetAddress.getHostAddress() + "]");
// Socket 채널을 channel에 수신 등록한다
channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().serviceType(this.serviceType).lastTrafficTime(System.currentTimeMillis()).remoteIP(inetAddress.getHostAddress()).build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void expireConnectUser(SelectionKey key) {
if (key == null || !key.isValid()) {
return;
}
try {
SocketChannel channel = (SocketChannel) key.channel();
ConnectUserDto userDto = (ConnectUserDto) key.attachment();
if (userDto != null && userDto.getUserId() != null) {
saveSystemLog("[CLIENT USER IS DISCONNECT : " + userDto.toString() + "]");
collectUserQueue.removeUser(this.serviceType, userDto.getUserId());
// connectUserMap.remove(userDto.getUserId());
key.attach(null);
}
// 소켓 채널 닫기
channel.close();
// 닫기
key.cancel();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public JSONObject monitorService() {
return null;
}
}

View File

@ -4,14 +4,16 @@ import com.munjaon.server.queue.enums.QueueTypeWorker;
import com.munjaon.server.server.dto.ConnectUserDto; import com.munjaon.server.server.dto.ConnectUserDto;
import com.munjaon.server.server.queue.CollectUserQueue; import com.munjaon.server.server.queue.CollectUserQueue;
import com.munjaon.server.server.task.CollectReadTask; import com.munjaon.server.server.task.CollectReadTask;
import com.munjaon.server.server.task.SendReadTask;
import com.munjaon.server.server.task.StatusCheckTask;
import com.munjaon.server.util.LogUtil; import com.munjaon.server.util.LogUtil;
import lombok.Getter; import lombok.Getter;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketAddress;
import java.nio.channels.SelectionKey; import java.nio.channels.SelectionKey;
import java.nio.channels.Selector; import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel; import java.nio.channels.ServerSocketChannel;
@ -21,17 +23,24 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.concurrent.ExecutionException;
import java.util.concurrent.*; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CollectServerService extends Service { public class CollectServerService extends Service {
private final InetSocketAddress listenAddress; private final InetSocketAddress listenAddress;
private CollectThreadService threadService; private CollectThreadService threadService;
private StatusThreadService statusThreadService;
private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance();
private Selector selector; private Selector selector;
private final String serviceType; private final String serviceType;
private int readMaxCore; private int readMaxCore;
private long USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis();
private static final long USER_STATUS_CYCLE_TIME = 60000;
public CollectServerService(String serviceName, String serviceType, int port) { public CollectServerService(String serviceName, String serviceType, int port) {
super(serviceName); super(serviceName);
this.readMaxCore = Integer.parseInt(getProp("READ_MAX_CORE").trim()); this.readMaxCore = Integer.parseInt(getProp("READ_MAX_CORE").trim());
@ -44,17 +53,21 @@ public class CollectServerService extends Service {
QueueTypeWorker worker = QueueTypeWorker.find(this.serviceType); QueueTypeWorker worker = QueueTypeWorker.find(this.serviceType);
if (worker != null && worker.getQueueSize() > 0) { if (worker != null && worker.getQueueSize() > 0) {
this.IS_READY_YN = true; this.IS_READY_YN = true;
saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS READY ... ...");
} else { } else {
this.IS_READY_YN = false; this.IS_READY_YN = false;
saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS NOT READY ... ...");
} }
saveSystemLog("CollectServerService ready : " + this.IS_READY_YN);
} }
@Override @Override
public void initResources() { public void initResources() {
try { try {
saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZING ... ...");
initCollectChannel(); initCollectChannel();
threadService = new CollectThreadService(readMaxCore, this.serviceType, logger); threadService = new CollectThreadService(readMaxCore, this.serviceType, logger);
statusThreadService = new StatusThreadService(this.serviceType, this.logger);
saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZED ... ...");
} catch (IOException e) { } catch (IOException e) {
saveSystemLog(e); saveSystemLog(e);
throw new RuntimeException(e); throw new RuntimeException(e);
@ -62,6 +75,8 @@ public class CollectServerService extends Service {
} }
private void initCollectChannel() throws IOException { private void initCollectChannel() throws IOException {
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZING ... ...");
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER PORT [" + listenAddress.getPort() + "]");
selector = Selector.open(); selector = Selector.open();
/* 채널 생성 */ /* 채널 생성 */
ServerSocketChannel serverChannel = ServerSocketChannel.open(); ServerSocketChannel serverChannel = ServerSocketChannel.open();
@ -71,6 +86,7 @@ public class CollectServerService extends Service {
serverChannel.socket().bind(listenAddress); serverChannel.socket().bind(listenAddress);
/* 채널에 accept 대기 설정 */ /* 채널에 accept 대기 설정 */
serverChannel.register(selector, SelectionKey.OP_ACCEPT); serverChannel.register(selector, SelectionKey.OP_ACCEPT);
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZED ... ...");
} }
private void closeCollectChannel() throws IOException { private void closeCollectChannel() throws IOException {
@ -79,24 +95,58 @@ public class CollectServerService extends Service {
@Override @Override
public void releaseResources() { public void releaseResources() {
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASING ... ...");
try { try {
closeCollectChannel(); closeCollectChannel();
threadService.close(); threadService.close();
statusThreadService.close();
} catch (IOException e) { } catch (IOException e) {
saveSystemLog(e); saveSystemLog(e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASED ... ...");
} }
@Override @Override
public void doService() { public void doService() {
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STARTED ... ...");
while (isRun()) { while (isRun()) {
try { try {
execInterest(); execInterest();
execUserStatus();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STOPPED ... ...");
}
private void execInterest_bak() throws IOException {
if (selector.select(1000) == 0) {
return ;
}
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
/* 키 셋에서 제거. */
keys.remove();
if (key.isValid()) {
if (key.isAcceptable()) { // 접속일 경우..
saveSystemLog("CONNECTION IS ACCEPTABLE ... ...");
accept(selector, key);
} else if (key.isReadable()) { // 수신일 경우..
ConnectUserDto connectUserDto = (ConnectUserDto) key.attachment();
if (connectUserDto == null || connectUserDto.isRunningMode()) {
continue;
}
threadService.execute(new SendReadTask(selector, key, this.serviceType, logger));
// threadService.submit(selector, key, 2);
}
} else {
expireConnectUser(key);
}
}
} }
private void execInterest() throws IOException { private void execInterest() throws IOException {
@ -112,10 +162,9 @@ public class CollectServerService extends Service {
if (key.isValid()) { if (key.isValid()) {
if (key.isAcceptable()) { // 접속일 경우.. if (key.isAcceptable()) { // 접속일 경우..
saveSystemLog("isAcceptable"); saveSystemLog("CONNECTION IS ACCEPTABLE ... ...");
accept(selector, key); accept(selector, key);
} else if (key.isReadable()) { // 수신일 경우.. } else if (key.isReadable()) { // 수신일 경우..
saveSystemLog("isReadable");
Future<ConnectUserDto> future = threadService.submit(new CollectReadTask(selector, key, this.serviceType, logger)); Future<ConnectUserDto> future = threadService.submit(new CollectReadTask(selector, key, this.serviceType, logger));
list.add(future); list.add(future);
// threadService.submit(selector, key, 2); // threadService.submit(selector, key, 2);
@ -132,14 +181,19 @@ public class CollectServerService extends Service {
} catch (ExecutionException e) { } catch (ExecutionException e) {
} }
if (connectUserDto == null) { if (connectUserDto != null) {
saveSystemLog("Future : " + future); saveSystemLog("[READ USER : " + connectUserDto.toString() + "]");
} else {
saveSystemLog("Future : " + connectUserDto.toString());
} }
} }
} }
private void execUserStatus() throws IOException {
if (System.currentTimeMillis() - USER_STATUS_LAST_CHECK_TIME > USER_STATUS_CYCLE_TIME) {
statusThreadService.execute(new StatusCheckTask(this.serviceType, logger));
USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis();
}
}
private void accept(Selector selector, SelectionKey key) { private void accept(Selector selector, SelectionKey key) {
try { try {
/* 키 채널을 가져온다. */ /* 키 채널을 가져온다. */
@ -149,10 +203,10 @@ public class CollectServerService extends Service {
channel.configureBlocking(false); channel.configureBlocking(false);
/* 소켓 취득 */ /* 소켓 취득 */
Socket socket = channel.socket(); Socket socket = channel.socket();
SocketAddress remoteAddr = socket.getRemoteSocketAddress(); InetAddress inetAddress = socket.getInetAddress();
saveSystemLog("Connected to: " + remoteAddr); saveSystemLog("[CLIENT CONNECTION IP : " + inetAddress.getHostAddress() + "]");
// Socket 채널을 channel에 수신 등록한다 // Socket 채널을 channel에 수신 등록한다
channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().serviceType(this.serviceType).lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).build()); channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().serviceType(this.serviceType).lastTrafficTime(System.currentTimeMillis()).remoteIP(inetAddress.getHostAddress()).build());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -166,6 +220,7 @@ public class CollectServerService extends Service {
SocketChannel channel = (SocketChannel) key.channel(); SocketChannel channel = (SocketChannel) key.channel();
ConnectUserDto userDto = (ConnectUserDto) key.attachment(); ConnectUserDto userDto = (ConnectUserDto) key.attachment();
if (userDto != null && userDto.getUserId() != null) { if (userDto != null && userDto.getUserId() != null) {
saveSystemLog("[CLIENT USER IS DISCONNECT : " + userDto.toString() + "]");
collectUserQueue.removeUser(this.serviceType, userDto.getUserId()); collectUserQueue.removeUser(this.serviceType, userDto.getUserId());
// connectUserMap.remove(userDto.getUserId()); // connectUserMap.remove(userDto.getUserId());
key.attach(null); key.attach(null);
@ -184,27 +239,77 @@ public class CollectServerService extends Service {
return null; return null;
} }
private static class CollectThreadService { private static class StatusThreadService {
@Getter @Getter
private String serviceType; private String serviceType;
@Getter @Getter
private final int maxCore; private final int maxCore = 1;
private final ExecutorService executor; private final ExecutorService executor;
private final Map<String, ConnectUserDto> connectUserMap = new ConcurrentHashMap<>();
private final LogUtil logger; private final LogUtil logger;
public CollectThreadService(String serviceType, LogUtil logger) { public StatusThreadService(String serviceType, LogUtil logger) {
this(Runtime.getRuntime().availableProcessors(), serviceType, logger);
}
public CollectThreadService(int maxCore, String serviceType, LogUtil logger) {
this.maxCore = maxCore;
this.executor = Executors.newFixedThreadPool(maxCore); this.executor = Executors.newFixedThreadPool(maxCore);
this.logger = logger; this.logger = logger;
saveSystemLog("[STATUS_TASK_THREAD_POOL : " + maxCore + "]");
} }
public Future<ConnectUserDto> submit(CollectReadTask collectReadTask) { public void execute(StatusCheckTask statusCheckTask) {
return executor.submit(collectReadTask); executor.execute(statusCheckTask);
}
private void saveSystemLog(Object obj) {
saveLog(obj, true);
}
private void saveLog(Object obj) {
saveLog(obj, false);
}
private void saveLog(Object obj, boolean isConsoleOutput) {
if (isConsoleOutput) {
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{" + serviceType + "}} " + obj);
}
if (logger == null) {
return;
}
logger.log(obj);
}
public void close() {
List<Runnable> unfinishedTasks = executor.shutdownNow();
if (!unfinishedTasks.isEmpty()) {
saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size());
}
}
}
private static class CollectThreadService {
@Getter
private String serviceType;
@Getter
private final int maxCore;
private final ExecutorService executor;
private final LogUtil logger;
public CollectThreadService(String serviceType, LogUtil logger) {
this(Runtime.getRuntime().availableProcessors(), serviceType, logger);
}
public CollectThreadService(int maxCore, String serviceType, LogUtil logger) {
this.maxCore = maxCore;
this.executor = Executors.newFixedThreadPool(maxCore);
this.logger = logger;
saveSystemLog("[COLLECT_TASK_THREAD_POOL : " + maxCore + "]");
}
public Future<ConnectUserDto> submit(CollectReadTask collectReadTask) {
return executor.submit(collectReadTask);
}
public void execute(SendReadTask sendReadTask) {
executor.execute(sendReadTask);
} }
private void saveSystemLog(Object obj) { private void saveSystemLog(Object obj) {
@ -229,7 +334,6 @@ public class CollectServerService extends Service {
public void close() { public void close() {
List<Runnable> unfinishedTasks = executor.shutdownNow(); List<Runnable> unfinishedTasks = executor.shutdownNow();
connectUserMap.clear();
if (!unfinishedTasks.isEmpty()) { if (!unfinishedTasks.isEmpty()) {
saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size()); saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size());
} }

View File

@ -3,14 +3,18 @@ package com.munjaon.server.server.service;
import com.munjaon.server.queue.dto.BasicMessageDto; import com.munjaon.server.queue.dto.BasicMessageDto;
import com.munjaon.server.queue.enums.QueueTypeWorker; import com.munjaon.server.queue.enums.QueueTypeWorker;
import com.munjaon.server.queue.pool.ReadQueue; import com.munjaon.server.queue.pool.ReadQueue;
import com.munjaon.server.queue.pool.SerialQueuePool;
import com.munjaon.server.queue.pool.WriteQueue; import com.munjaon.server.queue.pool.WriteQueue;
import com.munjaon.server.util.CommonUtil; import com.munjaon.server.util.CommonUtil;
import com.munjaon.server.util.MessageUtil;
import com.munjaon.server.util.ServiceUtil; import com.munjaon.server.util.ServiceUtil;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class QueueServerService extends Service { public class QueueServerService extends Service {
/** 큐모드 설정(WAIT : 파일에 쓰기모드만 / DB : DB에 적재) */ /** 큐모드 설정(WAIT : 파일에 쓰기모드만 / DB : DB에 적재) */
@ -21,6 +25,7 @@ public class QueueServerService extends Service {
private long QUEUE_INIT_CHECK_TIME = 0; private long QUEUE_INIT_CHECK_TIME = 0;
/** Commit 누적 카운트 */ /** Commit 누적 카운트 */
private long SUM_COMMIT_COUNT = 0; private long SUM_COMMIT_COUNT = 0;
SerialQueuePool queueInstance = SerialQueuePool.getInstance();
/* 쓰기큐 */ /* 쓰기큐 */
private WriteQueue writeQueue; private WriteQueue writeQueue;
private ReadQueue readQueue; private ReadQueue readQueue;
@ -49,7 +54,7 @@ public class QueueServerService extends Service {
@Override @Override
public void checkReady() { public void checkReady() {
this.IS_READY_YN = true; this.IS_READY_YN = queueInstance.isReady();
} }
@Override @Override
@ -109,6 +114,8 @@ public class QueueServerService extends Service {
} }
// 큐초기화 대상이면 // 큐초기화 대상이면
if (isQueueInit) { if (isQueueInit) {
/* 큐 백업 */
writeQueue.backupQueue();
/* 커밋 카운트 초기화 */ /* 커밋 카운트 초기화 */
SUM_COMMIT_COUNT = 0; SUM_COMMIT_COUNT = 0;
writeQueue.truncateQueue(); writeQueue.truncateQueue();
@ -158,6 +165,8 @@ public class QueueServerService extends Service {
isQueueInit = true; isQueueInit = true;
} }
if (isQueueInit) { if (isQueueInit) {
/* 큐 백업 */
writeQueue.backupQueue();
/* 커밋 카운트 초기화 */ /* 커밋 카운트 초기화 */
SUM_COMMIT_COUNT = 0; SUM_COMMIT_COUNT = 0;
// 큐를 초기화한다. // 큐를 초기화한다.
@ -171,6 +180,34 @@ public class QueueServerService extends Service {
} }
private void messageService() throws Exception { private void messageService() throws Exception {
int DB_PROC_COUNT = 0;
List<BasicMessageDto> list = new ArrayList<>();
for (int loopCnt = 0; loopCnt < ServiceUtil.COMMIT_COUNT; loopCnt++) {
BasicMessageDto messageDto = readQueue.popMessageFromBuffer();
if (messageDto == null) {
break;
}
/* MSG ID 채번 */
String msgId = queueInstance.getSerialNumber();
msgId = MessageUtil.makeMessageKey(msgId);
String msgGroupId = msgId.replace("MSGID", "MGRP");
messageDto.setId(msgId);
messageDto.setMsgGroupID(msgGroupId);
list.add(messageDto);
DB_PROC_COUNT++;
SUM_COMMIT_COUNT++;
}
// DB 처리한 카운트에 대한 처리
if (DB_PROC_COUNT > 0) {
worker.saveMessageForList(list);
Thread.sleep(10);
} else {
Thread.sleep(100);
}
}
private void messageService_bak() throws Exception {
int DB_PROC_COUNT = 0; int DB_PROC_COUNT = 0;
for (int loopCnt = 0; loopCnt < ServiceUtil.COMMIT_COUNT; loopCnt++) { for (int loopCnt = 0; loopCnt < ServiceUtil.COMMIT_COUNT; loopCnt++) {
BasicMessageDto messageDto = readQueue.popMessageFromBuffer(); BasicMessageDto messageDto = readQueue.popMessageFromBuffer();

View File

@ -17,10 +17,12 @@ public class ReportQueueServerService extends Service {
private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance(); private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance();
private QueueThreadService threadService; private QueueThreadService threadService;
private int queueMaxCore; private int queueMaxCore;
private int maxWriteCount;
public ReportQueueServerService(String serviceName) { public ReportQueueServerService(String serviceName) {
super(serviceName); super(serviceName);
this.queueMaxCore = Integer.parseInt(getProp("QUEUE_MAX_CORE").trim()); this.queueMaxCore = Integer.parseInt(getProp("QUEUE_MAX_CORE").trim());
this.maxWriteCount = Integer.parseInt(getProp("MAX_WRITE_COUNT").trim());
} }
@Override @Override
@ -43,7 +45,7 @@ public class ReportQueueServerService extends Service {
while (isRun()) { while (isRun()) {
try { try {
doQueueService(); doQueueService();
Thread.sleep(100); Thread.sleep(10);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -57,6 +59,7 @@ public class ReportQueueServerService extends Service {
} }
for (ReportUserDto reportUserDto : reportUserList) { for (ReportUserDto reportUserDto : reportUserList) {
reportUserDto.setMaxWriteCount(this.maxWriteCount);
threadService.execute(new ReportQueueTask(reportUserDto, logger)); threadService.execute(new ReportQueueTask(reportUserDto, logger));
} }
} }

View File

@ -0,0 +1,191 @@
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 org.json.simple.JSONObject;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Future;
public class ReportServer extends Service {
private final InetSocketAddress listenAddress;
private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance();
private Selector selector;
public ReportServer(String serviceName, int port) {
super(serviceName);
this.listenAddress = new InetSocketAddress(port);
}
@Override
public void checkReady() {
this.IS_READY_YN = true;
}
@Override
public void initResources() {
try {
initReportChannel();
} catch (IOException e) {
saveSystemLog(e);
throw new RuntimeException(e);
}
}
private void initReportChannel() throws IOException {
selector = Selector.open();
/* 채널 생성 */
ServerSocketChannel serverChannel = ServerSocketChannel.open();
/* non-Blocking 설정 */
serverChannel.configureBlocking(false);
/* 서버 ip, port 설정 */
serverChannel.socket().bind(listenAddress);
/* 채널에 accept 대기 설정 */
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
private void closeReportChannel() throws IOException {
selector.close();
}
@Override
public void releaseResources() {
try {
closeReportChannel();
} catch (IOException e) {
saveSystemLog(e);
throw new RuntimeException(e);
}
}
@Override
public void doService() {
while (isRun()) {
try {
execInterest();
checkInterest();
} catch (Exception e) {
saveSystemLog(e.toString());
}
}
}
private void checkInterest() throws IOException, InterruptedException {
Iterator<SelectionKey> keys = selector.keys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
if (key.isValid()) {
ReportUserDto reportUserDto = (ReportUserDto) key.attachment();
if (reportUserDto == null) {
continue;
}
SocketChannel channel = (SocketChannel) key.channel(); // 채널을 가져온다.
if (reportUserDto.isAlive() == 1) { // 로그인이 완료되지 않은 경우
expireConnectUser(key);
} else if (reportUserDto.isAlive() == 2) {
if (reportUserDto == null || reportUserDto.isRunningMode()) {
continue;
}
} else {
ReportQueue reportQueue = reportUserDto.getReportQueue();
if (reportUserDto.isLogin() && reportQueue != null && reportQueue.isRemainReport()) {
if (reportUserDto.isRunningMode()) {
continue;
}
/* 사용자별 Report Thread 실행 */
}
}
} else {
expireConnectUser(key);
}
}
}
private void execInterest() throws IOException {
if (selector.select(1000) == 0) {
return ;
}
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
List<Future<ReportUserDto>> list = new ArrayList<>();
while (keys.hasNext()) {
SelectionKey key = keys.next();
/* 키 셋에서 제거. */
keys.remove();
if (key.isValid()) {
if (key.isAcceptable()) { // 접속일 경우..
saveSystemLog("CONNECTION IS ACCEPTABLE ... ...");
accept(selector, key);
} else if (key.isReadable()) { // 수신일 경우..
ReportUserDto reportUserDto = (ReportUserDto) key.attachment();
if (reportUserDto == null || reportUserDto.isRunningMode()) {
continue;
}
saveSystemLog("isReadable");
/* 사용자별 Report Thread 실행 */
// threadService.submit(selector, key, 2);
}
} else {
expireConnectUser(key);
}
}
}
private void accept(Selector selector, SelectionKey key) {
try {
/* 키 채널을 가져온다. */
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
/* accept을 해서 Socket 채널을 가져온다. */
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
/* 소켓 취득 */
Socket socket = channel.socket();
SocketAddress remoteAddr = socket.getRemoteSocketAddress();
saveSystemLog("Connected to: " + remoteAddr);
// Socket 채널을 channel에 수신 등록한다
channel.register(selector, SelectionKey.OP_READ, ReportUserDto.builder().lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).queuePath(System.getProperty("ROOTPATH") + File.separator + getProp("QUEUE_PATH")).build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void expireConnectUser(SelectionKey key) {
if (key == null || !key.isValid()) {
return;
}
try {
SocketChannel channel = (SocketChannel) key.channel();
ConnectUserDto userDto = (ConnectUserDto) key.attachment();
if (userDto != null && userDto.getUserId() != null) {
reportUserQueue.removeUser(userDto.getUserId());
// connectUserMap.remove(userDto.getUserId());
key.attach(null);
}
// 소켓 채널 닫기
channel.close();
// 닫기
key.cancel();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public JSONObject monitorService() {
return null;
}
}

View File

@ -62,7 +62,7 @@ public class ReportServerService extends Service {
public void initResources() { public void initResources() {
try { try {
initReportChannel(); initReportChannel();
threadService = new ReadThreadService(8, logger); threadService = new ReadThreadService(readMaxCore, logger);
} catch (IOException e) { } catch (IOException e) {
saveSystemLog(e); saveSystemLog(e);
throw new RuntimeException(e); throw new RuntimeException(e);
@ -142,7 +142,6 @@ public class ReportServerService extends Service {
try { try {
ReportDto reportDto = reportQueue.popReportFromQueue(); ReportDto reportDto = reportQueue.popReportFromQueue();
if (reportDto == null) { if (reportDto == null) {
saveSystemLog("reportQueue.popReportFromQueue() : null");
continue; continue;
} }
saveSystemLog("reportQueue.popReportFromQueue() : " + reportDto.toString()); saveSystemLog("reportQueue.popReportFromQueue() : " + reportDto.toString());

View File

@ -77,6 +77,11 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
} }
private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
/* 서비스 중지여부 체크 */
if (isExpireService()) {
expireConnectUser();
return;
}
switch (this.serviceType) { switch (this.serviceType) {
case "SMS": case "SMS":
recvSmsDeliver(channel, headBuffer); recvSmsDeliver(channel, headBuffer);
@ -97,6 +102,40 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
} }
} }
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;
}
if (collectUserQueue.isExist(this.serviceType, memberDto.getMberId()) == false) {
return true;
}
/* 회원 사용 상태 */
if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
return true;
}
/* 서비스 이용 상태 */
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return true;
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return true;
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return true;
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return true;
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return true;
}
return false;
}
public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) { public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) {
if (deliverBuffer == null) { if (deliverBuffer == null) {
return null; return null;
@ -116,6 +155,7 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
return messageDto; return messageDto;
} }
private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try { try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH); ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH);
@ -126,7 +166,18 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
// Packet.printBuffer(deliverBuffer); // Packet.printBuffer(deliverBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer)); messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer));
System.out.println("BasicMessageDto : " + messageDto.toString());
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getSmsAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice()));
}
saveSystemLog("[SMS] [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);
@ -148,6 +199,17 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer)); messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer)); messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer));
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getLmsAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice()));
}
saveSystemLog("[LMS] [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);
@ -173,11 +235,8 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
if (fileCount != null && fileCount.length() > 0) { if (fileCount != null && fileCount.length() > 0) {
recvFileCount = Integer.parseInt(fileCount); recvFileCount = Integer.parseInt(fileCount);
messageDto.setUserFileCnt(recvFileCount); messageDto.setUserFileCnt(recvFileCount);
saveSystemLog("recvFileCount : " + recvFileCount);
} }
saveSystemLog("messageDto : " + messageDto.toString());
String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile"; String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile";
imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(imagePath); FileUtil.mkdirs(imagePath);
@ -198,9 +257,28 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
} else if (i == 2) { } else if (i == 2) {
messageDto.setUserFileName03(imagePath + File.separator + fileName); messageDto.setUserFileName03(imagePath + File.separator + fileName);
} }
saveSystemLog("File : " + fileName + ", Size : " + fileSize); saveSystemLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]");
} }
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getMmsAgentCode());
float mmsPrice = 0.0F;
if (recvFileCount == 1) {
mmsPrice = savedMemberDto.getPicturePrice();
} else if (recvFileCount == 2) {
mmsPrice = savedMemberDto.getPicture2Price();
} else {
mmsPrice = savedMemberDto.getPicture3Price();
}
messageDto.setUnitCost(String.valueOf(mmsPrice));
}
saveSystemLog("[MMS] [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);
@ -224,8 +302,6 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer));
messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer));
saveSystemLog("messageDto : " + messageDto.toString());
String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile";
jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(jsonPath); FileUtil.mkdirs(jsonPath);
@ -242,8 +318,19 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
saveSystemLog("File : " + fileName + ", Size : " + fileSize); saveSystemLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getKakaoAtAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice()));
}
saveSystemLog("[KAKAO ALARM] [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);
@ -269,8 +356,6 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer));
messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer));
saveSystemLog("messageDto : " + messageDto.toString());
String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile";
jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(jsonPath); FileUtil.mkdirs(jsonPath);
@ -287,8 +372,19 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
saveSystemLog("File : " + fileName + ", Size : " + fileSize); saveSystemLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getKakaoFtAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice()));
}
saveSystemLog("[KAKAO FRIEND] [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);
@ -304,6 +400,11 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
channel.read(bodyBuffer); channel.read(bodyBuffer);
// SocketChannel channel = (SocketChannel) key.channel(); // SocketChannel channel = (SocketChannel) key.channel();
channel.write(LinkCheck.makeLinkCheckAckBuffer()); channel.write(LinkCheck.makeLinkCheckAckBuffer());
/* 서비스 중지여부 체크 */
if (isExpireService()) {
expireConnectUser();
return;
}
} }
private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { private void recvBind(SocketChannel channel, ByteBuffer headBuffer) {
@ -316,29 +417,46 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
String id = Bind.getBindId(bindBuffer); String id = Bind.getBindId(bindBuffer);
String pwd = Bind.getBindPwd(bindBuffer); String pwd = Bind.getBindPwd(bindBuffer);
saveSystemLog("Bind id : " + id);
saveSystemLog("Bind pwd : " + pwd); MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService();
if (id == null || pwd == null) { MemberDto memberDto = null;
resultCode = "50"; if (svc != null) {
} else { memberDto = svc.get(id);
if (collectUserQueue.isExist(this.serviceType, id)) { }
resultCode = "60"; saveSystemLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]");
/* Bind Check */
resultCode = checkBind(memberDto, this.serviceType, id, pwd);
/* 접속 IP 체크 */
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());
if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) {
isPermit = true;
}
if (memberDto.getAllowIpExtend() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) {
isPermit = true;
}
} else { } else {
MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); isPermit = true;
MemberDto memberDto = null;
if (svc != null) {
memberDto = svc.get(id);
}
if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
resultCode = "20";
} else {
connectUserDto.setUserId(id);
connectUserDto.setLogin(true);
connectUserDto.setMemberDto(memberDto);
/* 세션통신 시간 업데이트 */
connectUserDto.updateLastTrafficTime();
}
} }
if (isPermit) {
resultCode = "00";
} else {
resultCode = "40";
}
}
if ("00".equals(resultCode)) {
connectUserDto.setUserId(id);
connectUserDto.setLogin(true);
connectUserDto.setMemberDto(memberDto);
/* 사용자 Pool에 저장 */
collectUserQueue.putUser(this.serviceType, connectUserDto);
/* 세션통신 시간 업데이트 */
connectUserDto.updateLastTrafficTime();
} }
} catch (Exception e) { } catch (Exception e) {
resultCode = "10"; resultCode = "10";
@ -346,7 +464,7 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
} }
try { try {
saveSystemLog("Bind ResultCode : " + resultCode); saveSystemLog("[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();
@ -356,6 +474,60 @@ public class CollectReadTask implements Callable<ConnectUserDto> {
} }
} }
private String checkBind(MemberDto memberDto, String serviceType, String id, String pwd) {
if (id == null || pwd == null) {
return "50";
}
if (collectUserQueue.isExist(this.serviceType, id)) {
return "60";
}
if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
return "20";
}
/* 회원 사용 상태 */
if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
return "30";
}
/* 서비스 이용 상태 */
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return "30";
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return "30";
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return "30";
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return "30";
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return "30";
}
return "00";
}
private String checkService(MemberDto memberDto, String serviceType) {
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return "30";
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return "30";
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return "30";
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return "30";
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return "30";
}
return "00";
}
private void expireConnectUser() { private void expireConnectUser() {
if (key == null || !key.isValid()) { if (key == null || !key.isValid()) {
return; return;

View File

@ -0,0 +1,635 @@
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.dto.BasicMessageDto;
import com.munjaon.server.queue.enums.QueueTypeWorker;
import com.munjaon.server.server.config.ServerConfig;
import com.munjaon.server.server.dto.ConnectUserDto;
import com.munjaon.server.server.packet.*;
import com.munjaon.server.server.queue.CollectUserQueue;
import com.munjaon.server.server.service.PropertyLoader;
import com.munjaon.server.util.*;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CollectServerTask implements Runnable {
public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]");
public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]";
private Selector selector;
private SelectionKey key;
private SocketChannel channel;
private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance();
private ConnectUserDto connectUserDto;
private String serviceName;
private String serviceType;
private final LogUtil logger;
private boolean IS_SERVER_RUN; // 서버가 구동중인지 여부
private boolean IS_RUN_YN;
private long RUN_FLAG_CHECK_TIME;
/* 클라이언트 요청 데이터 수신 */
/* 세션이 만료되었는지 체크 */
private boolean isExpiredYn;
public CollectServerTask(Selector selector, SelectionKey key, String serviceName, String serviceType, LogUtil logger) {
this.selector = selector;
this.key = key;
this.channel = (SocketChannel) key.channel();
this.connectUserDto = (ConnectUserDto) key.attachment();
this.connectUserDto.setRunningMode(true);
this.serviceName = serviceName;
this.serviceType = serviceType;
this.logger = logger;
}
protected String getProp(String name) {
return getProp(this.serviceName, name);
}
public static String getProp(String svc, String name) {
return PropertyLoader.getProp(svc, name);
}
private void reloadRunFlag() {
if (System.currentTimeMillis() - RUN_FLAG_CHECK_TIME > ServerConfig.INTERVAL_PROPERTY_RELOAD_TIME) {
this.IS_RUN_YN = getProp("RUN_FLAG") != null && "Y".equals(getProp("RUN_FLAG"));
this.IS_SERVER_RUN = getProp("server", "run") != null && "Y".equals(getProp("server", "run"));
RUN_FLAG_CHECK_TIME = System.currentTimeMillis();
}
}
public boolean isRun() {
return IS_SERVER_RUN && IS_RUN_YN;
}
@Override
public void run() {
saveSystemLog("CollectServerTask is Entered");
/* 최초 RUN Flag 체크 */
reloadRunFlag();
/* BIND 체크 및 처리 */
while (isRun()) {
/* 만료 여부 체크 */
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 읽기 */
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() - connectUserDto.getLastTrafficTime() > ServerConfig.DELIVER_EXEC_CYCLE_TIME) {
this.isExpiredYn = true;
}
} else {
expireConnectUser();
}
} catch (Exception e) {
size = -1;
e.printStackTrace();
}
/* RUN Flag 체크 */
reloadRunFlag();
}
/* 중요 : 사용자 Thread 실행모드 Off */
connectUserDto.setRunningMode(false);
saveSystemLog("CollectServerTask is Finished");
}
private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
/* 서비스 중지여부 체크 */
if (isExpireService()) {
expireConnectUser();
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;
default:break;
}
}
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;
}
if (collectUserQueue.isExist(this.serviceType, memberDto.getMberId()) == false) {
return true;
}
/* 회원 사용 상태 */
if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
return true;
}
/* 서비스 이용 상태 */
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return true;
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return true;
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return true;
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return true;
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return true;
}
return false;
}
public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) {
if (deliverBuffer == null) {
return null;
}
BasicMessageDto messageDto = new BasicMessageDto();
messageDto.setRouterSeq("40");
messageDto.setServiceType("4");
messageDto.setUserId(connectUserDto.getUserId());
messageDto.setRemoteIP(connectUserDto.getRemoteIP());
messageDto.setSendStatus("0");
messageDto.setUserMsgID(CommonMessage.getMessageIdForDeliver(deliverBuffer));
messageDto.setUserSender(CommonMessage.getSenderForDeliver(deliverBuffer));
messageDto.setUserReceiver(CommonMessage.getReceiverForDeliver(deliverBuffer));
messageDto.setReserveDt(CommonMessage.getReserveTimeForDeliver(deliverBuffer));
messageDto.setRequestDt(CommonMessage.getRequestTimeForDeliver(deliverBuffer));
messageDto.setUnitCost("10.4");
return messageDto;
}
private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + SmsMessage.DELIVER_SMS_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
// Packet.printBuffer(deliverBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer));
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getSmsAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice()));
}
saveLog("[SMS] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("SMS");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(SmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
connectUserDto.updateLastTrafficTime();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvLmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(LmsMessage.DELIVER_LMS_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + LmsMessage.DELIVER_LMS_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer));
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getLmsAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice()));
}
saveSystemLog("[LMS] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("LMS");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(LmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
connectUserDto.updateLastTrafficTime();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvMmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + MmsMessage.DELIVER_MMS_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserSubject(MmsMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(MmsMessage.getMessageForDeliver(deliverBuffer));
String fileCount = MessageUtil.doNumber(MmsMessage.getFileCountForDeliver(deliverBuffer));
int recvFileCount = 0;
if (fileCount != null && fileCount.length() > 0) {
recvFileCount = Integer.parseInt(fileCount);
messageDto.setUserFileCnt(recvFileCount);
}
String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile";
imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(imagePath);
for (int i = 0; i < recvFileCount; i++) {
ByteBuffer fileHeadBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_FILENAME_LENGTH + MmsMessage.DELIVER_MMS_FILESIZE_LENGTH);
channel.read(fileHeadBuffer);
String fileName = MmsMessage.getFileNameForDeliver(fileHeadBuffer);
String fileSize = MmsMessage.getFileSizeForDeliver(fileHeadBuffer);
ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize));
channel.read(fileBuffer);
fileBuffer.flip();
JobFileFactory.saveFileForByteBuffer(imagePath, fileName, fileBuffer);
if (i == 0) {
messageDto.setUserFileName01(imagePath + File.separator + fileName);
} else if (i == 1) {
messageDto.setUserFileName02(imagePath + File.separator + fileName);
} else if (i == 2) {
messageDto.setUserFileName03(imagePath + File.separator + fileName);
}
saveSystemLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]");
}
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getMmsAgentCode());
float mmsPrice = 0.0F;
if (recvFileCount == 1) {
mmsPrice = savedMemberDto.getPicturePrice();
} else if (recvFileCount == 2) {
mmsPrice = savedMemberDto.getPicture2Price();
} else {
mmsPrice = savedMemberDto.getPicture3Price();
}
messageDto.setUnitCost(String.valueOf(mmsPrice));
}
saveSystemLog("[MMS] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("MMS");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(MmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
connectUserDto.updateLastTrafficTime();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvKatDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer));
messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer));
messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer));
String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile";
jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(jsonPath);
ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH);
channel.read(fileHeadBuffer);
String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer);
String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer);
ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize));
channel.read(fileBuffer);
fileBuffer.flip();
JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
saveSystemLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getKakaoAtAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice()));
}
saveSystemLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("KAT");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
connectUserDto.updateLastTrafficTime();
} else {
saveSystemLog("worker is null");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvKftDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer));
messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer));
messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer));
String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile";
jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(jsonPath);
ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH);
channel.read(fileHeadBuffer);
String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer);
String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer);
ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize));
channel.read(fileBuffer);
fileBuffer.flip();
JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
saveSystemLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getKakaoFtAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice()));
}
saveSystemLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("KFT");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
connectUserDto.updateLastTrafficTime();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvLinkCheck(SocketChannel channel) throws IOException {
ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH);
channel.read(bodyBuffer);
// SocketChannel channel = (SocketChannel) key.channel();
channel.write(LinkCheck.makeLinkCheckAckBuffer());
connectUserDto.updateLastTrafficTime();
/* 서비스 중지여부 체크 */
if (isExpireService()) {
expireConnectUser();
return;
}
}
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("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]");
/* Bind Check */
resultCode = checkBind(memberDto, this.serviceType, id, pwd);
/* 접속 IP 체크 */
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());
if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) {
isPermit = true;
}
if (memberDto.getAllowIpExtend() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) {
isPermit = true;
}
} else {
isPermit = true;
}
if (isPermit) {
resultCode = "00";
} else {
resultCode = "40";
}
}
if ("00".equals(resultCode)) {
connectUserDto.setUserId(id);
connectUserDto.setLogin(true);
connectUserDto.setMemberDto(memberDto);
/* 사용자 Pool에 저장 */
collectUserQueue.putUser(this.serviceType, connectUserDto);
/* 세션통신 시간 업데이트 */
connectUserDto.updateLastTrafficTime();
}
} catch (Exception e) {
resultCode = "10";
e.printStackTrace();
}
try {
saveSystemLog("[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 serviceType, String id, String pwd) {
if (id == null || pwd == null) {
return "50";
}
if (collectUserQueue.isExist(this.serviceType, id)) {
return "60";
}
if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
return "20";
}
/* 회원 사용 상태 */
if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
return "30";
}
/* 서비스 이용 상태 */
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return "30";
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return "30";
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return "30";
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return "30";
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return "30";
}
return "00";
}
private String checkService(MemberDto memberDto, String serviceType) {
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return "30";
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return "30";
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return "30";
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return "30";
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return "30";
}
return "00";
}
private void expireConnectUser() {
if (key == null || !key.isValid()) {
return;
}
try {
SocketChannel channel = (SocketChannel) key.channel();
if (connectUserDto != null) {
if (connectUserDto.getUserId() != null) {
collectUserQueue.removeUser(connectUserDto.getServiceType(), connectUserDto.getUserId());
}
key.attach(null);
}
/* 세션 만료 여부 */
this.isExpiredYn = true;
// 소켓 채널 닫기
channel.close();
// 닫기
key.cancel();
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveSystemLog(Object obj) {
saveLog(obj, true);
}
private void saveLog(Object obj) {
saveLog(obj, false);
}
private void saveLog(Object obj, boolean isConsoleOutput) {
if (isConsoleOutput) {
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj);
}
if (logger == null) {
return;
}
logger.log(obj);
}
}

View File

@ -36,6 +36,16 @@ public class ReportQueueTask implements Runnable {
} }
ReportQueue reportQueue = reportUserDto.getReportQueue(); ReportQueue reportQueue = reportUserDto.getReportQueue();
/* 리포트큐에 최대 크기까지 쓰고 모두 리포트는 전송했는지 체크 : 테스트후 적용 */
// if (reportQueue.isWriteLimit(reportUserDto.getMaxWriteCount())) {
// if (reportQueue.isTruncateQueue(reportUserDto.getMaxWriteCount())) {
// try {
// reportQueue.truncateQueue();
// } catch (Exception e) {}
// } else {
// return;
// }
// }
ReportService reportService = (ReportService) CacheService.REPORT_SERVICE.getService(); ReportService reportService = (ReportService) CacheService.REPORT_SERVICE.getService();
List<ReportDto> list = reportService.getReportListForUser(reportUserDto.getUserId()); List<ReportDto> list = reportService.getReportListForUser(reportUserDto.getUserId());
if (list == null || list.isEmpty()) { if (list == null || list.isEmpty()) {

View File

@ -87,21 +87,112 @@ public class ReportReadTask implements Callable<ReportUserDto> {
private void recvReport(SocketChannel channel, ByteBuffer headBuffer) { private void recvReport(SocketChannel channel, ByteBuffer headBuffer) {
try { try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(Report.REPORT_ACK_BODY_LENGTH); ByteBuffer bodyBuffer = ByteBuffer.allocate(Report.REPORT_ACK_BODY_LENGTH);
saveSystemLog("recv report");
int size = channel.read(bodyBuffer); int size = channel.read(bodyBuffer);
if (size > 0) { if (size != Report.REPORT_ACK_BODY_LENGTH) {
ReportQueue reportQueue = reportUserDto.getReportQueue(); return;
reportUserDto.updateLastTrafficTime(); }
if (reportQueue != null) {
reportQueue.addReadCounter(); saveSystemLog("recv report");
} ReportQueue reportQueue = reportUserDto.getReportQueue();
reportUserDto.updateLastTrafficTime();
if (reportQueue != null) {
reportQueue.addReadCounter();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); 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 recvBind(SocketChannel channel, ByteBuffer headBuffer) { 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("[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("connectUserDto.getRemoteIP() : " + reportUserDto.getRemoteIP());
saveSystemLog("Customize Toolbar... : " + memberDto.getAllowIpBasic());
saveSystemLog("memberDto.getAllowIpExtend() : " + 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("Bind ResultCode : " + resultCode);
channel.write(Bind.makeBindAckBuffer(resultCode));
if ("00".equals(resultCode) == false) {
expireConnectUser();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void recvBind_bak(SocketChannel channel, ByteBuffer headBuffer) {
String resultCode = "00"; String resultCode = "00";
try { try {
ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH);

View File

@ -0,0 +1,219 @@
package com.munjaon.server.server.task;
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.queue.ReportUserQueue;
import com.munjaon.server.server.service.PropertyLoader;
import com.munjaon.server.util.LogUtil;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ReportServerTask implements Runnable {
public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]");
public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]";
private Selector selector;
private SelectionKey key;
private SocketChannel channel;
private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance();
private ReportUserDto reportUserDto;
private ReportQueue reportQueue;
private String serviceName;
private final LogUtil logger;
private boolean IS_SERVER_RUN; // 서버가 구동중인지 여부
private boolean IS_RUN_YN;
private long RUN_FLAG_CHECK_TIME;
/* 세션이 만료되었는지 체크 */
private boolean isExpiredYn;
/* Packet을 전송했는지 여부 */
private boolean isPacketSendYn;
public ReportServerTask(Selector selector, SelectionKey key, String serviceName, LogUtil logger) {
this.selector = selector;
this.key = key;
this.channel = (SocketChannel) key.channel();
this.reportUserDto = (ReportUserDto) key.attachment();
this.reportUserDto.setRunningMode(true);
this.serviceName = serviceName;
this.reportQueue = reportUserDto.getReportQueue();
this.logger = logger;
}
protected String getProp(String name) {
return getProp(this.serviceName, name);
}
public static String getProp(String svc, String name) {
return PropertyLoader.getProp(svc, name);
}
private void reloadRunFlag() {
if (System.currentTimeMillis() - RUN_FLAG_CHECK_TIME > ServerConfig.INTERVAL_PROPERTY_RELOAD_TIME) {
this.IS_RUN_YN = getProp("RUN_FLAG") != null && "Y".equals(getProp("RUN_FLAG"));
this.IS_SERVER_RUN = getProp("server", "run") != null && "Y".equals(getProp("server", "run"));
RUN_FLAG_CHECK_TIME = System.currentTimeMillis();
}
}
public boolean isRun() {
return IS_SERVER_RUN && IS_RUN_YN;
}
@Override
public void run() {
saveSystemLog("ReportServerTask is Entered");
/* 최초 RUN Flag 체크 */
reloadRunFlag();
/* BIND 체크 및 처리 */
while (isRun()) {
/* 만료 여부 체크 */
if (isExpiredYn) {
break;
}
try {
sendInterest();
/* RUN Flag 체크 */
reloadRunFlag();
} catch (Exception e) {
this.isExpiredYn = true;
e.printStackTrace();
}
}
/* 중요 : 사용자 Thread 실행모드 Off */
reportUserDto.setRunningMode(false);
saveSystemLog("ReportServerTask is Finished");
}
// 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 sendInterest() throws IOException {
if (reportUserDto.isLogin() == false) {
return;
}
if (reportUserDto.isAlive() == 1) {
expireConnectUser();
} else if (reportUserDto.isAlive() == 2) {
channel.write(LinkCheck.makeLinkCheckBuffer());
/* Packet을 전송했는지 여부 */
isPacketSendYn = true;
} else {
if (this.reportQueue != null && this.reportQueue.isRemainReport()) {
try {
ReportDto reportDto = this.reportQueue.popReportFromQueue();
if (reportDto == null) {
return;
}
saveSystemLog("[REPORT : " + 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을 전송했는지 여부 */
isPacketSendYn = true;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void expireConnectUser() {
if (key == null || !key.isValid()) {
return;
}
try {
SocketChannel channel = (SocketChannel) key.channel();
if (reportUserDto != null) {
if (reportUserDto.getUserId() != null) {
reportUserQueue.removeUser(reportUserDto.getUserId());
}
key.attach(null);
}
/* 세션 만료 여부 */
this.isExpiredYn = true;
// 소켓 채널 닫기
channel.close();
// 닫기
key.cancel();
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveSystemLog(Object obj) {
saveLog(obj, true);
}
private void saveLog(Object obj) {
saveLog(obj, false);
}
private void saveLog(Object obj, boolean isConsoleOutput) {
if (isConsoleOutput) {
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj);
}
if (logger == null) {
return;
}
logger.log(obj);
}
}

View File

@ -0,0 +1,564 @@
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.dto.BasicMessageDto;
import com.munjaon.server.queue.enums.QueueTypeWorker;
import com.munjaon.server.server.dto.ConnectUserDto;
import com.munjaon.server.server.packet.*;
import com.munjaon.server.server.queue.CollectUserQueue;
import com.munjaon.server.util.*;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class SendReadTask implements Runnable {
public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]");
public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]";
private Selector selector;
private SelectionKey key;
private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance();
private ConnectUserDto connectUserDto;
private String serviceType;
private final LogUtil logger;
public SendReadTask(Selector selector, SelectionKey key, String serviceType, LogUtil logger) {
this.selector = selector;
this.key = key;
this.connectUserDto = (ConnectUserDto) key.attachment();
this.serviceType = serviceType;
this.logger = logger;
}
@Override
public void run() {
System.out.println("SendReadTask start : " + Thread.currentThread().getName());
int size = -1;
try {
SocketChannel channel = (SocketChannel) key.channel();
/* 1. Head 읽기 */
ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH);
try {
size = channel.read(headBuffer);
} catch (IOException e) {}
/* 2. Body 읽기 */
if (size > 0) {
// Packet.printBuffer(headBuffer);
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 {
expireConnectUser();
}
} catch (Exception e) {
size = -1;
e.printStackTrace();
}
}
private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
/* 서비스 중지여부 체크 */
if (isExpireService()) {
expireConnectUser();
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;
default:break;
}
}
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;
}
if (collectUserQueue.isExist(this.serviceType, memberDto.getMberId()) == false) {
return true;
}
/* 회원 사용 상태 */
if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
return true;
}
/* 서비스 이용 상태 */
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return true;
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return true;
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return true;
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return true;
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return true;
}
return false;
}
public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) {
if (deliverBuffer == null) {
return null;
}
BasicMessageDto messageDto = new BasicMessageDto();
messageDto.setRouterSeq("40");
messageDto.setServiceType("4");
messageDto.setUserId(connectUserDto.getUserId());
messageDto.setRemoteIP(connectUserDto.getRemoteIP());
messageDto.setSendStatus("0");
messageDto.setUserMsgID(CommonMessage.getMessageIdForDeliver(deliverBuffer));
messageDto.setUserSender(CommonMessage.getSenderForDeliver(deliverBuffer));
messageDto.setUserReceiver(CommonMessage.getReceiverForDeliver(deliverBuffer));
messageDto.setReserveDt(CommonMessage.getReserveTimeForDeliver(deliverBuffer));
messageDto.setRequestDt(CommonMessage.getRequestTimeForDeliver(deliverBuffer));
messageDto.setUnitCost("10.4");
return messageDto;
}
private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + SmsMessage.DELIVER_SMS_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
// Packet.printBuffer(deliverBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer));
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getSmsAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice()));
}
saveSystemLog("[SMS] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("SMS");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(SmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvLmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(LmsMessage.DELIVER_LMS_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + LmsMessage.DELIVER_LMS_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer));
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getLmsAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice()));
}
saveSystemLog("[LMS] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("LMS");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(LmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvMmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + MmsMessage.DELIVER_MMS_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserSubject(MmsMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(MmsMessage.getMessageForDeliver(deliverBuffer));
String fileCount = MessageUtil.doNumber(MmsMessage.getFileCountForDeliver(deliverBuffer));
int recvFileCount = 0;
if (fileCount != null && fileCount.length() > 0) {
recvFileCount = Integer.parseInt(fileCount);
messageDto.setUserFileCnt(recvFileCount);
}
String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile";
imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(imagePath);
for (int i = 0; i < recvFileCount; i++) {
ByteBuffer fileHeadBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_FILENAME_LENGTH + MmsMessage.DELIVER_MMS_FILESIZE_LENGTH);
channel.read(fileHeadBuffer);
String fileName = MmsMessage.getFileNameForDeliver(fileHeadBuffer);
String fileSize = MmsMessage.getFileSizeForDeliver(fileHeadBuffer);
ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize));
channel.read(fileBuffer);
fileBuffer.flip();
JobFileFactory.saveFileForByteBuffer(imagePath, fileName, fileBuffer);
if (i == 0) {
messageDto.setUserFileName01(imagePath + File.separator + fileName);
} else if (i == 1) {
messageDto.setUserFileName02(imagePath + File.separator + fileName);
} else if (i == 2) {
messageDto.setUserFileName03(imagePath + File.separator + fileName);
}
saveSystemLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]");
}
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getMmsAgentCode());
float mmsPrice = 0.0F;
if (recvFileCount == 1) {
mmsPrice = savedMemberDto.getPicturePrice();
} else if (recvFileCount == 2) {
mmsPrice = savedMemberDto.getPicture2Price();
} else {
mmsPrice = savedMemberDto.getPicture3Price();
}
messageDto.setUnitCost(String.valueOf(mmsPrice));
}
saveSystemLog("[MMS] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("MMS");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(MmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvKatDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer));
messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer));
messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer));
String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile";
jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(jsonPath);
ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH);
channel.read(fileHeadBuffer);
String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer);
String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer);
ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize));
channel.read(fileBuffer);
fileBuffer.flip();
JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
saveSystemLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getKakaoAtAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice()));
}
saveSystemLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("KAT");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
} else {
saveSystemLog("worker is null");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvKftDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException {
try {
ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH);
channel.read(bodyBuffer);
ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH);
Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer);
BasicMessageDto messageDto = recvCommonMessage(deliverBuffer);
messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer));
messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer));
messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer));
messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer));
String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile";
jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo();
FileUtil.mkdirs(jsonPath);
ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH);
channel.read(fileHeadBuffer);
String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer);
String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer);
ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize));
channel.read(fileBuffer);
fileBuffer.flip();
JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer);
messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName);
saveSystemLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]");
/* 사용자 단가, 발송망 설정 */
MemberDto savedMemberDto = null;
if (this.connectUserDto != null) {
savedMemberDto = this.connectUserDto.getMemberDto();
}
if (savedMemberDto != null) {
messageDto.setRouterSeq(savedMemberDto.getKakaoFtAgentCode());
messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice()));
}
saveSystemLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]");
QueueTypeWorker worker = QueueTypeWorker.find("KFT");
if (worker != null) {
worker.pushQueue(messageDto);
channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void recvLinkCheck(SocketChannel channel) throws IOException {
ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH);
channel.read(bodyBuffer);
// SocketChannel channel = (SocketChannel) key.channel();
channel.write(LinkCheck.makeLinkCheckAckBuffer());
/* 서비스 중지여부 체크 */
if (isExpireService()) {
expireConnectUser();
return;
}
}
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("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]");
/* Bind Check */
resultCode = checkBind(memberDto, this.serviceType, id, pwd);
/* 접속 IP 체크 */
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());
if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) {
isPermit = true;
}
if (memberDto.getAllowIpExtend() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) {
isPermit = true;
}
} else {
isPermit = true;
}
if (isPermit) {
resultCode = "00";
} else {
resultCode = "40";
}
}
if ("00".equals(resultCode)) {
connectUserDto.setUserId(id);
connectUserDto.setLogin(true);
connectUserDto.setMemberDto(memberDto);
/* 사용자 Pool에 저장 */
collectUserQueue.putUser(this.serviceType, connectUserDto);
/* 세션통신 시간 업데이트 */
connectUserDto.updateLastTrafficTime();
}
} catch (Exception e) {
resultCode = "10";
e.printStackTrace();
}
try {
saveSystemLog("[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 serviceType, String id, String pwd) {
if (id == null || pwd == null) {
return "50";
}
if (collectUserQueue.isExist(this.serviceType, id)) {
return "60";
}
if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
return "20";
}
/* 회원 사용 상태 */
if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
return "30";
}
/* 서비스 이용 상태 */
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return "30";
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return "30";
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return "30";
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return "30";
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return "30";
}
return "00";
}
private String checkService(MemberDto memberDto, String serviceType) {
if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) {
return "30";
}
if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) {
return "30";
}
if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) {
return "30";
}
if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) {
return "30";
}
if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) {
return "30";
}
return "00";
}
private void expireConnectUser() {
if (key == null || !key.isValid()) {
return;
}
try {
SocketChannel channel = (SocketChannel) key.channel();
if (connectUserDto != null) {
if (connectUserDto.getUserId() != null) {
collectUserQueue.removeUser(connectUserDto.getServiceType(), connectUserDto.getUserId());
}
key.attach(null);
}
// 소켓 채널 닫기
channel.close();
// 닫기
key.cancel();
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveSystemLog(Object obj) {
saveLog(obj, true);
}
private void saveLog(Object obj) {
saveLog(obj, false);
}
private void saveLog(Object obj, boolean isConsoleOutput) {
if (isConsoleOutput) {
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj);
}
if (logger == null) {
return;
}
logger.log(obj);
}
}

View File

@ -0,0 +1,76 @@
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.server.dto.ConnectUserDto;
import com.munjaon.server.server.queue.CollectUserQueue;
import com.munjaon.server.util.LogUtil;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
public class StatusCheckTask implements Runnable {
public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]");
public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]";
private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance();
private String serviceType;
private final LogUtil logger;
public StatusCheckTask(String serviceType, LogUtil logger) {
this.serviceType = serviceType;
this.logger = logger;
}
@Override
public void run() {
saveSystemLog("[" + this.serviceType + "][USER STATUS CHECK is starting ... ...]");
List<ConnectUserDto> userList = collectUserQueue.getUsers(this.serviceType);
if (userList == null && userList.isEmpty()) {
saveSystemLog("[" + this.serviceType + "][USER STATUS CHECK is empty ... ...]");
saveSystemLog("[" + this.serviceType + "][USER STATUS CHECK is ended ... ...]");
return;
}
MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService();
for (ConnectUserDto user : userList) {
MemberDto savedMemberDto = user.getMemberDto();
saveSystemLog("[" + this.serviceType + "][USER PREVIOUS STATUS : " + savedMemberDto.toString() + "]");
if (savedMemberDto == null) {
continue;
}
MemberDto newMemberDto = svc.get(savedMemberDto.getMberId());
saveSystemLog("[" + this.serviceType + "][USER NEW STATUS : " + newMemberDto.toString() + "]");
if (newMemberDto == null) {
savedMemberDto.setMberSttus("N");
} else {
user.setMemberDto(newMemberDto);
}
saveSystemLog("[" + this.serviceType + "][USER AFTER STATUS : " + savedMemberDto.toString() + "]");
}
saveSystemLog("[" + this.serviceType + "][USER STATUS CHECK is ended ... ...]");
}
private void saveSystemLog(Object obj) {
saveLog(obj, true);
}
private void saveLog(Object obj) {
saveLog(obj, false);
}
private void saveLog(Object obj, boolean isConsoleOutput) {
if (isConsoleOutput) {
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{StatusCheckTask}} " + obj);
}
if (logger == null) {
return;
}
logger.log(obj);
}
}

View File

@ -501,4 +501,16 @@ public final class MessageUtil {
return reportDto; return reportDto;
} }
public static String makeMessageKey(String msgId) {
if (msgId == null || msgId.trim().isEmpty() || msgId.trim().length() > 14) {
return "MSGID_" + SerialNoUtil.getSerialNo();
}
String lpad = "";
for (int i = 0, size = 14 - msgId.trim().length(); i < size; i++) {
lpad += "0";
}
return "MSGID_" + lpad + msgId.trim();
}
} }

View File

@ -4,6 +4,10 @@ spring:
profiles: profiles:
default: local default: local
logging:
level:
root: info
mybatis: mybatis:
configuration: configuration:
map-underscore-to-camel-case: true map-underscore-to-camel-case: true

View File

@ -2,7 +2,9 @@ spring:
datasource: datasource:
server: server:
driver-class-name: org.mariadb.jdbc.Driver driver-class-name: org.mariadb.jdbc.Driver
jdbc-url: jdbc:mariadb://119.193.215.98:3306/mjon_agent_back url: jdbc:mariadb://192.168.0.125:3306/mjon_agent_back
jdbc-url: jdbc:mariadb://192.168.0.125:3306/mjon_agent_back
# jdbc-url: jdbc:mariadb://119.193.215.98:3306/mjon_agent_back
username: mjonUr_agent username: mjonUr_agent
password: mjagent123$ password: mjagent123$

View File

@ -10,7 +10,7 @@
<pattern>${LOG_PATTERN}</pattern> <pattern>${LOG_PATTERN}</pattern>
</encoder> </encoder>
</appender> </appender>
<logger name="com.munjaon.server" level="DEBUG" /> <logger name="com.munjaon.server" level="INFO" />
<root level="ERROR"> <root level="ERROR">
<appender-ref ref="CONSOLE"/> <appender-ref ref="CONSOLE"/>
</root> </root>

View File

@ -2,6 +2,7 @@ spring:
datasource: datasource:
server: server:
driver-class-name: org.mariadb.jdbc.Driver driver-class-name: org.mariadb.jdbc.Driver
url: jdbc:mariadb://119.193.215.98:3306/mjon_agent
jdbc-url: jdbc:mariadb://119.193.215.98:3306/mjon_agent jdbc-url: jdbc:mariadb://119.193.215.98:3306/mjon_agent
username: mjonUr_agent username: mjonUr_agent
password: mjagent123$ password: mjagent123$

View File

@ -21,6 +21,22 @@
, BIZ_KAKAO_RESEND_DATA , BIZ_KAKAO_RESEND_DATA
, BIZ_KAKAO_RESEND_TYPE , BIZ_KAKAO_RESEND_TYPE
, BIZ_KAKAO_JSON_FILE , BIZ_KAKAO_JSON_FILE
) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, #{kakaoSenderKey}, #{kakaoTemplateCode}, NOW(), #{userReceiver}, #{userSender}, #{userMessage}, #{userSubject}, '8', 'N', null, null, #{kakaoJsonFile}) ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, #{kakaoSenderKey}, #{kakaoTemplateCode}, NOW(), #{userReceiver}, #{userSender}, #{userMessage}, #{userSubject}, '8', 'N', null, null, #{kakaoJsonFile})
</insert>
<insert id="insertForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, MSG_NOTICETALK_SENDER_KEY, MSG_NOTICETALK_TMP_KEY, REQ_DATE, CALL_TO, CALL_FROM, SMS_TXT, BIZ_KAKAO_TITLE, MSG_TYPE, BIZ_KAKAO_RESEND_YN, BIZ_KAKAO_RESEND_DATA, BIZ_KAKAO_RESEND_TYPE, BIZ_KAKAO_JSON_FILE)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, #{item.kakaoSenderKey}, #{item.kakaoTemplateCode}, NOW(), #{item.userReceiver}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, '8', 'N', null, null, #{item.kakaoJsonFile})
</foreach>
</insert>
<insert id="insertGroupForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, NOW(), '1', NULL, '8', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, '0', '0.0', NULL, NULL, 'Y', '' )
</foreach>
</insert> </insert>
</mapper> </mapper>

View File

@ -20,6 +20,22 @@
, BIZ_KAKAO_RESEND_DATA , BIZ_KAKAO_RESEND_DATA
, BIZ_KAKAO_RESEND_TYPE , BIZ_KAKAO_RESEND_TYPE
, BIZ_KAKAO_JSON_FILE , BIZ_KAKAO_JSON_FILE
) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, #{kakaoSenderKey}, #{kakaoTemplateCode}, NOW(), #{userReceiver}, #{userSender}, #{userMessage}, #{userSubject}, '9', 'N', null, null, #{kakaoJsonFile}) ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, #{kakaoSenderKey}, #{kakaoTemplateCode}, NOW(), #{userReceiver}, #{userSender}, #{userMessage}, #{userSubject}, '9', 'N', null, null, #{kakaoJsonFile})
</insert>
<insert id="insertForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, MSG_NOTICETALK_SENDER_KEY, MSG_NOTICETALK_TMP_KEY, REQ_DATE, CALL_TO, CALL_FROM, SMS_TXT, BIZ_KAKAO_TITLE, MSG_TYPE, BIZ_KAKAO_RESEND_YN, BIZ_KAKAO_RESEND_DATA, BIZ_KAKAO_RESEND_TYPE, BIZ_KAKAO_JSON_FILE)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, #{item.kakaoSenderKey}, #{item.kakaoTemplateCode}, NOW(), #{item.userReceiver}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, '8', 'N', null, null, #{item.kakaoJsonFile})
</foreach>
</insert>
<insert id="insertGroupForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, NOW(), '1', NULL, '9', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, '0', '0.0', NULL, NULL, 'Y', '' )
</foreach>
</insert> </insert>
</mapper> </mapper>

View File

@ -16,6 +16,22 @@
, SMS_TXT , SMS_TXT
, MSG_TYPE , MSG_TYPE
, CONT_SEQ, FILE_CNT , CONT_SEQ, FILE_CNT
) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, NOW(), #{userReceiver}, #{userSender}, #{userSubject}, #{userMessage}, '6', null, '0' ) ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, NOW(), #{userReceiver}, #{userSender}, #{userSubject}, #{userMessage}, '6', null, '0' )
</insert>
<insert id="insertForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, REQ_DATE, CALL_TO, CALL_FROM, SUBJECT, SMS_TXT, MSG_TYPE, CONT_SEQ, FILE_CNT)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, NOW(), #{item.userReceiver}, #{item.userSender}, #{item.userSubject}, #{item.userMessage}, '6', null, '0' )
</foreach>
</insert>
<insert id="insertGroupForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, NOW(), '1', NULL, '6', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, '0', '0.0', NULL, NULL, 'N', '' )
</foreach>
</insert> </insert>
</mapper> </mapper>

View File

@ -21,6 +21,22 @@
, FILE_PATH2 , FILE_PATH2
, FILE_PATH3 , FILE_PATH3
, NEO_TYPE , NEO_TYPE
) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, NOW(), #{userReceiver}, #{userSender}, #{userSubject}, #{userMessage}, '6', null, #{userFileCnt}, #{userFileName01}, #{userFileName02}, #{userFileName03}, null) ) VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, NOW(), #{userReceiver}, #{userSender}, #{userSubject}, #{userMessage}, '6', null, #{userFileCnt}, #{userFileName01}, #{userFileName02}, #{userFileName03}, null)
</insert>
<insert id="insertForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, REQ_DATE, CALL_TO, CALL_FROM, SUBJECT, SMS_TXT, MSG_TYPE, CONT_SEQ, FILE_CNT, FILE_PATH1, FILE_PATH2, FILE_PATH3, NEO_TYPE)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, NOW(), #{item.userReceiver}, #{item.userSender}, #{item.userSubject}, #{item.userMessage}, '6', null, #{item.userFileCnt}, #{item.userFileName01}, #{item.userFileName02}, #{item.userFileName03}, null)
</foreach>
</insert>
<insert id="insertGroupForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, #{item.userSubject}, NOW(), '1', NULL, '6', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, #{item.userFileCnt}, '0.0', NULL, NULL, 'N', '' )
</foreach>
</insert> </insert>
</mapper> </mapper>

View File

@ -15,6 +15,22 @@
, SUBJECT , SUBJECT
, SMS_TXT , SMS_TXT
, MSG_TYPE , MSG_TYPE
)VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, '04', 0, NOW(), #{userReceiver}, #{userSender}, NULL, #{userMessage}, '4' ) )VALUES (#{id}, #{msgGroupID}, #{userId}, #{userMsgID}, #{routerSeq}, 0, NOW(), #{userReceiver}, #{userSender}, NULL, #{userMessage}, '4' )
</insert>
<insert id="insertForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_DATA (MSG_ID, MSG_GROUP_ID, USER_ID, AGENT_MSG_ID, AGENT_CODE, CUR_STATE, REQ_DATE, CALL_TO, CALL_FROM, SUBJECT, SMS_TXT, MSG_TYPE)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.id}, #{item.msgGroupID}, #{item.userId}, #{item.userMsgID}, #{item.routerSeq}, 0, NOW(), #{item.userReceiver}, #{item.userSender}, NULL, #{item.userMessage}, '4' )
</foreach>
</insert>
<insert id="insertGroupForList" parameterType="java.util.List">
INSERT INTO MJ_MSG_GROUP_DATA (MSG_GROUP_ID, USER_ID, CALL_FROM, SMS_TXT, SUBJECT, REQ_DATE, MSG_GROUP_CNT, CONECT_MTHD, MSG_TYPE, MSG_KIND, AGENT_CODE, EACH_PRICE, RESERVE_YN, BEF_CASH, BEF_POINT, RECOMM_ID, FILE_CNT, TOT_PRICE, EVENT_YN, DELAY_YN, AT_DELAY_YN, BIZ_KAKAO_RESEND_ORGNL_TXT)
VALUES
<foreach separator="," item="item" collection="list">
(#{item.msgGroupID}, #{item.userId}, #{item.userSender}, #{item.userMessage}, NULL, NOW(), '1', NULL, '4', NULL, #{item.routerSeq}, '0.0', 'N', '0.00', '0', NULL, '0', '0.0', NULL, NULL, 'N', '' )
</foreach>
</insert> </insert>
</mapper> </mapper>