테스트코드, 미사용 코드, 미사용 클래스, 미사용 library 제거
This commit is contained in:
parent
b369522f6b
commit
7d08d942fe
@ -45,8 +45,6 @@ dependencies {
|
||||
implementation 'org.apache.commons:commons-configuration2:2.10.1'
|
||||
// https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils
|
||||
implementation 'commons-beanutils:commons-beanutils:1.9.4'
|
||||
// https://mvnrepository.com/artifact/io.netty/netty-all
|
||||
implementation 'io.netty:netty-all:4.1.42.Final'
|
||||
// https://mvnrepository.com/artifact/org.jdom/jdom2
|
||||
implementation 'org.jdom:jdom2:2.0.6.1'
|
||||
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
package com.munjaon.server.netty.config;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public interface BaseConfig {
|
||||
NioEventLoopGroup bossGroup();
|
||||
NioEventLoopGroup workerGroup();
|
||||
InetSocketAddress port();
|
||||
ServerBootstrap serverBootstrap();
|
||||
ChannelInboundHandlerAdapter handler();
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
package com.munjaon.server.netty.handler;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
|
||||
public class SampleHandler extends SimpleChannelInboundHandler<String> {
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
package com.munjaon.server.netty.init;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
|
||||
public class SampleNettyInitializer extends ChannelInitializer<Channel> {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
package com.munjaon.server.server.sample;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class ExecutorServiceTest3 {
|
||||
public static void main(String args[]) {
|
||||
final int maxCore = Runtime.getRuntime().availableProcessors();
|
||||
System.out.println("maxCore : " + maxCore);
|
||||
final ExecutorService executor = Executors.newFixedThreadPool(maxCore);
|
||||
final List<Future<String>> futures = new ArrayList<>();
|
||||
|
||||
for (int i = 1; i < 5; i++) {
|
||||
final int index = i;
|
||||
futures.add(executor.submit(() -> {
|
||||
System.out.println("finished job" + index);
|
||||
return "job" + index + " " + Thread.currentThread().getName();
|
||||
}));
|
||||
}
|
||||
|
||||
for (Future<String> future : futures) {
|
||||
String result = null;
|
||||
try {
|
||||
result = future.get();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
executor.shutdownNow();
|
||||
System.out.println("end");
|
||||
}
|
||||
}
|
||||
@ -1,63 +0,0 @@
|
||||
package com.munjaon.server.server.sample;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class ExecutorServiceTest4 {
|
||||
public static void main(String args[]) {
|
||||
ParallelExcutorService service = new ParallelExcutorService();
|
||||
service.submit("job1");
|
||||
service.submit("job2");
|
||||
service.submit("job3");
|
||||
service.submit("job4");
|
||||
|
||||
// for (int i = 0 ; i < 4; i++) {
|
||||
// String result = service.take();
|
||||
// System.out.println(result);
|
||||
// }
|
||||
|
||||
System.out.println("end");
|
||||
service.close();
|
||||
}
|
||||
|
||||
private static class ParallelExcutorService {
|
||||
private final int maxCore = Runtime.getRuntime().availableProcessors();
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(maxCore);
|
||||
private final BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
|
||||
|
||||
public ParallelExcutorService() {
|
||||
}
|
||||
|
||||
public void submit(String job) {
|
||||
executor.submit(() -> {
|
||||
// String threadName = Thread.currentThread().getName();
|
||||
System.out.println("finished " + job);
|
||||
// String result = job + ", " + threadName;
|
||||
// try {
|
||||
// queue.put(result);
|
||||
// } catch (InterruptedException e) {
|
||||
// Thread.currentThread().interrupt();
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
public String take() {
|
||||
try {
|
||||
return queue.take();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
List<Runnable> unfinishedTasks = executor.shutdownNow();
|
||||
if (!unfinishedTasks.isEmpty()) {
|
||||
System.out.println("Not all tasks finished before calling close: " + unfinishedTasks.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
package com.munjaon.server.server.sample;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) throws InterruptedException, ExecutionException {
|
||||
ExecutorService e = Executors.newFixedThreadPool(5);
|
||||
// 리턴 값이 필요 없는 경우
|
||||
for (int i = 0; i < 5; i++) {
|
||||
e.execute(new MyRunnable(i * 20));
|
||||
}
|
||||
// 작업을 기다려야 할 경우
|
||||
e.shutdown();
|
||||
|
||||
// 리턴 값이 필요한 경우
|
||||
// List<Future<Integer>> l = new ArrayList<>();
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// Future<Integer> f = e.submit(new MyCallable(i * 20));
|
||||
// l.add(f);
|
||||
// }
|
||||
//
|
||||
// // 작업이 완료 되길 기다려야 할 경우
|
||||
// int n = 0;
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// Future<Integer> f = l.get(i);
|
||||
// n += f.get();
|
||||
// }
|
||||
}
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
package com.munjaon.server.server.sample;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class MyCallable implements Callable {
|
||||
private final int s;
|
||||
|
||||
public MyCallable(int s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
int in = 0;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
System.out.println(s + " : MyCallable");
|
||||
System.out.println(i + s);
|
||||
in += i + s;
|
||||
try {
|
||||
Thread.sleep(1000L);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
package com.munjaon.server.server.sample;
|
||||
|
||||
public class MyRunnable implements Runnable {
|
||||
private final int s;
|
||||
public MyRunnable(int s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println("SendReadTask start : " + Thread.currentThread().getName());
|
||||
for (int i = 0; i < 20; i++) {
|
||||
System.out.println(s + " : MyRunnable : " + Thread.currentThread().getName());
|
||||
System.out.println(i + s);
|
||||
try {
|
||||
Thread.sleep(1000L);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
package com.munjaon.server.server.sample;
|
||||
|
||||
import com.slack.api.Slack;
|
||||
import com.slack.api.methods.MethodsClient;
|
||||
import com.slack.api.methods.SlackApiException;
|
||||
import com.slack.api.methods.request.chat.ChatPostMessageRequest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SlackTest {
|
||||
public static void main(final String[] args) {
|
||||
String token = "xoxb-7591405602163-7594011803524-gKJQfJbhRSmOFr1XFcwujWDr";
|
||||
String channelAddress = "#프로젝트";
|
||||
String message = "test";
|
||||
try{
|
||||
|
||||
MethodsClient methods = Slack.getInstance().methods(token);
|
||||
|
||||
ChatPostMessageRequest request = ChatPostMessageRequest.builder()
|
||||
.channel(channelAddress)
|
||||
.text(message)
|
||||
.build();
|
||||
|
||||
methods.chatPostMessage(request);
|
||||
|
||||
// log.info("Slack " + channel + " 에 메시지 보냄");
|
||||
} catch (SlackApiException | IOException e) {
|
||||
e.printStackTrace();
|
||||
// log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,404 +0,0 @@
|
||||
package com.munjaon.server.server.service;
|
||||
|
||||
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.dto.HeaderDto;
|
||||
import com.munjaon.server.server.packet.common.*;
|
||||
import com.munjaon.server.util.LogUtil;
|
||||
import lombok.Getter;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class CollectBackServerService extends Service {
|
||||
private final InetSocketAddress listenAddress;
|
||||
private CollectorThreadService threadService;
|
||||
private Selector selector;
|
||||
private final String serviceType;
|
||||
|
||||
public CollectBackServerService(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;
|
||||
} else {
|
||||
this.IS_READY_YN = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initResources() {
|
||||
try {
|
||||
initCollectChannel();
|
||||
threadService = new CollectorThreadService(8, this.serviceType, logger);
|
||||
} catch (IOException e) {
|
||||
saveSystemLog(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initCollectChannel() 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 closeCollectChannel() throws IOException {
|
||||
selector.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseResources() {
|
||||
try {
|
||||
closeCollectChannel();
|
||||
threadService.close();
|
||||
} catch (IOException e) {
|
||||
saveSystemLog(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doService() {
|
||||
while (isRun()) {
|
||||
try {
|
||||
execInterest();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void execInterest() throws IOException {
|
||||
if (selector.select(1000) == 0) {
|
||||
return ;
|
||||
}
|
||||
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
|
||||
while (keys.hasNext()) {
|
||||
SelectionKey key = keys.next();
|
||||
if (key.isValid()) {
|
||||
if (key.isAcceptable()) { // 접속일 경우..
|
||||
saveSystemLog("isAcceptable");
|
||||
threadService.submit(selector, key, 1);
|
||||
} else if (key.isReadable()) { // 수신일 경우..
|
||||
saveSystemLog("isReadable");
|
||||
threadService.submit(selector, key, 2);
|
||||
} else if (key.isWritable()) { // 발신일 경우..
|
||||
saveSystemLog("isWritable");
|
||||
threadService.submit(selector, key, 3);
|
||||
}
|
||||
}
|
||||
/* 키 셋에서 제거. */
|
||||
keys.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject monitorService() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class CollectorThreadService {
|
||||
@Getter
|
||||
private String serviceType;
|
||||
@Getter
|
||||
private final int maxCore;
|
||||
private final ExecutorService executor;
|
||||
private final Map<String, ConnectUserDto> connectUserMap = new ConcurrentHashMap<>();
|
||||
private final LogUtil logger;
|
||||
|
||||
public CollectorThreadService(String serviceType, LogUtil logger) {
|
||||
this(Runtime.getRuntime().availableProcessors(), serviceType, logger);
|
||||
}
|
||||
|
||||
public CollectorThreadService(int maxCore, String serviceType, LogUtil logger) {
|
||||
this.maxCore = maxCore;
|
||||
this.executor = Executors.newFixedThreadPool(maxCore);
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public void submit(Selector selector, SelectionKey key, int interestOps) {
|
||||
executor.submit(() -> {
|
||||
switch (interestOps) {
|
||||
case 1 : accept(selector, key); break;
|
||||
case 2 : read(selector, key); break;
|
||||
case 3 : write(selector, key); break;
|
||||
default : break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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("accept : " + Thread.currentThread().getName());
|
||||
saveSystemLog("Connected to: " + remoteAddr);
|
||||
// Socket 채널을 channel에 수신 등록한다
|
||||
channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).build());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// private void read(Selector selector, SelectionKey key) {
|
||||
// try {
|
||||
// saveSystemLog("read : " + Thread.currentThread().getName());
|
||||
// // 키 채널을 가져온다.
|
||||
// SocketChannel channel = (SocketChannel) key.channel();
|
||||
// ConnectUserDto userDto = (ConnectUserDto) key.attachment();
|
||||
//
|
||||
// int size = -1;
|
||||
//
|
||||
// ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH);
|
||||
// ByteBuffer bindBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH);
|
||||
// ByteBuffer linkBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_BODY_LENGTH);
|
||||
// ByteBuffer msgBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH);
|
||||
// try {
|
||||
// size = channel.read(headBuffer);
|
||||
// String command = Header.getCommand(headBuffer);
|
||||
// System.out.println("command : " + command);
|
||||
// if ("1".equals(command)) {
|
||||
// size = channel.read(bindBuffer);
|
||||
// } else if ("3".equals(command)) {
|
||||
// size = channel.read(msgBuffer);
|
||||
// } else if ("7".equals(command)) {
|
||||
// size = channel.read(linkBuffer);
|
||||
// } else {
|
||||
// size = -1;
|
||||
// }
|
||||
//
|
||||
// System.out.println("size : " + size);
|
||||
// } catch (IOException e) {}
|
||||
// if (size < 0) {
|
||||
// expireConnectUser(key);
|
||||
// } else if (size > 0) {
|
||||
//// String command = Header.getCommand(buffer);
|
||||
//// saveSystemLog("command : " + command);
|
||||
//// switch (Integer.parseInt(command)) {
|
||||
//// case 1 : recvBind(channel, buffer, userDto); break;
|
||||
//// case 3 : recvDeliver(channel, buffer, userDto); break;
|
||||
//// case 7 : recvLinkCheck(key); break;
|
||||
//// default: expireConnectUser(key); break;
|
||||
//// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// System.out.println("read");
|
||||
// }
|
||||
|
||||
private void read(Selector selector, SelectionKey key) {
|
||||
try {
|
||||
saveSystemLog("read : " + Thread.currentThread().getName());
|
||||
// 키 채널을 가져온다.
|
||||
SocketChannel channel = (SocketChannel) key.channel();
|
||||
ConnectUserDto userDto = (ConnectUserDto) key.attachment();
|
||||
|
||||
int size = -1;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(256);
|
||||
try {
|
||||
size = channel.read(buffer);
|
||||
} catch (IOException e) {}
|
||||
if (size < 0) {
|
||||
expireConnectUser(key);
|
||||
} else if (size > 0) {
|
||||
String command = Header.getCommand(buffer);
|
||||
saveSystemLog("command : " + command);
|
||||
switch (Integer.parseInt(command)) {
|
||||
case 1 : recvBind(channel, buffer, userDto); break;
|
||||
case 3 : recvDeliver(channel, buffer, userDto); break;
|
||||
case 7 : recvLinkCheck(key); break;
|
||||
default: expireConnectUser(key); break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("read");
|
||||
}
|
||||
|
||||
private void recvBind(SocketChannel channel, ByteBuffer buffer, ConnectUserDto userDto) {
|
||||
String resultCode = "00";
|
||||
try {
|
||||
String id = Bind.getBindId(buffer);
|
||||
String pwd = Bind.getBindPwd(buffer);
|
||||
saveSystemLog("id : " + id);
|
||||
saveSystemLog("pwd : " + pwd);
|
||||
if (id == null || pwd == null) {
|
||||
resultCode = "50";
|
||||
} else {
|
||||
if (connectUserMap.containsKey(id)) {
|
||||
resultCode = "60";
|
||||
} else {
|
||||
MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService();
|
||||
MemberDto memberDto = null;
|
||||
if (svc != null) {
|
||||
memberDto = svc.get(id);
|
||||
}
|
||||
if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
|
||||
resultCode = "20";
|
||||
} else {
|
||||
userDto.setUserId(id);
|
||||
userDto.setLogin(true);
|
||||
userDto.setMemberDto(memberDto);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
resultCode = "10";
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
saveSystemLog("resultCode : " + resultCode);
|
||||
channel.write(Bind.makeBindAckBuffer(resultCode));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void recvDeliver(SocketChannel channel, ByteBuffer buffer, ConnectUserDto userDto) throws Exception {
|
||||
BasicMessageDto messageDto = new BasicMessageDto();
|
||||
messageDto.setRouterSeq("40");
|
||||
messageDto.setServiceType("4");
|
||||
messageDto.setUserId(userDto.getUserId());
|
||||
messageDto.setRemoteIP(userDto.getRemoteIP());
|
||||
messageDto.setSendStatus("0");
|
||||
messageDto.setUserMsgID(CommonMessage.getMessageIdForDeliver(buffer));
|
||||
messageDto.setUserSender(CommonMessage.getSenderForDeliver(buffer));
|
||||
messageDto.setUserReceiver(CommonMessage.getReceiverForDeliver(buffer));
|
||||
messageDto.setReserveDt(CommonMessage.getReserveTimeForDeliver(buffer));
|
||||
messageDto.setRequestDt(CommonMessage.getRequestTimeForDeliver(buffer));
|
||||
messageDto.setUnitCost("10.4");
|
||||
messageDto.setUserMessage(SmsMessage.getMessageForDeliver(buffer));
|
||||
|
||||
QueueTypeWorker worker = QueueTypeWorker.find("SMS");
|
||||
if (worker != null) {
|
||||
worker.pushQueue(messageDto);
|
||||
channel.write(SmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus()));
|
||||
}
|
||||
}
|
||||
private void recvLinkCheck(SelectionKey key) throws IOException {
|
||||
SocketChannel channel = (SocketChannel) key.channel();
|
||||
channel.write(LinkCheck.makeLinkCheckAckBuffer());
|
||||
}
|
||||
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) {
|
||||
connectUserMap.remove(userDto.getUserId());
|
||||
key.attach(null);
|
||||
}
|
||||
// 소켓 채널 닫기
|
||||
channel.close();
|
||||
// 키 닫기
|
||||
key.cancel();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private HeaderDto getHeader(SocketChannel channel) throws UnsupportedEncodingException {
|
||||
HeaderDto headerDto = HeaderDto.builder().build();
|
||||
int size = -1;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(Header.HEADER_LENGTH);
|
||||
if (channel != null) {
|
||||
try {
|
||||
saveSystemLog("Key is valid : ");
|
||||
// SocketChannel channel = (SocketChannel) key.channel();
|
||||
size = channel.read(buffer);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
if (size < 0) {
|
||||
saveSystemLog("Is Error : ");
|
||||
headerDto.setError(true);
|
||||
} else {
|
||||
saveSystemLog("version : " + Header.getVersion(buffer));
|
||||
saveSystemLog("Command : " + Header.getCommand(buffer));
|
||||
saveSystemLog("BodyLength : " + Header.getBodyLength(buffer));
|
||||
headerDto.setVersion(Header.getVersion(buffer));
|
||||
headerDto.setCommand(Integer.parseInt(Header.getCommand(buffer)));
|
||||
headerDto.setBodyLength(Integer.parseInt(Header.getBodyLength(buffer)));
|
||||
}
|
||||
|
||||
saveSystemLog("READ HEADER : " + size);
|
||||
|
||||
return headerDto;
|
||||
}
|
||||
|
||||
private void write(Selector selector, SelectionKey key) {
|
||||
System.out.println("write");
|
||||
}
|
||||
|
||||
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();
|
||||
connectUserMap.clear();
|
||||
if (!unfinishedTasks.isEmpty()) {
|
||||
saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,342 +0,0 @@
|
||||
package com.munjaon.server.server.service;
|
||||
|
||||
import com.munjaon.server.queue.enums.QueueTypeWorker;
|
||||
import com.munjaon.server.server.dto.ConnectUserDto;
|
||||
import com.munjaon.server.server.queue.CollectUserQueue;
|
||||
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 lombok.Getter;
|
||||
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.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class CollectServerService extends Service {
|
||||
private final InetSocketAddress listenAddress;
|
||||
private CollectThreadService threadService;
|
||||
private StatusThreadService statusThreadService;
|
||||
private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance();
|
||||
|
||||
private Selector selector;
|
||||
private final String serviceType;
|
||||
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) {
|
||||
super(serviceName);
|
||||
this.readMaxCore = Integer.parseInt(getProp("READ_MAX_CORE").trim());
|
||||
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();
|
||||
threadService = new CollectThreadService(readMaxCore, this.serviceType, logger);
|
||||
statusThreadService = new StatusThreadService(this.serviceType, this.logger);
|
||||
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();
|
||||
threadService.close();
|
||||
statusThreadService.close();
|
||||
} 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_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 {
|
||||
if (selector.select(1000) == 0) {
|
||||
return ;
|
||||
}
|
||||
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
|
||||
List<Future<ConnectUserDto>> 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()) { // 수신일 경우..
|
||||
Future<ConnectUserDto> future = threadService.submit(new CollectReadTask(selector, key, this.serviceType, logger));
|
||||
list.add(future);
|
||||
// threadService.submit(selector, key, 2);
|
||||
}
|
||||
} else {
|
||||
expireConnectUser(key);
|
||||
}
|
||||
}
|
||||
for (Future<ConnectUserDto> future : list) {
|
||||
ConnectUserDto connectUserDto = null;
|
||||
try {
|
||||
connectUserDto = future.get();
|
||||
} catch (InterruptedException e) {
|
||||
} catch (ExecutionException e) {
|
||||
}
|
||||
|
||||
if (connectUserDto != null) {
|
||||
saveSystemLog("[READ USER : " + 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
private static class StatusThreadService {
|
||||
@Getter
|
||||
private String serviceType;
|
||||
@Getter
|
||||
private final int maxCore = 1;
|
||||
private final ExecutorService executor;
|
||||
private final LogUtil logger;
|
||||
|
||||
public StatusThreadService(String serviceType, LogUtil logger) {
|
||||
this.executor = Executors.newFixedThreadPool(maxCore);
|
||||
this.logger = logger;
|
||||
saveSystemLog("[STATUS_TASK_THREAD_POOL : " + maxCore + "]");
|
||||
}
|
||||
|
||||
public void execute(StatusCheckTask statusCheckTask) {
|
||||
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) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,6 @@ import com.munjaon.server.server.queue.ReportUserQueue;
|
||||
import com.munjaon.server.server.task.ReportBindTask;
|
||||
import com.munjaon.server.server.task.ReportLinkCheckTask;
|
||||
import com.munjaon.server.server.task.ReportResultTask;
|
||||
import com.munjaon.server.server.task.ReportServerTask;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -17,10 +16,7 @@ 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;
|
||||
@ -135,44 +131,6 @@ public class ReportServer extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkInterest_bak() 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;
|
||||
}
|
||||
if (reportUserDto.isAlive() == 1) { // 로그인이 완료되지 않은 경우
|
||||
expireConnectUser(key);
|
||||
} else if (reportUserDto.isAlive() == 2) {
|
||||
if (reportUserDto.isRunningMode()) {
|
||||
continue;
|
||||
}
|
||||
/* 로그인이 된경우 Link Check를 위해 실행 */
|
||||
if (reportUserDto.isLogin()) {
|
||||
reportUserDto.setRunningMode(true);
|
||||
/* 사용자별 Report Thread 실행 */
|
||||
new ReportServerTask(selector, key, getName(), logger).run();
|
||||
}
|
||||
} else {
|
||||
ReportQueue reportQueue = reportUserDto.getReportQueue();
|
||||
if (reportUserDto.isLogin() && reportQueue != null && reportQueue.isRemainReport()) {
|
||||
if (reportUserDto.isRunningMode()) {
|
||||
continue;
|
||||
}
|
||||
reportUserDto.setRunningMode(true);
|
||||
/* 사용자별 Report Thread 실행 */
|
||||
new ReportServerTask(selector, key, getName(), logger).start();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
expireConnectUser(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bindInterest() throws IOException {
|
||||
if (selector.select(300) == 0) {
|
||||
return ;
|
||||
@ -206,35 +164,6 @@ public class ReportServer extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
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()) { // 접속일 경우..
|
||||
saveLog("CONNECTION IS ACCEPTABLE ... ...");
|
||||
accept(selector, key);
|
||||
} else if (key.isReadable()) { // 수신일 경우..
|
||||
ReportUserDto reportUserDto = (ReportUserDto) key.attachment();
|
||||
if (reportUserDto == null || reportUserDto.isRunningMode()) {
|
||||
continue;
|
||||
}
|
||||
reportUserDto.setRunningMode(true);
|
||||
/* 사용자별 Report Thread 실행 */
|
||||
new ReportServerTask(selector, key, getName(), logger).start();
|
||||
}
|
||||
} else {
|
||||
expireConnectUser(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void accept(Selector selector, SelectionKey key) {
|
||||
try {
|
||||
/* 키 채널을 가져온다. */
|
||||
@ -264,7 +193,6 @@ public class ReportServer extends Service {
|
||||
saveLog("Expire connect user: " + userDto);
|
||||
if (userDto != null && userDto.getUserId() != null) {
|
||||
reportUserQueue.removeUser(userDto.getUserId());
|
||||
// connectUserMap.remove(userDto.getUserId());
|
||||
key.attach(null);
|
||||
/* 모니터링 로그 */
|
||||
HealthCheckServer.saveMonitorLog("[REPORT SERVER][ID : " + userDto.getUserId() + "][EXPIRE CONNECT USER]");
|
||||
|
||||
@ -1,296 +0,0 @@
|
||||
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.ReportDto;
|
||||
import com.munjaon.server.server.dto.ReportUserDto;
|
||||
import com.munjaon.server.server.packet.common.Header;
|
||||
import com.munjaon.server.server.packet.common.LinkCheck;
|
||||
import com.munjaon.server.server.packet.common.Packet;
|
||||
import com.munjaon.server.server.packet.common.Report;
|
||||
import com.munjaon.server.server.queue.ReportUserQueue;
|
||||
import com.munjaon.server.server.task.ReportReadTask;
|
||||
import com.munjaon.server.util.LogUtil;
|
||||
import lombok.Getter;
|
||||
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.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class ReportServerService extends Service {
|
||||
private final InetSocketAddress listenAddress;
|
||||
private ReadThreadService threadService;
|
||||
private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance();
|
||||
private Selector selector;
|
||||
private int readMaxCore;
|
||||
private int queueMaxCore;
|
||||
// private long CHECKED_INTEREST_TIME = System.currentTimeMillis();
|
||||
// private final long LIMIT_CYCLE_TIME = 3000;
|
||||
|
||||
// private final ByteBuffer reportBuffer = ByteBuffer.allocateDirect(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH);
|
||||
|
||||
public ReportServerService(String serviceName, int port) {
|
||||
super(serviceName);
|
||||
this.readMaxCore = Integer.parseInt(getProp("READ_MAX_CORE").trim());
|
||||
this.queueMaxCore = Integer.parseInt(getProp("QUEUE_MAX_CORE").trim());
|
||||
this.listenAddress = new InetSocketAddress(port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkReady() {
|
||||
this.IS_READY_YN = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initResources() {
|
||||
try {
|
||||
initReportChannel();
|
||||
threadService = new ReadThreadService(readMaxCore, logger);
|
||||
} 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();
|
||||
threadService.close();
|
||||
} 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 {
|
||||
// if (System.currentTimeMillis() - CHECKED_INTEREST_TIME < LIMIT_CYCLE_TIME) {
|
||||
// return;
|
||||
// }
|
||||
// /* 체크시간 업데이트 */
|
||||
// CHECKED_INTEREST_TIME = System.currentTimeMillis();
|
||||
|
||||
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) {
|
||||
if (reportUserDto.getUserId() != null) {
|
||||
reportUserQueue.removeUser(reportUserDto.getUserId());
|
||||
}
|
||||
Socket socket = channel.socket(); // 소켓 취득
|
||||
channel.close(); // 소켓 채널 닫기
|
||||
socket.close(); // 소켓 닫기
|
||||
key.attach(null); // 키 닫기
|
||||
key.cancel();
|
||||
} else if (reportUserDto.isAlive() == 2) {
|
||||
channel.write(LinkCheck.makeLinkCheckBuffer());
|
||||
} else {
|
||||
if (reportUserDto.isLogin()) {
|
||||
ReportQueue reportQueue = reportUserDto.getReportQueue();
|
||||
try {
|
||||
ReportDto reportDto = reportQueue.popReportFromQueue();
|
||||
if (reportDto == null) {
|
||||
continue;
|
||||
}
|
||||
saveSystemLog("reportQueue.popReportFromQueue() : " + 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);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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("isAcceptable");
|
||||
accept(selector, key);
|
||||
} else if (key.isReadable()) { // 수신일 경우..
|
||||
saveSystemLog("isReadable");
|
||||
Future<ReportUserDto> future = threadService.submit(new ReportReadTask(selector, key, logger));
|
||||
list.add(future);
|
||||
// threadService.submit(selector, key, 2);
|
||||
}
|
||||
} else {
|
||||
expireConnectUser(key);
|
||||
}
|
||||
}
|
||||
for (Future<ReportUserDto> future : list) {
|
||||
ReportUserDto reportUserDto = null;
|
||||
try {
|
||||
reportUserDto = future.get();
|
||||
} catch (InterruptedException e) {
|
||||
} catch (ExecutionException e) {
|
||||
}
|
||||
|
||||
if (reportUserDto == null) {
|
||||
saveSystemLog("Future : " + future);
|
||||
} else {
|
||||
saveSystemLog("Future : " + reportUserDto.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private static class ReadThreadService {
|
||||
@Getter
|
||||
private final int maxCore;
|
||||
private final ExecutorService executor;
|
||||
private ReportUserQueue reportUserQueue = ReportUserQueue.getInstance();
|
||||
private final LogUtil logger;
|
||||
|
||||
public ReadThreadService(LogUtil logger) {
|
||||
this(Runtime.getRuntime().availableProcessors(), logger);
|
||||
}
|
||||
|
||||
public ReadThreadService(int maxCore, LogUtil logger) {
|
||||
this.maxCore = maxCore;
|
||||
this.executor = Executors.newFixedThreadPool(maxCore);
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public Future<ReportUserDto> submit(ReportReadTask reportReadTask) {
|
||||
return executor.submit(reportReadTask);
|
||||
}
|
||||
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)) + " {{ReporterThreadService}} " + 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,117 +0,0 @@
|
||||
package com.munjaon.server.server.service;
|
||||
|
||||
import com.munjaon.server.server.config.ServerConfig;
|
||||
import com.munjaon.server.server.dto.ConnectUserDto;
|
||||
|
||||
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.Iterator;
|
||||
|
||||
public abstract class Server {
|
||||
private InetSocketAddress listenAddress;
|
||||
private Selector selector;
|
||||
/* 마지막 통신 시간 */
|
||||
private Long lastTrafficCheckTime = System.currentTimeMillis();
|
||||
|
||||
private Server(InetSocketAddress listenAddress) {
|
||||
this.listenAddress = listenAddress;
|
||||
}
|
||||
|
||||
protected Server(String address, int port) throws IOException {
|
||||
this(new InetSocketAddress(address, port));
|
||||
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);
|
||||
}
|
||||
|
||||
protected Iterator<SelectionKey> selectInterest() throws IOException {
|
||||
if (selector.select(1000) == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return selector.selectedKeys().iterator();
|
||||
}
|
||||
|
||||
protected void execInterest(Iterator<SelectionKey> keys) throws IOException {
|
||||
while (keys != null && keys.hasNext()) {
|
||||
SelectionKey key = keys.next();
|
||||
/* 키 셋에서 제거. */
|
||||
keys.remove();
|
||||
if (!key.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key.isAcceptable()) { // 접속일 경우..
|
||||
this.accept(selector, key);
|
||||
} else if (key.isReadable()) { // 수신일 경우..
|
||||
this.receive(selector, key);
|
||||
} else if (key.isWritable()) { // 발신일 경우..
|
||||
this.send(selector, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void accept(Selector selector, SelectionKey key) throws IOException {
|
||||
/* 키 채널을 가져온다. */
|
||||
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
|
||||
/* accept을 해서 Socket 채널을 가져온다. */
|
||||
SocketChannel channel = serverChannel.accept();
|
||||
channel.configureBlocking(false);
|
||||
/* 소켓 취득 */
|
||||
Socket socket = channel.socket();
|
||||
SocketAddress remoteAddr = socket.getRemoteSocketAddress();
|
||||
System.out.println("Connected to: " + remoteAddr);
|
||||
// Socket 채널을 channel에 수신 등록한다
|
||||
channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).build());
|
||||
}
|
||||
|
||||
protected void checkInterest() throws IOException {
|
||||
if (lastTrafficCheckTime - System.currentTimeMillis() < ServerConfig.CYCLE_SOCKET_TIMEOUT) {
|
||||
return;
|
||||
}
|
||||
Iterator<SelectionKey> keys = selector.keys().iterator();
|
||||
while (keys.hasNext()) {
|
||||
SelectionKey key = keys.next();
|
||||
if (key.interestOps() == SelectionKey.OP_READ) {
|
||||
ConnectUserDto userDto = (ConnectUserDto) key.attachment();
|
||||
|
||||
if (userDto != null) {
|
||||
if (userDto.isAlive() != 0) {
|
||||
System.out.println("userDto is disconnet");
|
||||
// 키 채널을 가져온다.
|
||||
SocketChannel channel = (SocketChannel) key.channel();
|
||||
// 소켓 취득
|
||||
Socket socket = channel.socket();
|
||||
// 소켓 채널 닫기
|
||||
channel.close();
|
||||
// 소켓 닫기
|
||||
socket.close();
|
||||
// 키 닫기
|
||||
key.attach(null);
|
||||
key.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lastTrafficCheckTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
protected void releaseServer() throws IOException {
|
||||
selector.close();
|
||||
}
|
||||
|
||||
protected abstract void receive(Selector selector, SelectionKey key) throws IOException;
|
||||
protected abstract void send(Selector selector, SelectionKey key) throws IOException;
|
||||
}
|
||||
@ -1,572 +0,0 @@
|
||||
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.common.*;
|
||||
import com.munjaon.server.server.queue.CollectUserQueue;
|
||||
import com.munjaon.server.util.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
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;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class CollectReadTask implements Callable<ConnectUserDto> {
|
||||
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 CollectReadTask(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 ConnectUserDto call() throws Exception {
|
||||
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();
|
||||
}
|
||||
|
||||
/* 읽은 데이터가 없는 경우 command -1 */
|
||||
if (size <= 0) {
|
||||
connectUserDto.setCommand(-1);
|
||||
}
|
||||
|
||||
return connectUserDto;
|
||||
}
|
||||
|
||||
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) throws UnsupportedEncodingException {
|
||||
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()));
|
||||
}
|
||||
} 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()));
|
||||
}
|
||||
|
||||
saveLog("[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);
|
||||
}
|
||||
saveLog("[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));
|
||||
}
|
||||
|
||||
saveLog("[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);
|
||||
saveLog("[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()));
|
||||
}
|
||||
|
||||
saveLog("[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 {
|
||||
saveLog("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);
|
||||
saveLog("[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()));
|
||||
}
|
||||
|
||||
saveLog("[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);
|
||||
}
|
||||
saveLog("[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())) {
|
||||
saveLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP());
|
||||
saveLog("Customize Toolbar... : " + memberDto.getAllowIpBasic());
|
||||
saveLog("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 {
|
||||
saveLog("[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);
|
||||
}
|
||||
}
|
||||
@ -1,290 +0,0 @@
|
||||
package com.munjaon.server.server.task;
|
||||
|
||||
import com.munjaon.server.cache.dto.MemberDto;
|
||||
import com.munjaon.server.cache.enums.CacheService;
|
||||
import com.munjaon.server.cache.service.MemberService;
|
||||
import com.munjaon.server.queue.pool.ReportQueue;
|
||||
import com.munjaon.server.server.dto.ReportUserDto;
|
||||
import com.munjaon.server.server.packet.common.*;
|
||||
import com.munjaon.server.server.queue.ReportUserQueue;
|
||||
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;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class ReportReadTask implements Callable<ReportUserDto> {
|
||||
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 final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance();
|
||||
private ReportUserDto reportUserDto;
|
||||
private final LogUtil logger;
|
||||
|
||||
public ReportReadTask(Selector selector, SelectionKey key, LogUtil logger) {
|
||||
this.selector = selector;
|
||||
this.key = key;
|
||||
this.reportUserDto = (ReportUserDto) key.attachment();
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReportUserDto call() throws Exception {
|
||||
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) {
|
||||
String command = Header.getCommand(headBuffer);
|
||||
switch (Integer.parseInt(command)) {
|
||||
case 1 : recvBind(channel, headBuffer); break;
|
||||
case 6 : recvReport(channel, headBuffer); break;
|
||||
case 8 : recvLinkCheck(channel, headBuffer); break;
|
||||
default: expireConnectUser(); break;
|
||||
}
|
||||
} else {
|
||||
expireConnectUser();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
size = -1;
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/* 읽은 데이터가 없는 경우 command -1 */
|
||||
if (size <= 0) {
|
||||
reportUserDto.setCommand(-1);
|
||||
}
|
||||
|
||||
return reportUserDto;
|
||||
}
|
||||
|
||||
private void recvLinkCheck(SocketChannel channel, ByteBuffer headBuffer) {
|
||||
try {
|
||||
ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH);
|
||||
int size = channel.read(bodyBuffer);
|
||||
if (size > 0) {
|
||||
saveLog("Recv link check");
|
||||
reportUserDto.updateLastTrafficTime();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void recvReport(SocketChannel channel, ByteBuffer headBuffer) {
|
||||
try {
|
||||
ByteBuffer bodyBuffer = ByteBuffer.allocate(Report.REPORT_ACK_BODY_LENGTH);
|
||||
int size = channel.read(bodyBuffer);
|
||||
if (size != Report.REPORT_ACK_BODY_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
saveLog("recv report");
|
||||
ReportQueue reportQueue = reportUserDto.getReportQueue();
|
||||
reportUserDto.updateLastTrafficTime();
|
||||
if (reportQueue != null) {
|
||||
reportQueue.addReadCounter();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private String checkBind(MemberDto memberDto, String id, String pwd) {
|
||||
if (id == null || pwd == null) {
|
||||
return "50";
|
||||
}
|
||||
if (reportUserQueue.isExist(id)) {
|
||||
return "60";
|
||||
}
|
||||
if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
|
||||
return "20";
|
||||
}
|
||||
/* 회원 사용 상태 */
|
||||
if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
|
||||
return "30";
|
||||
}
|
||||
|
||||
return "00";
|
||||
}
|
||||
|
||||
private void 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);
|
||||
}
|
||||
saveLog("[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())) {
|
||||
saveLog("connectUserDto.getRemoteIP() : " + reportUserDto.getRemoteIP());
|
||||
saveLog("Customize Toolbar... : " + memberDto.getAllowIpBasic());
|
||||
saveLog("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 {
|
||||
saveLog("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";
|
||||
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);
|
||||
saveLog("Bind id : " + id);
|
||||
saveLog("Bind pwd : " + pwd);
|
||||
if (id == null || pwd == null) {
|
||||
resultCode = "50";
|
||||
} else {
|
||||
if (reportUserQueue.isExist(id)) {
|
||||
resultCode = "60";
|
||||
} else {
|
||||
MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService();
|
||||
MemberDto memberDto = null;
|
||||
if (svc != null) {
|
||||
memberDto = svc.get(id);
|
||||
}
|
||||
if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
|
||||
resultCode = "20";
|
||||
} else {
|
||||
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 {
|
||||
saveLog("Bind ResultCode : " + resultCode);
|
||||
channel.write(Bind.makeBindAckBuffer(resultCode));
|
||||
if ("00".equals(resultCode) == false) {
|
||||
expireConnectUser();
|
||||
}
|
||||
} catch (IOException 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);
|
||||
}
|
||||
// 소켓 채널 닫기
|
||||
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)) + " {{REPORT_READ_TASK}} " + obj);
|
||||
}
|
||||
|
||||
if (logger == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log(obj);
|
||||
}
|
||||
}
|
||||
@ -1,430 +0,0 @@
|
||||
package com.munjaon.server.server.task;
|
||||
|
||||
import com.munjaon.server.cache.dto.MemberDto;
|
||||
import com.munjaon.server.cache.enums.CacheService;
|
||||
import com.munjaon.server.cache.service.MemberService;
|
||||
import com.munjaon.server.queue.pool.ReportQueue;
|
||||
import com.munjaon.server.server.config.ServerConfig;
|
||||
import com.munjaon.server.server.dto.ReportDto;
|
||||
import com.munjaon.server.server.dto.ReportUserDto;
|
||||
import com.munjaon.server.server.packet.common.*;
|
||||
import com.munjaon.server.server.queue.ReportUserQueue;
|
||||
import com.munjaon.server.server.service.HealthCheckServer;
|
||||
import com.munjaon.server.server.service.PropertyLoader;
|
||||
import com.munjaon.server.util.LogUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
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 extends Thread {
|
||||
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 final SelectionKey key;
|
||||
private final SocketChannel channel;
|
||||
private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance();
|
||||
private final ReportUserDto reportUserDto;
|
||||
private final ReportQueue reportQueue;
|
||||
private final String serviceName;
|
||||
private final LogUtil logger;
|
||||
|
||||
private boolean IS_SERVER_RUN; // 서버가 구동중인지 여부
|
||||
private boolean IS_RUN_YN;
|
||||
private long RUN_FLAG_CHECK_TIME;
|
||||
private long SEND_CYCLE_CHECK_TIME;
|
||||
private long LAST_PACKET_SEND_TIME = System.currentTimeMillis(); // 패킷 송수신 시간을 체크하기 위한 변수(최대 3초간 요청이 없는 경우 Thread 종료)
|
||||
private boolean IS_ERROR = false;
|
||||
|
||||
/* 세션이 만료되었는지 체크 */
|
||||
private boolean isExpiredYn;
|
||||
/* 클라이언트 요청 데이터 수신 */
|
||||
private final ByteBuffer headBuffer = ByteBuffer.allocateDirect(Header.HEADER_LENGTH);
|
||||
private ReportDto reportDto; // 전송 리포트
|
||||
/* 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;
|
||||
if (reportUserDto.isLogin()) {
|
||||
saveLog("[REPORT SERVER READ] [ID : " + reportUserDto.getUserId() + "]");
|
||||
} else {
|
||||
saveLog("[REPORT SERVER READ] [FIRST CONNECTION ... ... ... ... ... ... ...]");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 로그 헤더 생성 */
|
||||
private String printTaskLog() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("[ReportServerTask]");
|
||||
if (reportUserDto.isLogin()) {
|
||||
builder.append("[ID : ").append(reportUserDto.getUserId()).append("]");
|
||||
} else {
|
||||
builder.append("[FIRST CONNECTION ... ... ... ... ... ... ...]");
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
saveLog(printTaskLog() + "[### Start ### ### ### ### ### ### ###]");
|
||||
/* 최초 RUN Flag 체크 */
|
||||
reloadRunFlag();
|
||||
try {
|
||||
/* BIND 체크 및 처리 */
|
||||
bindInterest();
|
||||
SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
|
||||
while (reportUserDto.isLogin() && isRun()) {
|
||||
/* 만료 여부 체크 */
|
||||
if (isExpiredYn) {
|
||||
break;
|
||||
}
|
||||
/* 2. Packet Timeout Check */
|
||||
if (checkTimeOut()) {
|
||||
saveLog(printTaskLog() + "[checkTimeOut : Expired ... ... ... ... ... ... ...]");
|
||||
expireConnectUser();
|
||||
saveLog(printTaskLog() + "[### End ### ### ### ### ### ### ###]");
|
||||
break;
|
||||
}
|
||||
|
||||
sendInterest();
|
||||
recvInterest();
|
||||
/* RUN Flag 체크 */
|
||||
reloadRunFlag();
|
||||
/* 쓰레드 완료 시점 체크 */
|
||||
if (System.currentTimeMillis() - LAST_PACKET_SEND_TIME > ServerConfig.REPORT_EXEC_CYCLE_TIME) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
/* 세션 만료 여부 */
|
||||
this.isExpiredYn = true;
|
||||
this.IS_ERROR = true;
|
||||
saveLog(e);
|
||||
}
|
||||
/* 중요 : 사용자 Thread 실행모드 Off */
|
||||
reportUserDto.setRunningMode(false);
|
||||
/* 에러가 발생한 경우 세션을 종료힌다. */
|
||||
if (IS_ERROR) {
|
||||
expireConnectUser();
|
||||
}
|
||||
saveLog(printTaskLog() + "[### End ### ### ### ### ### ### ###]");
|
||||
}
|
||||
|
||||
private boolean checkTimeOut() {
|
||||
if (System.currentTimeMillis() - this.reportUserDto.getLastTrafficTime() >= Packet.LIMIT_PACKET_TIMEOUT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initHeaderBuffer() {
|
||||
this.headBuffer.clear();
|
||||
for (int loopCnt = 0; loopCnt < Header.HEADER_LENGTH; loopCnt++) {
|
||||
this.headBuffer.put(Packet.SET_DEFAULT_BYTE);
|
||||
}
|
||||
this.headBuffer.position(0);
|
||||
}
|
||||
|
||||
private int readHeader() {
|
||||
initHeaderBuffer();
|
||||
int size = -1;
|
||||
try {
|
||||
size = channel.read(headBuffer);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
private void bindInterest() throws UnsupportedEncodingException {
|
||||
if (reportUserDto.isLogin()) {
|
||||
return;
|
||||
}
|
||||
long bind_check_start_time = System.currentTimeMillis();
|
||||
while(true) {
|
||||
/* 1. Head 읽기 */
|
||||
int size = readHeader();
|
||||
/* 2. Body 읽기 */
|
||||
if (size > 0) {
|
||||
String command = Header.getCommand(this.headBuffer);
|
||||
if (Integer.parseInt(command) == 1) {
|
||||
recvBind(channel, headBuffer);
|
||||
} else {
|
||||
expireConnectUser();
|
||||
}
|
||||
/* 패킷 수신한 경우 무조건 루프를 빠져나간다 */
|
||||
break;
|
||||
}
|
||||
/* 3초 이내에 로그인 실패시 종료 */
|
||||
if (System.currentTimeMillis() - bind_check_start_time > ServerConfig.LIMIT_BIND_TIMEOUT) {
|
||||
expireConnectUser();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recvBind(SocketChannel channel, ByteBuffer headBuffer) {
|
||||
String resultCode = "00";
|
||||
try {
|
||||
ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH);
|
||||
ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH);
|
||||
channel.read(bodyBuffer);
|
||||
Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer);
|
||||
|
||||
String id = Bind.getBindId(bindBuffer);
|
||||
String pwd = Bind.getBindPwd(bindBuffer);
|
||||
|
||||
MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService();
|
||||
MemberDto memberDto = null;
|
||||
if (svc != null) {
|
||||
memberDto = svc.get(id);
|
||||
}
|
||||
saveLog(printTaskLog() + "[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]");
|
||||
/* Bind Check */
|
||||
resultCode = checkBind(memberDto, id, pwd);
|
||||
|
||||
/* 접속 IP 체크 */
|
||||
if ("00".equals(resultCode)) {
|
||||
boolean isPermit = false;
|
||||
if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) {
|
||||
saveLog(printTaskLog() + "[REMOTE IP : " + reportUserDto.getRemoteIP() + "]");
|
||||
saveLog(printTaskLog() + "[ALLOW IP BASIC : " + memberDto.getAllowIpBasic() + "]");
|
||||
saveLog(printTaskLog() + "[ALLOW IP EXTEND : " + memberDto.getAllowIpExtend() + "]");
|
||||
if (memberDto.getAllowIpBasic() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) {
|
||||
isPermit = true;
|
||||
}
|
||||
if (memberDto.getAllowIpExtend() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) {
|
||||
isPermit = true;
|
||||
}
|
||||
} else {
|
||||
isPermit = true;
|
||||
}
|
||||
if (isPermit) {
|
||||
resultCode = "00";
|
||||
} else {
|
||||
resultCode = "40";
|
||||
}
|
||||
}
|
||||
|
||||
/* BIND 성공인 경우 사용자 정보 저장 */
|
||||
if ("00".equals(resultCode)) {
|
||||
reportUserDto.setUserId(id);
|
||||
reportUserDto.setLogin(true);
|
||||
reportUserDto.setMemberDto(memberDto);
|
||||
/* 리포트 큐 생성 */
|
||||
ReportQueue reportQueue = new ReportQueue(reportUserDto.getQueuePath(), reportUserDto.getUserId());
|
||||
reportUserDto.setReportQueue(reportQueue);
|
||||
/* 세션통신 시간 업데이트 */
|
||||
reportUserDto.updateLastTrafficTime();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
resultCode = "10";
|
||||
saveLog(e);
|
||||
}
|
||||
|
||||
try {
|
||||
saveLog(printTaskLog() + "[BIND RESULT : " + resultCode + "]");
|
||||
channel.write(Bind.makeBindAckBuffer(resultCode));
|
||||
if ("00".equals(resultCode)) {
|
||||
/* BIND 성공인 경우 사용자 Pool에 저장 */
|
||||
reportUserQueue.putUser(reportUserDto);
|
||||
} else {
|
||||
expireConnectUser();
|
||||
}
|
||||
/* 모니터링 로그 */
|
||||
HealthCheckServer.saveMonitorLog("[REPORT SERVER][ID : " + reportUserDto.getUserId() + "][BIND RESULT : " + resultCode + "]");
|
||||
} catch (IOException e) {
|
||||
saveLog(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String checkBind(MemberDto memberDto, String id, String pwd) {
|
||||
if (id == null || pwd == null) {
|
||||
return "50";
|
||||
}
|
||||
if (reportUserQueue.isExist(id)) {
|
||||
return "60";
|
||||
}
|
||||
if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) {
|
||||
return "20";
|
||||
}
|
||||
/* 회원 사용 상태 */
|
||||
if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) {
|
||||
return "30";
|
||||
}
|
||||
|
||||
return "00";
|
||||
}
|
||||
|
||||
private void recvInterest() throws IOException, Exception {
|
||||
while (isPacketSendYn) {
|
||||
/* 1. Head 읽기 */
|
||||
ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH);
|
||||
int size = channel.read(headBuffer);
|
||||
if (size > 0) {
|
||||
String command = Header.getCommand(headBuffer);
|
||||
switch (Integer.parseInt(command)) {
|
||||
case 6 : recvReport(channel); break;
|
||||
case 8 : recvLinkCheck(channel); break;
|
||||
default: saveLog(printTaskLog() + "[INVALID REQUEST][command : " + command + "]");
|
||||
expireConnectUser(); break;
|
||||
}
|
||||
/* 마지막 패킷 수신시간 체크 */
|
||||
LAST_PACKET_SEND_TIME = System.currentTimeMillis();
|
||||
} else if (size == 0) {
|
||||
Thread.sleep(1);
|
||||
if (System.currentTimeMillis() - SEND_CYCLE_CHECK_TIME >= ServerConfig.REPORT_EXEC_CYCLE_TIME) {
|
||||
saveLog(printTaskLog() + "[SEND_CYCLE_CHECK_TIME IS OVER : 3000ms]");
|
||||
expireConnectUser();
|
||||
this.isExpiredYn = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
saveLog(printTaskLog() + "[recvInterest : size is zero]");
|
||||
expireConnectUser();
|
||||
throw new IOException("[recvInterest : size is zero]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recvLinkCheck(SocketChannel channel) throws IOException {
|
||||
ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH);
|
||||
int size = channel.read(bodyBuffer);
|
||||
if (size > 0) {
|
||||
saveLog(printTaskLog() + "[RECEIVE LINK CHECK ACK ... ... ... ... ... ... ...]");
|
||||
reportUserDto.updateLastTrafficTime();
|
||||
this.isPacketSendYn = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void recvReport(SocketChannel channel) throws Exception {
|
||||
ByteBuffer bodyBuffer = ByteBuffer.allocate(Report.REPORT_ACK_BODY_LENGTH);
|
||||
int size = channel.read(bodyBuffer);
|
||||
if (size != Report.REPORT_ACK_BODY_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
saveLog(printTaskLog() + "[RECEIVE REPORT ACK ... ... ... ... ... ... ...]");
|
||||
ReportQueue reportQueue = reportUserDto.getReportQueue();
|
||||
reportUserDto.updateLastTrafficTime();
|
||||
this.isPacketSendYn = false;
|
||||
if (reportQueue != null && this.reportDto != null) {
|
||||
saveLog(printTaskLog() + "[RECEIVE REPORT : " + this.reportDto.toString() + "]");
|
||||
reportQueue.addReadCounter();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendInterest() throws Exception {
|
||||
if (isPacketSendYn) {
|
||||
return;
|
||||
}
|
||||
if (reportUserDto.isAlive() == 2) {
|
||||
channel.write(LinkCheck.makeLinkCheckBuffer());
|
||||
saveLog(printTaskLog() + "[SEND LINK CHECK ... ... ... ... ... ... ...]");
|
||||
SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
|
||||
/* Packet 전송했는지 여부 */
|
||||
isPacketSendYn = true;
|
||||
} else {
|
||||
if (this.reportQueue != null && this.reportQueue.isRemainReport()) {
|
||||
this.reportDto = this.reportQueue.popReportFromQueue();
|
||||
if (reportDto == null) {
|
||||
return;
|
||||
}
|
||||
saveLog(printTaskLog() + "[REPORT SEND : " + reportDto.toString() + "]");
|
||||
ByteBuffer reportBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH);
|
||||
Packet.setDefaultByte(reportBuffer);
|
||||
Header.putHeader(reportBuffer, Header.COMMAND_REPORT, Report.REPORT_BODY_LENGTH);
|
||||
Report.putReport(reportBuffer, reportDto);
|
||||
channel.write(reportBuffer);
|
||||
/* Packet 전송했는지 여부 */
|
||||
SEND_CYCLE_CHECK_TIME = System.currentTimeMillis();
|
||||
isPacketSendYn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void expireConnectUser() {
|
||||
if (key == null || !key.isValid()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
SocketChannel channel = (SocketChannel) key.channel();
|
||||
saveLog("[ReportServerTask]Expire connect user: " + reportUserDto);
|
||||
if (reportUserDto != null) {
|
||||
if (reportUserDto.getUserId() != null) {
|
||||
reportUserQueue.removeUser(reportUserDto.getUserId());
|
||||
}
|
||||
key.attach(null);
|
||||
/* 모니터링 로그 */
|
||||
HealthCheckServer.saveMonitorLog("[REPORT SERVER][ID : " + reportUserDto.getUserId() + "][EXPIRE CONNECT USER]");
|
||||
}
|
||||
/* 세션 만료 여부 */
|
||||
this.isExpiredYn = true;
|
||||
// 소켓 채널 닫기
|
||||
channel.close();
|
||||
// 키 닫기
|
||||
key.cancel();
|
||||
} catch (IOException e) {
|
||||
saveLog(e);
|
||||
}
|
||||
}
|
||||
|
||||
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)) + " {{" + this.serviceName + "}} " + obj);
|
||||
}
|
||||
|
||||
if (logger == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log(obj);
|
||||
}
|
||||
}
|
||||
@ -1,565 +0,0 @@
|
||||
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.common.*;
|
||||
import com.munjaon.server.server.queue.CollectUserQueue;
|
||||
import com.munjaon.server.util.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
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();
|
||||
saveLog("[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) throws UnsupportedEncodingException {
|
||||
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()));
|
||||
}
|
||||
} 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()));
|
||||
}
|
||||
|
||||
saveLog("[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);
|
||||
}
|
||||
saveLog("[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));
|
||||
}
|
||||
|
||||
saveLog("[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);
|
||||
saveLog("[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()));
|
||||
}
|
||||
|
||||
saveLog("[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 {
|
||||
saveLog("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);
|
||||
saveLog("[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()));
|
||||
}
|
||||
|
||||
saveLog("[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);
|
||||
}
|
||||
saveLog("[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())) {
|
||||
saveLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP());
|
||||
saveLog("Customize Toolbar... : " + memberDto.getAllowIpBasic());
|
||||
saveLog("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 {
|
||||
saveLog("[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);
|
||||
}
|
||||
}
|
||||
@ -1,125 +0,0 @@
|
||||
package com.munjaon.server.util;
|
||||
|
||||
import org.jdom2.Document;
|
||||
import org.jdom2.Element;
|
||||
import org.jdom2.JDOMException;
|
||||
import org.jdom2.input.SAXBuilder;
|
||||
import org.jdom2.output.Format;
|
||||
import org.jdom2.output.XMLOutputter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
|
||||
public class XmlUtil {
|
||||
// private static Document getDOMParsedDocument(final String fileName) {
|
||||
// Document document = null;
|
||||
// try {
|
||||
//
|
||||
// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
// //If want to make namespace aware.
|
||||
// //factory.setNamespaceAware(true);
|
||||
// DocumentBuilder documentBuilder = factory.newDocumentBuilder();
|
||||
// document = documentBuilder.parse(new File("C:\\Docs\\JDS\\ITN\\MMS01Header.xml"));
|
||||
//
|
||||
// NodeList nodeList = document.getDocumentElement().getChildNodes();
|
||||
// for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
// Node node = nodeList.item(i);
|
||||
// if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
// Element elem = (Element) node;
|
||||
// System.out.println("createDate : " + elem.getAttribute("createDate"));
|
||||
// System.out.println("getTagName : " + elem.getTagName());
|
||||
// System.out.println("getNodeName : " + elem.getNodeName());
|
||||
// System.out.println("getTextContent : " + elem.getTextContent());
|
||||
//// String createDate = elem.getElementsByTagName("createDate").item(0).getChildNodes().item(0).getNodeValue();
|
||||
//// System.out.println("createDate : " + createDate);
|
||||
//// String PopCounter = elem.getElementsByTagName("PopCounter").item(0).getChildNodes().item(0).getNodeValue();
|
||||
//// System.out.println("PopCounter : " + PopCounter);
|
||||
//// Double salary = Double.parseDouble(elem.getElementsByTagName("salary").item(0).getChildNodes().item(0).getNodeValue());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return document;
|
||||
// }
|
||||
|
||||
private static Document getSaxParsedDocument(final String fileName) {
|
||||
Document document = null;
|
||||
|
||||
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||
+ " <catalog>\r\n"
|
||||
+ " <book id=\"bk101\">"
|
||||
+ " <author>Gambardella, Matthew</author> "
|
||||
+ "<title>XML Developer's Guide</title>"
|
||||
+ " <genre>Computer</genre>"
|
||||
+ " <price>44.95</price> "
|
||||
+ "<publish_date>2000-10-01</publish_date> "
|
||||
+ "<description>An in-depth look at creating applications with XML.</description> "
|
||||
+ "</book>"
|
||||
+ " <book id=\"bk102\">"
|
||||
+ " <author>Ralls, Kim</author>"
|
||||
+ " <title>Midnight Rain</title>"
|
||||
+ " <genre>Fantasy</genre>"
|
||||
+ " <price>5.95</price>"
|
||||
+ " <publish_date>2000-12-16</publish_date>"
|
||||
+ " <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>"
|
||||
+ " </book> \r\n"
|
||||
+ "</catalog>\r\n";
|
||||
try {
|
||||
|
||||
SAXBuilder sax = new SAXBuilder();
|
||||
// String that contains XML
|
||||
Document doc = (Document) sax.build(new File("C:\\Docs\\JDS\\ITN\\MMS01Header.xml"));
|
||||
// org.jdom2.Document doc = sax.build(new StringReader(xml));
|
||||
|
||||
Element rootNode = doc.getRootElement();
|
||||
List<Element> bookElements = rootNode.getChildren();
|
||||
System.out.println("bookElements: " + bookElements);
|
||||
for(Element bookElement : bookElements){
|
||||
String name = bookElement.getName();
|
||||
String value = bookElement.getValue();
|
||||
System.out.println(name + " : " + value);
|
||||
}
|
||||
|
||||
} catch (IOException | JDOMException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return document;
|
||||
}
|
||||
|
||||
private static void writeSimpleXml() throws JDOMException, IOException {
|
||||
|
||||
String xml = "<root><child id=\"100\">mkyong</child></root>";
|
||||
SAXBuilder sb = new SAXBuilder();
|
||||
Document doc = sb.build(new StringReader(xml));
|
||||
|
||||
|
||||
Document docFile = new Document();
|
||||
|
||||
Element rootElement = new Element("ReadQueue");
|
||||
rootElement.addContent(new Element("createDate").setText("20240527"));
|
||||
rootElement.addContent(new Element("PopCounter").setText(Integer.toString(0)));
|
||||
|
||||
docFile.setRootElement(rootElement);
|
||||
|
||||
// default in compact mode
|
||||
// XMLOutputter xmlOutputter = new XMLOutputter();
|
||||
|
||||
// pretty print format
|
||||
XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
|
||||
|
||||
// output to console
|
||||
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Docs\\JDS\\ITN\\file.xml");
|
||||
xmlOutputter.output(docFile, fileOutputStream);
|
||||
|
||||
}
|
||||
public static void main(String[] args) throws IOException, JDOMException {
|
||||
// XmlUtil.getDOMParsedDocument("C:\\Docs\\JDS\\ITN\\MMS01Header.xml");
|
||||
XmlUtil.getSaxParsedDocument("C:\\Docs\\JDS\\ITN\\MMS01Header.xml");
|
||||
XmlUtil.writeSimpleXml();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user