--- build.gradle
+++ build.gradle
... | ... | @@ -45,8 +45,6 @@ |
| 45 | 45 |
implementation 'org.apache.commons:commons-configuration2:2.10.1' |
| 46 | 46 |
// https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils |
| 47 | 47 |
implementation 'commons-beanutils:commons-beanutils:1.9.4' |
| 48 |
- // https://mvnrepository.com/artifact/io.netty/netty-all |
|
| 49 |
- implementation 'io.netty:netty-all:4.1.42.Final' |
|
| 50 | 48 |
// https://mvnrepository.com/artifact/org.jdom/jdom2 |
| 51 | 49 |
implementation 'org.jdom:jdom2:2.0.6.1' |
| 52 | 50 |
|
--- src/main/java/com/munjaon/server/netty/config/BaseConfig.java
... | ... | @@ -1,15 +0,0 @@ |
| 1 | -package com.munjaon.server.netty.config; | |
| 2 | - | |
| 3 | -import io.netty.bootstrap.ServerBootstrap; | |
| 4 | -import io.netty.channel.ChannelInboundHandlerAdapter; | |
| 5 | -import io.netty.channel.nio.NioEventLoopGroup; | |
| 6 | - | |
| 7 | -import java.net.InetSocketAddress; | |
| 8 | - | |
| 9 | -public interface BaseConfig { | |
| 10 | - NioEventLoopGroup bossGroup(); | |
| 11 | - NioEventLoopGroup workerGroup(); | |
| 12 | - InetSocketAddress port(); | |
| 13 | - ServerBootstrap serverBootstrap(); | |
| 14 | - ChannelInboundHandlerAdapter handler(); | |
| 15 | -} |
--- src/main/java/com/munjaon/server/netty/handler/SampleHandler.java
... | ... | @@ -1,21 +0,0 @@ |
| 1 | -package com.munjaon.server.netty.handler; | |
| 2 | - | |
| 3 | -import io.netty.channel.ChannelHandlerContext; | |
| 4 | -import io.netty.channel.SimpleChannelInboundHandler; | |
| 5 | - | |
| 6 | -public class SampleHandler extends SimpleChannelInboundHandler<String> { | |
| 7 | - @Override | |
| 8 | - protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception { | |
| 9 | - | |
| 10 | - } | |
| 11 | - | |
| 12 | - @Override | |
| 13 | - public void channelInactive(ChannelHandlerContext ctx) throws Exception { | |
| 14 | - | |
| 15 | - } | |
| 16 | - | |
| 17 | - @Override | |
| 18 | - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { | |
| 19 | - | |
| 20 | - } | |
| 21 | -} |
--- src/main/java/com/munjaon/server/netty/init/SampleNettyInitializer.java
... | ... | @@ -1,11 +0,0 @@ |
| 1 | -package com.munjaon.server.netty.init; | |
| 2 | - | |
| 3 | -import io.netty.channel.Channel; | |
| 4 | -import io.netty.channel.ChannelInitializer; | |
| 5 | - | |
| 6 | -public class SampleNettyInitializer extends ChannelInitializer<Channel> { | |
| 7 | - @Override | |
| 8 | - protected void initChannel(Channel channel) throws Exception { | |
| 9 | - | |
| 10 | - } | |
| 11 | -} |
--- src/main/java/com/munjaon/server/server/sample/ExecutorServiceTest3.java
... | ... | @@ -1,40 +0,0 @@ |
| 1 | -package com.munjaon.server.server.sample; | |
| 2 | - | |
| 3 | -import java.util.ArrayList; | |
| 4 | -import java.util.List; | |
| 5 | -import java.util.concurrent.ExecutionException; | |
| 6 | -import java.util.concurrent.ExecutorService; | |
| 7 | -import java.util.concurrent.Executors; | |
| 8 | -import java.util.concurrent.Future; | |
| 9 | - | |
| 10 | -public class ExecutorServiceTest3 { | |
| 11 | - public static void main(String args[]) { | |
| 12 | - final int maxCore = Runtime.getRuntime().availableProcessors(); | |
| 13 | - System.out.println("maxCore : " + maxCore); | |
| 14 | - final ExecutorService executor = Executors.newFixedThreadPool(maxCore); | |
| 15 | - final List<Future<String>> futures = new ArrayList<>(); | |
| 16 | - | |
| 17 | - for (int i = 1; i < 5; i++) { | |
| 18 | - final int index = i; | |
| 19 | - futures.add(executor.submit(() -> { | |
| 20 | - System.out.println("finished job" + index); | |
| 21 | - return "job" + index + " " + Thread.currentThread().getName(); | |
| 22 | - })); | |
| 23 | - } | |
| 24 | - | |
| 25 | - for (Future<String> future : futures) { | |
| 26 | - String result = null; | |
| 27 | - try { | |
| 28 | - result = future.get(); | |
| 29 | - } catch (InterruptedException e) { | |
| 30 | - e.printStackTrace(); | |
| 31 | - } catch (ExecutionException e) { | |
| 32 | - e.printStackTrace(); | |
| 33 | - } | |
| 34 | - System.out.println(result); | |
| 35 | - } | |
| 36 | - | |
| 37 | - executor.shutdownNow(); | |
| 38 | - System.out.println("end"); | |
| 39 | - } | |
| 40 | -} |
--- src/main/java/com/munjaon/server/server/sample/ExecutorServiceTest4.java
... | ... | @@ -1,63 +0,0 @@ |
| 1 | -package com.munjaon.server.server.sample; | |
| 2 | - | |
| 3 | -import java.util.List; | |
| 4 | -import java.util.concurrent.ArrayBlockingQueue; | |
| 5 | -import java.util.concurrent.BlockingQueue; | |
| 6 | -import java.util.concurrent.ExecutorService; | |
| 7 | -import java.util.concurrent.Executors; | |
| 8 | - | |
| 9 | -public class ExecutorServiceTest4 { | |
| 10 | - public static void main(String args[]) { | |
| 11 | - ParallelExcutorService service = new ParallelExcutorService(); | |
| 12 | - service.submit("job1"); | |
| 13 | - service.submit("job2"); | |
| 14 | - service.submit("job3"); | |
| 15 | - service.submit("job4"); | |
| 16 | - | |
| 17 | -// for (int i = 0 ; i < 4; i++) { | |
| 18 | -// String result = service.take(); | |
| 19 | -// System.out.println(result); | |
| 20 | -// } | |
| 21 | - | |
| 22 | - System.out.println("end"); | |
| 23 | - service.close(); | |
| 24 | - } | |
| 25 | - | |
| 26 | - private static class ParallelExcutorService { | |
| 27 | - private final int maxCore = Runtime.getRuntime().availableProcessors(); | |
| 28 | - private final ExecutorService executor = Executors.newFixedThreadPool(maxCore); | |
| 29 | - private final BlockingQueue<String> queue = new ArrayBlockingQueue<>(10); | |
| 30 | - | |
| 31 | - public ParallelExcutorService() { | |
| 32 | - } | |
| 33 | - | |
| 34 | - public void submit(String job) { | |
| 35 | - executor.submit(() -> { | |
| 36 | -// String threadName = Thread.currentThread().getName(); | |
| 37 | - System.out.println("finished " + job); | |
| 38 | -// String result = job + ", " + threadName; | |
| 39 | -// try { | |
| 40 | -// queue.put(result); | |
| 41 | -// } catch (InterruptedException e) { | |
| 42 | -// Thread.currentThread().interrupt(); | |
| 43 | -// } | |
| 44 | - }); | |
| 45 | - } | |
| 46 | - | |
| 47 | - public String take() { | |
| 48 | - try { | |
| 49 | - return queue.take(); | |
| 50 | - } catch (InterruptedException e) { | |
| 51 | - Thread.currentThread().interrupt(); | |
| 52 | - throw new IllegalStateException(e); | |
| 53 | - } | |
| 54 | - } | |
| 55 | - | |
| 56 | - public void close() { | |
| 57 | - List<Runnable> unfinishedTasks = executor.shutdownNow(); | |
| 58 | - if (!unfinishedTasks.isEmpty()) { | |
| 59 | - System.out.println("Not all tasks finished before calling close: " + unfinishedTasks.size()); | |
| 60 | - } | |
| 61 | - } | |
| 62 | - } | |
| 63 | -} |
--- src/main/java/com/munjaon/server/server/sample/Main.java
... | ... | @@ -1,31 +0,0 @@ |
| 1 | -package com.munjaon.server.server.sample; | |
| 2 | - | |
| 3 | -import java.util.concurrent.ExecutionException; | |
| 4 | -import java.util.concurrent.ExecutorService; | |
| 5 | -import java.util.concurrent.Executors; | |
| 6 | - | |
| 7 | -public class Main { | |
| 8 | - public static void main(String[] args) throws InterruptedException, ExecutionException { | |
| 9 | - ExecutorService e = Executors.newFixedThreadPool(5); | |
| 10 | - // 리턴 값이 필요 없는 경우 | |
| 11 | - for (int i = 0; i < 5; i++) { | |
| 12 | - e.execute(new MyRunnable(i * 20)); | |
| 13 | - } | |
| 14 | - // 작업을 기다려야 할 경우 | |
| 15 | - e.shutdown(); | |
| 16 | - | |
| 17 | - // 리턴 값이 필요한 경우 | |
| 18 | -// List<Future<Integer>> l = new ArrayList<>(); | |
| 19 | -// for (int i = 0; i < 5; i++) { | |
| 20 | -// Future<Integer> f = e.submit(new MyCallable(i * 20)); | |
| 21 | -// l.add(f); | |
| 22 | -// } | |
| 23 | -// | |
| 24 | -// // 작업이 완료 되길 기다려야 할 경우 | |
| 25 | -// int n = 0; | |
| 26 | -// for (int i = 0; i < 5; i++) { | |
| 27 | -// Future<Integer> f = l.get(i); | |
| 28 | -// n += f.get(); | |
| 29 | -// } | |
| 30 | - } | |
| 31 | -} |
--- src/main/java/com/munjaon/server/server/sample/MyCallable.java
... | ... | @@ -1,27 +0,0 @@ |
| 1 | -package com.munjaon.server.server.sample; | |
| 2 | - | |
| 3 | -import java.util.concurrent.Callable; | |
| 4 | - | |
| 5 | -public class MyCallable implements Callable { | |
| 6 | - private final int s; | |
| 7 | - | |
| 8 | - public MyCallable(int s) { | |
| 9 | - this.s = s; | |
| 10 | - } | |
| 11 | - | |
| 12 | - @Override | |
| 13 | - public Integer call() throws Exception { | |
| 14 | - int in = 0; | |
| 15 | - for (int i = 0; i < 20; i++) { | |
| 16 | - System.out.println(s + " : MyCallable"); | |
| 17 | - System.out.println(i + s); | |
| 18 | - in += i + s; | |
| 19 | - try { | |
| 20 | - Thread.sleep(1000L); | |
| 21 | - } catch (InterruptedException e) { | |
| 22 | - throw new RuntimeException(e); | |
| 23 | - } | |
| 24 | - } | |
| 25 | - return in; | |
| 26 | - } | |
| 27 | -} |
--- src/main/java/com/munjaon/server/server/sample/MyRunnable.java
... | ... | @@ -1,21 +0,0 @@ |
| 1 | -package com.munjaon.server.server.sample; | |
| 2 | - | |
| 3 | -public class MyRunnable implements Runnable { | |
| 4 | - private final int s; | |
| 5 | - public MyRunnable(int s) { | |
| 6 | - this.s = s; | |
| 7 | - } | |
| 8 | - | |
| 9 | - public void run() { | |
| 10 | - System.out.println("SendReadTask start : " + Thread.currentThread().getName()); | |
| 11 | - for (int i = 0; i < 20; i++) { | |
| 12 | - System.out.println(s + " : MyRunnable : " + Thread.currentThread().getName()); | |
| 13 | - System.out.println(i + s); | |
| 14 | - try { | |
| 15 | - Thread.sleep(1000L); | |
| 16 | - } catch (InterruptedException e) { | |
| 17 | - throw new RuntimeException(e); | |
| 18 | - } | |
| 19 | - } | |
| 20 | - } | |
| 21 | -} |
--- src/main/java/com/munjaon/server/server/sample/SlackTest.java
... | ... | @@ -1,32 +0,0 @@ |
| 1 | -package com.munjaon.server.server.sample; | |
| 2 | - | |
| 3 | -import com.slack.api.Slack; | |
| 4 | -import com.slack.api.methods.MethodsClient; | |
| 5 | -import com.slack.api.methods.SlackApiException; | |
| 6 | -import com.slack.api.methods.request.chat.ChatPostMessageRequest; | |
| 7 | - | |
| 8 | -import java.io.IOException; | |
| 9 | - | |
| 10 | -public class SlackTest { | |
| 11 | - public static void main(final String[] args) { | |
| 12 | - String token = "xoxb-7591405602163-7594011803524-gKJQfJbhRSmOFr1XFcwujWDr"; | |
| 13 | - String channelAddress = "#프로젝트"; | |
| 14 | - String message = "test"; | |
| 15 | - try{ | |
| 16 | - | |
| 17 | - MethodsClient methods = Slack.getInstance().methods(token); | |
| 18 | - | |
| 19 | - ChatPostMessageRequest request = ChatPostMessageRequest.builder() | |
| 20 | - .channel(channelAddress) | |
| 21 | - .text(message) | |
| 22 | - .build(); | |
| 23 | - | |
| 24 | - methods.chatPostMessage(request); | |
| 25 | - | |
| 26 | -// log.info("Slack " + channel + " 에 메시지 보냄"); | |
| 27 | - } catch (SlackApiException | IOException e) { | |
| 28 | - e.printStackTrace(); | |
| 29 | -// log.error(e.getMessage()); | |
| 30 | - } | |
| 31 | - } | |
| 32 | -} |
--- src/main/java/com/munjaon/server/server/service/CollectBackServerService.java
... | ... | @@ -1,404 +0,0 @@ |
| 1 | -package com.munjaon.server.server.service; | |
| 2 | - | |
| 3 | -import com.munjaon.server.cache.dto.MemberDto; | |
| 4 | -import com.munjaon.server.cache.enums.CacheService; | |
| 5 | -import com.munjaon.server.cache.service.MemberService; | |
| 6 | -import com.munjaon.server.queue.dto.BasicMessageDto; | |
| 7 | -import com.munjaon.server.queue.enums.QueueTypeWorker; | |
| 8 | -import com.munjaon.server.server.dto.ConnectUserDto; | |
| 9 | -import com.munjaon.server.server.dto.HeaderDto; | |
| 10 | -import com.munjaon.server.server.packet.common.*; | |
| 11 | -import com.munjaon.server.util.LogUtil; | |
| 12 | -import lombok.Getter; | |
| 13 | -import org.json.simple.JSONObject; | |
| 14 | - | |
| 15 | -import java.io.IOException; | |
| 16 | -import java.io.UnsupportedEncodingException; | |
| 17 | -import java.net.InetSocketAddress; | |
| 18 | -import java.net.Socket; | |
| 19 | -import java.net.SocketAddress; | |
| 20 | -import java.nio.ByteBuffer; | |
| 21 | -import java.nio.channels.SelectionKey; | |
| 22 | -import java.nio.channels.Selector; | |
| 23 | -import java.nio.channels.ServerSocketChannel; | |
| 24 | -import java.nio.channels.SocketChannel; | |
| 25 | -import java.time.LocalDateTime; | |
| 26 | -import java.time.format.DateTimeFormatter; | |
| 27 | -import java.util.Iterator; | |
| 28 | -import java.util.List; | |
| 29 | -import java.util.Map; | |
| 30 | -import java.util.concurrent.ConcurrentHashMap; | |
| 31 | -import java.util.concurrent.ExecutorService; | |
| 32 | -import java.util.concurrent.Executors; | |
| 33 | - | |
| 34 | -public class CollectBackServerService extends Service { | |
| 35 | - private final InetSocketAddress listenAddress; | |
| 36 | - private CollectorThreadService threadService; | |
| 37 | - private Selector selector; | |
| 38 | - private final String serviceType; | |
| 39 | - | |
| 40 | - public CollectBackServerService(String serviceName, String serviceType, int port) { | |
| 41 | - super(serviceName); | |
| 42 | - this.listenAddress = new InetSocketAddress(port); | |
| 43 | - this.serviceType = serviceType; | |
| 44 | - } | |
| 45 | - @Override | |
| 46 | - public void checkReady() { | |
| 47 | - QueueTypeWorker worker = QueueTypeWorker.find(this.serviceType); | |
| 48 | - if (worker != null && worker.getQueueSize() > 0) { | |
| 49 | - this.IS_READY_YN = true; | |
| 50 | - } else { | |
| 51 | - this.IS_READY_YN = false; | |
| 52 | - } | |
| 53 | - } | |
| 54 | - | |
| 55 | - @Override | |
| 56 | - public void initResources() { | |
| 57 | - try { | |
| 58 | - initCollectChannel(); | |
| 59 | - threadService = new CollectorThreadService(8, this.serviceType, logger); | |
| 60 | - } catch (IOException e) { | |
| 61 | - saveSystemLog(e); | |
| 62 | - throw new RuntimeException(e); | |
| 63 | - } | |
| 64 | - } | |
| 65 | - | |
| 66 | - private void initCollectChannel() throws IOException { | |
| 67 | - selector = Selector.open(); | |
| 68 | - /* 채널 생성 */ | |
| 69 | - ServerSocketChannel serverChannel = ServerSocketChannel.open(); | |
| 70 | - /* non-Blocking 설정 */ | |
| 71 | - serverChannel.configureBlocking(false); | |
| 72 | - /* 서버 ip, port 설정 */ | |
| 73 | - serverChannel.socket().bind(listenAddress); | |
| 74 | - /* 채널에 accept 대기 설정 */ | |
| 75 | - serverChannel.register(selector, SelectionKey.OP_ACCEPT); | |
| 76 | - } | |
| 77 | - | |
| 78 | - private void closeCollectChannel() throws IOException { | |
| 79 | - selector.close(); | |
| 80 | - } | |
| 81 | - | |
| 82 | - @Override | |
| 83 | - public void releaseResources() { | |
| 84 | - try { | |
| 85 | - closeCollectChannel(); | |
| 86 | - threadService.close(); | |
| 87 | - } catch (IOException e) { | |
| 88 | - saveSystemLog(e); | |
| 89 | - throw new RuntimeException(e); | |
| 90 | - } | |
| 91 | - } | |
| 92 | - | |
| 93 | - @Override | |
| 94 | - public void doService() { | |
| 95 | - while (isRun()) { | |
| 96 | - try { | |
| 97 | - execInterest(); | |
| 98 | - } catch (Exception e) { | |
| 99 | - throw new RuntimeException(e); | |
| 100 | - } | |
| 101 | - } | |
| 102 | - } | |
| 103 | - | |
| 104 | - private void execInterest() throws IOException { | |
| 105 | - if (selector.select(1000) == 0) { | |
| 106 | - return ; | |
| 107 | - } | |
| 108 | - Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); | |
| 109 | - while (keys.hasNext()) { | |
| 110 | - SelectionKey key = keys.next(); | |
| 111 | - if (key.isValid()) { | |
| 112 | - if (key.isAcceptable()) { // 접속일 경우.. | |
| 113 | - saveSystemLog("isAcceptable"); | |
| 114 | - threadService.submit(selector, key, 1); | |
| 115 | - } else if (key.isReadable()) { // 수신일 경우.. | |
| 116 | - saveSystemLog("isReadable"); | |
| 117 | - threadService.submit(selector, key, 2); | |
| 118 | - } else if (key.isWritable()) { // 발신일 경우.. | |
| 119 | - saveSystemLog("isWritable"); | |
| 120 | - threadService.submit(selector, key, 3); | |
| 121 | - } | |
| 122 | - } | |
| 123 | - /* 키 셋에서 제거. */ | |
| 124 | - keys.remove(); | |
| 125 | - } | |
| 126 | - } | |
| 127 | - | |
| 128 | - @Override | |
| 129 | - public JSONObject monitorService() { | |
| 130 | - return null; | |
| 131 | - } | |
| 132 | - | |
| 133 | - private static class CollectorThreadService { | |
| 134 | - @Getter | |
| 135 | - private String serviceType; | |
| 136 | - @Getter | |
| 137 | - private final int maxCore; | |
| 138 | - private final ExecutorService executor; | |
| 139 | - private final Map<String, ConnectUserDto> connectUserMap = new ConcurrentHashMap<>(); | |
| 140 | - private final LogUtil logger; | |
| 141 | - | |
| 142 | - public CollectorThreadService(String serviceType, LogUtil logger) { | |
| 143 | - this(Runtime.getRuntime().availableProcessors(), serviceType, logger); | |
| 144 | - } | |
| 145 | - | |
| 146 | - public CollectorThreadService(int maxCore, String serviceType, LogUtil logger) { | |
| 147 | - this.maxCore = maxCore; | |
| 148 | - this.executor = Executors.newFixedThreadPool(maxCore); | |
| 149 | - this.logger = logger; | |
| 150 | - } | |
| 151 | - | |
| 152 | - public void submit(Selector selector, SelectionKey key, int interestOps) { | |
| 153 | - executor.submit(() -> { | |
| 154 | - switch (interestOps) { | |
| 155 | - case 1 : accept(selector, key); break; | |
| 156 | - case 2 : read(selector, key); break; | |
| 157 | - case 3 : write(selector, key); break; | |
| 158 | - default : break; | |
| 159 | - } | |
| 160 | - }); | |
| 161 | - } | |
| 162 | - | |
| 163 | - private void accept(Selector selector, SelectionKey key) { | |
| 164 | - try { | |
| 165 | - /* 키 채널을 가져온다. */ | |
| 166 | - ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); | |
| 167 | - /* accept을 해서 Socket 채널을 가져온다. */ | |
| 168 | - SocketChannel channel = serverChannel.accept(); | |
| 169 | - channel.configureBlocking(false); | |
| 170 | - /* 소켓 취득 */ | |
| 171 | - Socket socket = channel.socket(); | |
| 172 | - SocketAddress remoteAddr = socket.getRemoteSocketAddress(); | |
| 173 | - saveSystemLog("accept : " + Thread.currentThread().getName()); | |
| 174 | - saveSystemLog("Connected to: " + remoteAddr); | |
| 175 | - // Socket 채널을 channel에 수신 등록한다 | |
| 176 | - channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).build()); | |
| 177 | - } catch (Exception e) { | |
| 178 | - throw new RuntimeException(e); | |
| 179 | - } | |
| 180 | - } | |
| 181 | - | |
| 182 | -// private void read(Selector selector, SelectionKey key) { | |
| 183 | -// try { | |
| 184 | -// saveSystemLog("read : " + Thread.currentThread().getName()); | |
| 185 | -// // 키 채널을 가져온다. | |
| 186 | -// SocketChannel channel = (SocketChannel) key.channel(); | |
| 187 | -// ConnectUserDto userDto = (ConnectUserDto) key.attachment(); | |
| 188 | -// | |
| 189 | -// int size = -1; | |
| 190 | -// | |
| 191 | -// ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); | |
| 192 | -// ByteBuffer bindBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); | |
| 193 | -// ByteBuffer linkBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_BODY_LENGTH); | |
| 194 | -// ByteBuffer msgBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH); | |
| 195 | -// try { | |
| 196 | -// size = channel.read(headBuffer); | |
| 197 | -// String command = Header.getCommand(headBuffer); | |
| 198 | -// System.out.println("command : " + command); | |
| 199 | -// if ("1".equals(command)) { | |
| 200 | -// size = channel.read(bindBuffer); | |
| 201 | -// } else if ("3".equals(command)) { | |
| 202 | -// size = channel.read(msgBuffer); | |
| 203 | -// } else if ("7".equals(command)) { | |
| 204 | -// size = channel.read(linkBuffer); | |
| 205 | -// } else { | |
| 206 | -// size = -1; | |
| 207 | -// } | |
| 208 | -// | |
| 209 | -// System.out.println("size : " + size); | |
| 210 | -// } catch (IOException e) {} | |
| 211 | -// if (size < 0) { | |
| 212 | -// expireConnectUser(key); | |
| 213 | -// } else if (size > 0) { | |
| 214 | -//// String command = Header.getCommand(buffer); | |
| 215 | -//// saveSystemLog("command : " + command); | |
| 216 | -//// switch (Integer.parseInt(command)) { | |
| 217 | -//// case 1 : recvBind(channel, buffer, userDto); break; | |
| 218 | -//// case 3 : recvDeliver(channel, buffer, userDto); break; | |
| 219 | -//// case 7 : recvLinkCheck(key); break; | |
| 220 | -//// default: expireConnectUser(key); break; | |
| 221 | -//// } | |
| 222 | -// } | |
| 223 | -// } catch (Exception e) { | |
| 224 | -// e.printStackTrace(); | |
| 225 | -// } | |
| 226 | -// System.out.println("read"); | |
| 227 | -// } | |
| 228 | - | |
| 229 | - private void read(Selector selector, SelectionKey key) { | |
| 230 | - try { | |
| 231 | - saveSystemLog("read : " + Thread.currentThread().getName()); | |
| 232 | - // 키 채널을 가져온다. | |
| 233 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 234 | - ConnectUserDto userDto = (ConnectUserDto) key.attachment(); | |
| 235 | - | |
| 236 | - int size = -1; | |
| 237 | - ByteBuffer buffer = ByteBuffer.allocate(256); | |
| 238 | - try { | |
| 239 | - size = channel.read(buffer); | |
| 240 | - } catch (IOException e) {} | |
| 241 | - if (size < 0) { | |
| 242 | - expireConnectUser(key); | |
| 243 | - } else if (size > 0) { | |
| 244 | - String command = Header.getCommand(buffer); | |
| 245 | - saveSystemLog("command : " + command); | |
| 246 | - switch (Integer.parseInt(command)) { | |
| 247 | - case 1 : recvBind(channel, buffer, userDto); break; | |
| 248 | - case 3 : recvDeliver(channel, buffer, userDto); break; | |
| 249 | - case 7 : recvLinkCheck(key); break; | |
| 250 | - default: expireConnectUser(key); break; | |
| 251 | - } | |
| 252 | - } | |
| 253 | - } catch (Exception e) { | |
| 254 | - e.printStackTrace(); | |
| 255 | - } | |
| 256 | - System.out.println("read"); | |
| 257 | - } | |
| 258 | - | |
| 259 | - private void recvBind(SocketChannel channel, ByteBuffer buffer, ConnectUserDto userDto) { | |
| 260 | - String resultCode = "00"; | |
| 261 | - try { | |
| 262 | - String id = Bind.getBindId(buffer); | |
| 263 | - String pwd = Bind.getBindPwd(buffer); | |
| 264 | - saveSystemLog("id : " + id); | |
| 265 | - saveSystemLog("pwd : " + pwd); | |
| 266 | - if (id == null || pwd == null) { | |
| 267 | - resultCode = "50"; | |
| 268 | - } else { | |
| 269 | - if (connectUserMap.containsKey(id)) { | |
| 270 | - resultCode = "60"; | |
| 271 | - } else { | |
| 272 | - MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); | |
| 273 | - MemberDto memberDto = null; | |
| 274 | - if (svc != null) { | |
| 275 | - memberDto = svc.get(id); | |
| 276 | - } | |
| 277 | - if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { | |
| 278 | - resultCode = "20"; | |
| 279 | - } else { | |
| 280 | - userDto.setUserId(id); | |
| 281 | - userDto.setLogin(true); | |
| 282 | - userDto.setMemberDto(memberDto); | |
| 283 | - } | |
| 284 | - } | |
| 285 | - } | |
| 286 | - } catch (Exception e) { | |
| 287 | - resultCode = "10"; | |
| 288 | - e.printStackTrace(); | |
| 289 | - } | |
| 290 | - | |
| 291 | - try { | |
| 292 | - saveSystemLog("resultCode : " + resultCode); | |
| 293 | - channel.write(Bind.makeBindAckBuffer(resultCode)); | |
| 294 | - } catch (IOException e) { | |
| 295 | - e.printStackTrace(); | |
| 296 | - } | |
| 297 | - } | |
| 298 | - | |
| 299 | - private void recvDeliver(SocketChannel channel, ByteBuffer buffer, ConnectUserDto userDto) throws Exception { | |
| 300 | - BasicMessageDto messageDto = new BasicMessageDto(); | |
| 301 | - messageDto.setRouterSeq("40"); | |
| 302 | - messageDto.setServiceType("4"); | |
| 303 | - messageDto.setUserId(userDto.getUserId()); | |
| 304 | - messageDto.setRemoteIP(userDto.getRemoteIP()); | |
| 305 | - messageDto.setSendStatus("0"); | |
| 306 | - messageDto.setUserMsgID(CommonMessage.getMessageIdForDeliver(buffer)); | |
| 307 | - messageDto.setUserSender(CommonMessage.getSenderForDeliver(buffer)); | |
| 308 | - messageDto.setUserReceiver(CommonMessage.getReceiverForDeliver(buffer)); | |
| 309 | - messageDto.setReserveDt(CommonMessage.getReserveTimeForDeliver(buffer)); | |
| 310 | - messageDto.setRequestDt(CommonMessage.getRequestTimeForDeliver(buffer)); | |
| 311 | - messageDto.setUnitCost("10.4"); | |
| 312 | - messageDto.setUserMessage(SmsMessage.getMessageForDeliver(buffer)); | |
| 313 | - | |
| 314 | - QueueTypeWorker worker = QueueTypeWorker.find("SMS"); | |
| 315 | - if (worker != null) { | |
| 316 | - worker.pushQueue(messageDto); | |
| 317 | - channel.write(SmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 318 | - } | |
| 319 | - } | |
| 320 | - private void recvLinkCheck(SelectionKey key) throws IOException { | |
| 321 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 322 | - channel.write(LinkCheck.makeLinkCheckAckBuffer()); | |
| 323 | - } | |
| 324 | - private void expireConnectUser(SelectionKey key) { | |
| 325 | - if (key == null || !key.isValid()) { | |
| 326 | - return; | |
| 327 | - } | |
| 328 | - try { | |
| 329 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 330 | - ConnectUserDto userDto = (ConnectUserDto) key.attachment(); | |
| 331 | - if (userDto != null && userDto.getUserId() != null) { | |
| 332 | - connectUserMap.remove(userDto.getUserId()); | |
| 333 | - key.attach(null); | |
| 334 | - } | |
| 335 | - // 소켓 채널 닫기 | |
| 336 | - channel.close(); | |
| 337 | - // 키 닫기 | |
| 338 | - key.cancel(); | |
| 339 | - } catch (IOException e) { | |
| 340 | - e.printStackTrace(); | |
| 341 | - } | |
| 342 | - } | |
| 343 | - private HeaderDto getHeader(SocketChannel channel) throws UnsupportedEncodingException { | |
| 344 | - HeaderDto headerDto = HeaderDto.builder().build(); | |
| 345 | - int size = -1; | |
| 346 | - ByteBuffer buffer = ByteBuffer.allocate(Header.HEADER_LENGTH); | |
| 347 | - if (channel != null) { | |
| 348 | - try { | |
| 349 | - saveSystemLog("Key is valid : "); | |
| 350 | -// SocketChannel channel = (SocketChannel) key.channel(); | |
| 351 | - size = channel.read(buffer); | |
| 352 | - } catch (IOException e) {} | |
| 353 | - } | |
| 354 | - | |
| 355 | - if (size < 0) { | |
| 356 | - saveSystemLog("Is Error : "); | |
| 357 | - headerDto.setError(true); | |
| 358 | - } else { | |
| 359 | - saveSystemLog("version : " + Header.getVersion(buffer)); | |
| 360 | - saveSystemLog("Command : " + Header.getCommand(buffer)); | |
| 361 | - saveSystemLog("BodyLength : " + Header.getBodyLength(buffer)); | |
| 362 | - headerDto.setVersion(Header.getVersion(buffer)); | |
| 363 | - headerDto.setCommand(Integer.parseInt(Header.getCommand(buffer))); | |
| 364 | - headerDto.setBodyLength(Integer.parseInt(Header.getBodyLength(buffer))); | |
| 365 | - } | |
| 366 | - | |
| 367 | - saveSystemLog("READ HEADER : " + size); | |
| 368 | - | |
| 369 | - return headerDto; | |
| 370 | - } | |
| 371 | - | |
| 372 | - private void write(Selector selector, SelectionKey key) { | |
| 373 | - System.out.println("write"); | |
| 374 | - } | |
| 375 | - | |
| 376 | - private void saveSystemLog(Object obj) { | |
| 377 | - saveLog(obj, true); | |
| 378 | - } | |
| 379 | - | |
| 380 | - private void saveLog(Object obj) { | |
| 381 | - saveLog(obj, false); | |
| 382 | - } | |
| 383 | - | |
| 384 | - private void saveLog(Object obj, boolean isConsoleOutput) { | |
| 385 | - if (isConsoleOutput) { | |
| 386 | - System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{" + serviceType + "}} " + obj); | |
| 387 | - } | |
| 388 | - | |
| 389 | - if (logger == null) { | |
| 390 | - return; | |
| 391 | - } | |
| 392 | - | |
| 393 | - logger.log(obj); | |
| 394 | - } | |
| 395 | - | |
| 396 | - public void close() { | |
| 397 | - List<Runnable> unfinishedTasks = executor.shutdownNow(); | |
| 398 | - connectUserMap.clear(); | |
| 399 | - if (!unfinishedTasks.isEmpty()) { | |
| 400 | - saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size()); | |
| 401 | - } | |
| 402 | - } | |
| 403 | - } | |
| 404 | -} |
--- src/main/java/com/munjaon/server/server/service/CollectServerService.java
... | ... | @@ -1,342 +0,0 @@ |
| 1 | -package com.munjaon.server.server.service; | |
| 2 | - | |
| 3 | -import com.munjaon.server.queue.enums.QueueTypeWorker; | |
| 4 | -import com.munjaon.server.server.dto.ConnectUserDto; | |
| 5 | -import com.munjaon.server.server.queue.CollectUserQueue; | |
| 6 | -import com.munjaon.server.server.task.CollectReadTask; | |
| 7 | -import com.munjaon.server.server.task.SendReadTask; | |
| 8 | -import com.munjaon.server.server.task.StatusCheckTask; | |
| 9 | -import com.munjaon.server.util.LogUtil; | |
| 10 | -import lombok.Getter; | |
| 11 | -import org.json.simple.JSONObject; | |
| 12 | - | |
| 13 | -import java.io.IOException; | |
| 14 | -import java.net.InetAddress; | |
| 15 | -import java.net.InetSocketAddress; | |
| 16 | -import java.net.Socket; | |
| 17 | -import java.nio.channels.SelectionKey; | |
| 18 | -import java.nio.channels.Selector; | |
| 19 | -import java.nio.channels.ServerSocketChannel; | |
| 20 | -import java.nio.channels.SocketChannel; | |
| 21 | -import java.time.LocalDateTime; | |
| 22 | -import java.time.format.DateTimeFormatter; | |
| 23 | -import java.util.ArrayList; | |
| 24 | -import java.util.Iterator; | |
| 25 | -import java.util.List; | |
| 26 | -import java.util.concurrent.ExecutionException; | |
| 27 | -import java.util.concurrent.ExecutorService; | |
| 28 | -import java.util.concurrent.Executors; | |
| 29 | -import java.util.concurrent.Future; | |
| 30 | - | |
| 31 | -public class CollectServerService extends Service { | |
| 32 | - private final InetSocketAddress listenAddress; | |
| 33 | - private CollectThreadService threadService; | |
| 34 | - private StatusThreadService statusThreadService; | |
| 35 | - private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); | |
| 36 | - | |
| 37 | - private Selector selector; | |
| 38 | - private final String serviceType; | |
| 39 | - private int readMaxCore; | |
| 40 | - | |
| 41 | - private long USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis(); | |
| 42 | - private static final long USER_STATUS_CYCLE_TIME = 60000; | |
| 43 | - | |
| 44 | - public CollectServerService(String serviceName, String serviceType, int port) { | |
| 45 | - super(serviceName); | |
| 46 | - this.readMaxCore = Integer.parseInt(getProp("READ_MAX_CORE").trim()); | |
| 47 | - this.listenAddress = new InetSocketAddress(port); | |
| 48 | - this.serviceType = serviceType; | |
| 49 | - } | |
| 50 | - | |
| 51 | - @Override | |
| 52 | - public void checkReady() { | |
| 53 | - QueueTypeWorker worker = QueueTypeWorker.find(this.serviceType); | |
| 54 | - if (worker != null && worker.getQueueSize() > 0) { | |
| 55 | - this.IS_READY_YN = true; | |
| 56 | - saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS READY ... ..."); | |
| 57 | - } else { | |
| 58 | - this.IS_READY_YN = false; | |
| 59 | - saveSystemLog("COLLECT_SERVER_SERVICE : QUEUE IS NOT READY ... ..."); | |
| 60 | - } | |
| 61 | - } | |
| 62 | - | |
| 63 | - @Override | |
| 64 | - public void initResources() { | |
| 65 | - try { | |
| 66 | - saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZING ... ..."); | |
| 67 | - initCollectChannel(); | |
| 68 | - threadService = new CollectThreadService(readMaxCore, this.serviceType, logger); | |
| 69 | - statusThreadService = new StatusThreadService(this.serviceType, this.logger); | |
| 70 | - saveSystemLog("COLLECT_SERVER_SERVICE : RESOURCES INITIALIZED ... ..."); | |
| 71 | - } catch (IOException e) { | |
| 72 | - saveSystemLog(e); | |
| 73 | - throw new RuntimeException(e); | |
| 74 | - } | |
| 75 | - } | |
| 76 | - | |
| 77 | - private void initCollectChannel() throws IOException { | |
| 78 | - saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZING ... ..."); | |
| 79 | - saveSystemLog("COLLECT_SERVER_SERVICE : SERVER PORT [" + listenAddress.getPort() + "]"); | |
| 80 | - selector = Selector.open(); | |
| 81 | - /* 채널 생성 */ | |
| 82 | - ServerSocketChannel serverChannel = ServerSocketChannel.open(); | |
| 83 | - /* non-Blocking 설정 */ | |
| 84 | - serverChannel.configureBlocking(false); | |
| 85 | - /* 서버 ip, port 설정 */ | |
| 86 | - serverChannel.socket().bind(listenAddress); | |
| 87 | - /* 채널에 accept 대기 설정 */ | |
| 88 | - serverChannel.register(selector, SelectionKey.OP_ACCEPT); | |
| 89 | - saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SOCKET INITIALIZED ... ..."); | |
| 90 | - } | |
| 91 | - | |
| 92 | - private void closeCollectChannel() throws IOException { | |
| 93 | - selector.close(); | |
| 94 | - } | |
| 95 | - | |
| 96 | - @Override | |
| 97 | - public void releaseResources() { | |
| 98 | - saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASING ... ..."); | |
| 99 | - try { | |
| 100 | - closeCollectChannel(); | |
| 101 | - threadService.close(); | |
| 102 | - statusThreadService.close(); | |
| 103 | - } catch (IOException e) { | |
| 104 | - saveSystemLog(e); | |
| 105 | - throw new RuntimeException(e); | |
| 106 | - } | |
| 107 | - saveSystemLog("COLLECT_SERVER_SERVICE : SERVER RESOURCE RELEASED ... ..."); | |
| 108 | - } | |
| 109 | - | |
| 110 | - @Override | |
| 111 | - public void doService() { | |
| 112 | - saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STARTED ... ..."); | |
| 113 | - while (isRun()) { | |
| 114 | - try { | |
| 115 | - execInterest(); | |
| 116 | - execUserStatus(); | |
| 117 | - } catch (Exception e) { | |
| 118 | - throw new RuntimeException(e); | |
| 119 | - } | |
| 120 | - } | |
| 121 | - saveSystemLog("COLLECT_SERVER_SERVICE : SERVER SERVICE STOPPED ... ..."); | |
| 122 | - } | |
| 123 | - | |
| 124 | - private void execInterest_bak() throws IOException { | |
| 125 | - if (selector.select(1000) == 0) { | |
| 126 | - return ; | |
| 127 | - } | |
| 128 | - Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); | |
| 129 | - while (keys.hasNext()) { | |
| 130 | - SelectionKey key = keys.next(); | |
| 131 | - /* 키 셋에서 제거. */ | |
| 132 | - keys.remove(); | |
| 133 | - | |
| 134 | - if (key.isValid()) { | |
| 135 | - if (key.isAcceptable()) { // 접속일 경우.. | |
| 136 | - saveSystemLog("CONNECTION IS ACCEPTABLE ... ..."); | |
| 137 | - accept(selector, key); | |
| 138 | - } else if (key.isReadable()) { // 수신일 경우.. | |
| 139 | - ConnectUserDto connectUserDto = (ConnectUserDto) key.attachment(); | |
| 140 | - if (connectUserDto == null || connectUserDto.isRunningMode()) { | |
| 141 | - continue; | |
| 142 | - } | |
| 143 | - threadService.execute(new SendReadTask(selector, key, this.serviceType, logger)); | |
| 144 | -// threadService.submit(selector, key, 2); | |
| 145 | - } | |
| 146 | - } else { | |
| 147 | - expireConnectUser(key); | |
| 148 | - } | |
| 149 | - } | |
| 150 | - } | |
| 151 | - | |
| 152 | - private void execInterest() throws IOException { | |
| 153 | - if (selector.select(1000) == 0) { | |
| 154 | - return ; | |
| 155 | - } | |
| 156 | - Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); | |
| 157 | - List<Future<ConnectUserDto>> list = new ArrayList<>(); | |
| 158 | - while (keys.hasNext()) { | |
| 159 | - SelectionKey key = keys.next(); | |
| 160 | - /* 키 셋에서 제거. */ | |
| 161 | - keys.remove(); | |
| 162 | - | |
| 163 | - if (key.isValid()) { | |
| 164 | - if (key.isAcceptable()) { // 접속일 경우.. | |
| 165 | - saveSystemLog("CONNECTION IS ACCEPTABLE ... ..."); | |
| 166 | - accept(selector, key); | |
| 167 | - } else if (key.isReadable()) { // 수신일 경우.. | |
| 168 | - Future<ConnectUserDto> future = threadService.submit(new CollectReadTask(selector, key, this.serviceType, logger)); | |
| 169 | - list.add(future); | |
| 170 | -// threadService.submit(selector, key, 2); | |
| 171 | - } | |
| 172 | - } else { | |
| 173 | - expireConnectUser(key); | |
| 174 | - } | |
| 175 | - } | |
| 176 | - for (Future<ConnectUserDto> future : list) { | |
| 177 | - ConnectUserDto connectUserDto = null; | |
| 178 | - try { | |
| 179 | - connectUserDto = future.get(); | |
| 180 | - } catch (InterruptedException e) { | |
| 181 | - } catch (ExecutionException e) { | |
| 182 | - } | |
| 183 | - | |
| 184 | - if (connectUserDto != null) { | |
| 185 | - saveSystemLog("[READ USER : " + connectUserDto.toString() + "]"); | |
| 186 | - } | |
| 187 | - } | |
| 188 | - } | |
| 189 | - | |
| 190 | - private void execUserStatus() throws IOException { | |
| 191 | - if (System.currentTimeMillis() - USER_STATUS_LAST_CHECK_TIME > USER_STATUS_CYCLE_TIME) { | |
| 192 | - statusThreadService.execute(new StatusCheckTask(this.serviceType, logger)); | |
| 193 | - USER_STATUS_LAST_CHECK_TIME = System.currentTimeMillis(); | |
| 194 | - } | |
| 195 | - } | |
| 196 | - | |
| 197 | - private void accept(Selector selector, SelectionKey key) { | |
| 198 | - try { | |
| 199 | - /* 키 채널을 가져온다. */ | |
| 200 | - ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); | |
| 201 | - /* accept을 해서 Socket 채널을 가져온다. */ | |
| 202 | - SocketChannel channel = serverChannel.accept(); | |
| 203 | - channel.configureBlocking(false); | |
| 204 | - /* 소켓 취득 */ | |
| 205 | - Socket socket = channel.socket(); | |
| 206 | - InetAddress inetAddress = socket.getInetAddress(); | |
| 207 | - saveSystemLog("[CLIENT CONNECTION IP : " + inetAddress.getHostAddress() + "]"); | |
| 208 | - // Socket 채널을 channel에 수신 등록한다 | |
| 209 | - channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().serviceType(this.serviceType).lastTrafficTime(System.currentTimeMillis()).remoteIP(inetAddress.getHostAddress()).build()); | |
| 210 | - } catch (Exception e) { | |
| 211 | - throw new RuntimeException(e); | |
| 212 | - } | |
| 213 | - } | |
| 214 | - | |
| 215 | - private void expireConnectUser(SelectionKey key) { | |
| 216 | - if (key == null || !key.isValid()) { | |
| 217 | - return; | |
| 218 | - } | |
| 219 | - try { | |
| 220 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 221 | - ConnectUserDto userDto = (ConnectUserDto) key.attachment(); | |
| 222 | - if (userDto != null && userDto.getUserId() != null) { | |
| 223 | - saveSystemLog("[CLIENT USER IS DISCONNECT : " + userDto.toString() + "]"); | |
| 224 | - collectUserQueue.removeUser(this.serviceType, userDto.getUserId()); | |
| 225 | -// connectUserMap.remove(userDto.getUserId()); | |
| 226 | - key.attach(null); | |
| 227 | - } | |
| 228 | - // 소켓 채널 닫기 | |
| 229 | - channel.close(); | |
| 230 | - // 키 닫기 | |
| 231 | - key.cancel(); | |
| 232 | - } catch (IOException e) { | |
| 233 | - e.printStackTrace(); | |
| 234 | - } | |
| 235 | - } | |
| 236 | - | |
| 237 | - @Override | |
| 238 | - public JSONObject monitorService() { | |
| 239 | - return null; | |
| 240 | - } | |
| 241 | - | |
| 242 | - private static class StatusThreadService { | |
| 243 | - @Getter | |
| 244 | - private String serviceType; | |
| 245 | - @Getter | |
| 246 | - private final int maxCore = 1; | |
| 247 | - private final ExecutorService executor; | |
| 248 | - private final LogUtil logger; | |
| 249 | - | |
| 250 | - public StatusThreadService(String serviceType, LogUtil logger) { | |
| 251 | - this.executor = Executors.newFixedThreadPool(maxCore); | |
| 252 | - this.logger = logger; | |
| 253 | - saveSystemLog("[STATUS_TASK_THREAD_POOL : " + maxCore + "]"); | |
| 254 | - } | |
| 255 | - | |
| 256 | - public void execute(StatusCheckTask statusCheckTask) { | |
| 257 | - executor.execute(statusCheckTask); | |
| 258 | - } | |
| 259 | - | |
| 260 | - private void saveSystemLog(Object obj) { | |
| 261 | - saveLog(obj, true); | |
| 262 | - } | |
| 263 | - | |
| 264 | - private void saveLog(Object obj) { | |
| 265 | - saveLog(obj, false); | |
| 266 | - } | |
| 267 | - | |
| 268 | - private void saveLog(Object obj, boolean isConsoleOutput) { | |
| 269 | - if (isConsoleOutput) { | |
| 270 | - System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{" + serviceType + "}} " + obj); | |
| 271 | - } | |
| 272 | - | |
| 273 | - if (logger == null) { | |
| 274 | - return; | |
| 275 | - } | |
| 276 | - | |
| 277 | - logger.log(obj); | |
| 278 | - } | |
| 279 | - | |
| 280 | - public void close() { | |
| 281 | - List<Runnable> unfinishedTasks = executor.shutdownNow(); | |
| 282 | - if (!unfinishedTasks.isEmpty()) { | |
| 283 | - saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size()); | |
| 284 | - } | |
| 285 | - } | |
| 286 | - } | |
| 287 | - | |
| 288 | - private static class CollectThreadService { | |
| 289 | - @Getter | |
| 290 | - private String serviceType; | |
| 291 | - @Getter | |
| 292 | - private final int maxCore; | |
| 293 | - private final ExecutorService executor; | |
| 294 | - private final LogUtil logger; | |
| 295 | - | |
| 296 | - public CollectThreadService(String serviceType, LogUtil logger) { | |
| 297 | - this(Runtime.getRuntime().availableProcessors(), serviceType, logger); | |
| 298 | - } | |
| 299 | - | |
| 300 | - public CollectThreadService(int maxCore, String serviceType, LogUtil logger) { | |
| 301 | - this.maxCore = maxCore; | |
| 302 | - this.executor = Executors.newFixedThreadPool(maxCore); | |
| 303 | - this.logger = logger; | |
| 304 | - saveSystemLog("[COLLECT_TASK_THREAD_POOL : " + maxCore + "]"); | |
| 305 | - } | |
| 306 | - | |
| 307 | - public Future<ConnectUserDto> submit(CollectReadTask collectReadTask) { | |
| 308 | - return executor.submit(collectReadTask); | |
| 309 | - } | |
| 310 | - | |
| 311 | - public void execute(SendReadTask sendReadTask) { | |
| 312 | - executor.execute(sendReadTask); | |
| 313 | - } | |
| 314 | - | |
| 315 | - private void saveSystemLog(Object obj) { | |
| 316 | - saveLog(obj, true); | |
| 317 | - } | |
| 318 | - | |
| 319 | - private void saveLog(Object obj) { | |
| 320 | - saveLog(obj, false); | |
| 321 | - } | |
| 322 | - | |
| 323 | - private void saveLog(Object obj, boolean isConsoleOutput) { | |
| 324 | - if (isConsoleOutput) { | |
| 325 | - System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{" + serviceType + "}} " + obj); | |
| 326 | - } | |
| 327 | - | |
| 328 | - if (logger == null) { | |
| 329 | - return; | |
| 330 | - } | |
| 331 | - | |
| 332 | - logger.log(obj); | |
| 333 | - } | |
| 334 | - | |
| 335 | - public void close() { | |
| 336 | - List<Runnable> unfinishedTasks = executor.shutdownNow(); | |
| 337 | - if (!unfinishedTasks.isEmpty()) { | |
| 338 | - saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size()); | |
| 339 | - } | |
| 340 | - } | |
| 341 | - } | |
| 342 | -} |
--- src/main/java/com/munjaon/server/server/service/ReportServer.java
+++ src/main/java/com/munjaon/server/server/service/ReportServer.java
... | ... | @@ -6,7 +6,6 @@ |
| 6 | 6 |
import com.munjaon.server.server.task.ReportBindTask; |
| 7 | 7 |
import com.munjaon.server.server.task.ReportLinkCheckTask; |
| 8 | 8 |
import com.munjaon.server.server.task.ReportResultTask; |
| 9 |
-import com.munjaon.server.server.task.ReportServerTask; |
|
| 10 | 9 |
import org.json.simple.JSONObject; |
| 11 | 10 |
|
| 12 | 11 |
import java.io.IOException; |
... | ... | @@ -17,10 +16,7 @@ |
| 17 | 16 |
import java.nio.channels.Selector; |
| 18 | 17 |
import java.nio.channels.ServerSocketChannel; |
| 19 | 18 |
import java.nio.channels.SocketChannel; |
| 20 |
-import java.util.ArrayList; |
|
| 21 | 19 |
import java.util.Iterator; |
| 22 |
-import java.util.List; |
|
| 23 |
-import java.util.concurrent.Future; |
|
| 24 | 20 |
|
| 25 | 21 |
public class ReportServer extends Service {
|
| 26 | 22 |
private final InetSocketAddress listenAddress; |
... | ... | @@ -135,44 +131,6 @@ |
| 135 | 131 |
} |
| 136 | 132 |
} |
| 137 | 133 |
|
| 138 |
- private void checkInterest_bak() throws IOException, InterruptedException {
|
|
| 139 |
- Iterator<SelectionKey> keys = selector.keys().iterator(); |
|
| 140 |
- while (keys.hasNext()) {
|
|
| 141 |
- SelectionKey key = keys.next(); |
|
| 142 |
- if (key.isValid()) {
|
|
| 143 |
- ReportUserDto reportUserDto = (ReportUserDto) key.attachment(); |
|
| 144 |
- if (reportUserDto == null) {
|
|
| 145 |
- continue; |
|
| 146 |
- } |
|
| 147 |
- if (reportUserDto.isAlive() == 1) { // 로그인이 완료되지 않은 경우
|
|
| 148 |
- expireConnectUser(key); |
|
| 149 |
- } else if (reportUserDto.isAlive() == 2) {
|
|
| 150 |
- if (reportUserDto.isRunningMode()) {
|
|
| 151 |
- continue; |
|
| 152 |
- } |
|
| 153 |
- /* 로그인이 된경우 Link Check를 위해 실행 */ |
|
| 154 |
- if (reportUserDto.isLogin()) {
|
|
| 155 |
- reportUserDto.setRunningMode(true); |
|
| 156 |
- /* 사용자별 Report Thread 실행 */ |
|
| 157 |
- new ReportServerTask(selector, key, getName(), logger).run(); |
|
| 158 |
- } |
|
| 159 |
- } else {
|
|
| 160 |
- ReportQueue reportQueue = reportUserDto.getReportQueue(); |
|
| 161 |
- if (reportUserDto.isLogin() && reportQueue != null && reportQueue.isRemainReport()) {
|
|
| 162 |
- if (reportUserDto.isRunningMode()) {
|
|
| 163 |
- continue; |
|
| 164 |
- } |
|
| 165 |
- reportUserDto.setRunningMode(true); |
|
| 166 |
- /* 사용자별 Report Thread 실행 */ |
|
| 167 |
- new ReportServerTask(selector, key, getName(), logger).start(); |
|
| 168 |
- } |
|
| 169 |
- } |
|
| 170 |
- } else {
|
|
| 171 |
- expireConnectUser(key); |
|
| 172 |
- } |
|
| 173 |
- } |
|
| 174 |
- } |
|
| 175 |
- |
|
| 176 | 134 |
private void bindInterest() throws IOException {
|
| 177 | 135 |
if (selector.select(300) == 0) {
|
| 178 | 136 |
return ; |
... | ... | @@ -206,35 +164,6 @@ |
| 206 | 164 |
} |
| 207 | 165 |
} |
| 208 | 166 |
|
| 209 |
- private void execInterest() throws IOException {
|
|
| 210 |
- if (selector.select(1000) == 0) {
|
|
| 211 |
- return ; |
|
| 212 |
- } |
|
| 213 |
- Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); |
|
| 214 |
- while (keys.hasNext()) {
|
|
| 215 |
- SelectionKey key = keys.next(); |
|
| 216 |
- /* 키 셋에서 제거. */ |
|
| 217 |
- keys.remove(); |
|
| 218 |
- |
|
| 219 |
- if (key.isValid()) {
|
|
| 220 |
- if (key.isAcceptable()) { // 접속일 경우..
|
|
| 221 |
- saveLog("CONNECTION IS ACCEPTABLE ... ...");
|
|
| 222 |
- accept(selector, key); |
|
| 223 |
- } else if (key.isReadable()) { // 수신일 경우..
|
|
| 224 |
- ReportUserDto reportUserDto = (ReportUserDto) key.attachment(); |
|
| 225 |
- if (reportUserDto == null || reportUserDto.isRunningMode()) {
|
|
| 226 |
- continue; |
|
| 227 |
- } |
|
| 228 |
- reportUserDto.setRunningMode(true); |
|
| 229 |
- /* 사용자별 Report Thread 실행 */ |
|
| 230 |
- new ReportServerTask(selector, key, getName(), logger).start(); |
|
| 231 |
- } |
|
| 232 |
- } else {
|
|
| 233 |
- expireConnectUser(key); |
|
| 234 |
- } |
|
| 235 |
- } |
|
| 236 |
- } |
|
| 237 |
- |
|
| 238 | 167 |
private void accept(Selector selector, SelectionKey key) {
|
| 239 | 168 |
try {
|
| 240 | 169 |
/* 키 채널을 가져온다. */ |
... | ... | @@ -264,7 +193,6 @@ |
| 264 | 193 |
saveLog("Expire connect user: " + userDto);
|
| 265 | 194 |
if (userDto != null && userDto.getUserId() != null) {
|
| 266 | 195 |
reportUserQueue.removeUser(userDto.getUserId()); |
| 267 |
-// connectUserMap.remove(userDto.getUserId()); |
|
| 268 | 196 |
key.attach(null); |
| 269 | 197 |
/* 모니터링 로그 */ |
| 270 | 198 |
HealthCheckServer.saveMonitorLog("[REPORT SERVER][ID : " + userDto.getUserId() + "][EXPIRE CONNECT USER]");
|
--- src/main/java/com/munjaon/server/server/service/ReportServerService.java
... | ... | @@ -1,296 +0,0 @@ |
| 1 | -package com.munjaon.server.server.service; | |
| 2 | - | |
| 3 | -import com.munjaon.server.queue.pool.ReportQueue; | |
| 4 | -import com.munjaon.server.server.dto.ConnectUserDto; | |
| 5 | -import com.munjaon.server.server.dto.ReportDto; | |
| 6 | -import com.munjaon.server.server.dto.ReportUserDto; | |
| 7 | -import com.munjaon.server.server.packet.common.Header; | |
| 8 | -import com.munjaon.server.server.packet.common.LinkCheck; | |
| 9 | -import com.munjaon.server.server.packet.common.Packet; | |
| 10 | -import com.munjaon.server.server.packet.common.Report; | |
| 11 | -import com.munjaon.server.server.queue.ReportUserQueue; | |
| 12 | -import com.munjaon.server.server.task.ReportReadTask; | |
| 13 | -import com.munjaon.server.util.LogUtil; | |
| 14 | -import lombok.Getter; | |
| 15 | -import org.json.simple.JSONObject; | |
| 16 | - | |
| 17 | -import java.io.File; | |
| 18 | -import java.io.IOException; | |
| 19 | -import java.net.InetSocketAddress; | |
| 20 | -import java.net.Socket; | |
| 21 | -import java.net.SocketAddress; | |
| 22 | -import java.nio.ByteBuffer; | |
| 23 | -import java.nio.channels.SelectionKey; | |
| 24 | -import java.nio.channels.Selector; | |
| 25 | -import java.nio.channels.ServerSocketChannel; | |
| 26 | -import java.nio.channels.SocketChannel; | |
| 27 | -import java.time.LocalDateTime; | |
| 28 | -import java.time.format.DateTimeFormatter; | |
| 29 | -import java.util.ArrayList; | |
| 30 | -import java.util.Iterator; | |
| 31 | -import java.util.List; | |
| 32 | -import java.util.concurrent.ExecutionException; | |
| 33 | -import java.util.concurrent.ExecutorService; | |
| 34 | -import java.util.concurrent.Executors; | |
| 35 | -import java.util.concurrent.Future; | |
| 36 | - | |
| 37 | -public class ReportServerService extends Service { | |
| 38 | - private final InetSocketAddress listenAddress; | |
| 39 | - private ReadThreadService threadService; | |
| 40 | - private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance(); | |
| 41 | - private Selector selector; | |
| 42 | - private int readMaxCore; | |
| 43 | - private int queueMaxCore; | |
| 44 | -// private long CHECKED_INTEREST_TIME = System.currentTimeMillis(); | |
| 45 | -// private final long LIMIT_CYCLE_TIME = 3000; | |
| 46 | - | |
| 47 | -// private final ByteBuffer reportBuffer = ByteBuffer.allocateDirect(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH); | |
| 48 | - | |
| 49 | - public ReportServerService(String serviceName, int port) { | |
| 50 | - super(serviceName); | |
| 51 | - this.readMaxCore = Integer.parseInt(getProp("READ_MAX_CORE").trim()); | |
| 52 | - this.queueMaxCore = Integer.parseInt(getProp("QUEUE_MAX_CORE").trim()); | |
| 53 | - this.listenAddress = new InetSocketAddress(port); | |
| 54 | - } | |
| 55 | - | |
| 56 | - @Override | |
| 57 | - public void checkReady() { | |
| 58 | - this.IS_READY_YN = true; | |
| 59 | - } | |
| 60 | - | |
| 61 | - @Override | |
| 62 | - public void initResources() { | |
| 63 | - try { | |
| 64 | - initReportChannel(); | |
| 65 | - threadService = new ReadThreadService(readMaxCore, logger); | |
| 66 | - } catch (IOException e) { | |
| 67 | - saveSystemLog(e); | |
| 68 | - throw new RuntimeException(e); | |
| 69 | - } | |
| 70 | - } | |
| 71 | - | |
| 72 | - private void initReportChannel() throws IOException { | |
| 73 | - selector = Selector.open(); | |
| 74 | - /* 채널 생성 */ | |
| 75 | - ServerSocketChannel serverChannel = ServerSocketChannel.open(); | |
| 76 | - /* non-Blocking 설정 */ | |
| 77 | - serverChannel.configureBlocking(false); | |
| 78 | - /* 서버 ip, port 설정 */ | |
| 79 | - serverChannel.socket().bind(listenAddress); | |
| 80 | - /* 채널에 accept 대기 설정 */ | |
| 81 | - serverChannel.register(selector, SelectionKey.OP_ACCEPT); | |
| 82 | - } | |
| 83 | - | |
| 84 | - private void closeReportChannel() throws IOException { | |
| 85 | - selector.close(); | |
| 86 | - } | |
| 87 | - | |
| 88 | - @Override | |
| 89 | - public void releaseResources() { | |
| 90 | - try { | |
| 91 | - closeReportChannel(); | |
| 92 | - threadService.close(); | |
| 93 | - } catch (IOException e) { | |
| 94 | - saveSystemLog(e); | |
| 95 | - throw new RuntimeException(e); | |
| 96 | - } | |
| 97 | - } | |
| 98 | - | |
| 99 | - @Override | |
| 100 | - public void doService() { | |
| 101 | - | |
| 102 | - while (isRun()) { | |
| 103 | - try { | |
| 104 | - execInterest(); | |
| 105 | - checkInterest(); | |
| 106 | - } catch (Exception e) { | |
| 107 | - saveSystemLog(e.toString()); | |
| 108 | - } | |
| 109 | - } | |
| 110 | - } | |
| 111 | - | |
| 112 | - private void checkInterest() throws IOException, InterruptedException { | |
| 113 | -// if (System.currentTimeMillis() - CHECKED_INTEREST_TIME < LIMIT_CYCLE_TIME) { | |
| 114 | -// return; | |
| 115 | -// } | |
| 116 | -// /* 체크시간 업데이트 */ | |
| 117 | -// CHECKED_INTEREST_TIME = System.currentTimeMillis(); | |
| 118 | - | |
| 119 | - Iterator<SelectionKey> keys = selector.keys().iterator(); | |
| 120 | - while (keys.hasNext()) { | |
| 121 | - SelectionKey key = keys.next(); | |
| 122 | - if (key.isValid()) { | |
| 123 | - ReportUserDto reportUserDto = (ReportUserDto) key.attachment(); | |
| 124 | - if (reportUserDto == null) { | |
| 125 | - continue; | |
| 126 | - } | |
| 127 | - SocketChannel channel = (SocketChannel) key.channel(); // 키 채널을 가져온다. | |
| 128 | - if (reportUserDto.isAlive() == 1) { | |
| 129 | - if (reportUserDto.getUserId() != null) { | |
| 130 | - reportUserQueue.removeUser(reportUserDto.getUserId()); | |
| 131 | - } | |
| 132 | - Socket socket = channel.socket(); // 소켓 취득 | |
| 133 | - channel.close(); // 소켓 채널 닫기 | |
| 134 | - socket.close(); // 소켓 닫기 | |
| 135 | - key.attach(null); // 키 닫기 | |
| 136 | - key.cancel(); | |
| 137 | - } else if (reportUserDto.isAlive() == 2) { | |
| 138 | - channel.write(LinkCheck.makeLinkCheckBuffer()); | |
| 139 | - } else { | |
| 140 | - if (reportUserDto.isLogin()) { | |
| 141 | - ReportQueue reportQueue = reportUserDto.getReportQueue(); | |
| 142 | - try { | |
| 143 | - ReportDto reportDto = reportQueue.popReportFromQueue(); | |
| 144 | - if (reportDto == null) { | |
| 145 | - continue; | |
| 146 | - } | |
| 147 | - saveSystemLog("reportQueue.popReportFromQueue() : " + reportDto.toString()); | |
| 148 | - ByteBuffer reportBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH); | |
| 149 | - Packet.setDefaultByte(reportBuffer); | |
| 150 | - Header.putHeader(reportBuffer, Header.COMMAND_REPORT, Report.REPORT_BODY_LENGTH); | |
| 151 | - Report.putReport(reportBuffer, reportDto); | |
| 152 | - channel.write(reportBuffer); | |
| 153 | - } catch (Exception e) { | |
| 154 | - e.printStackTrace(); | |
| 155 | - } | |
| 156 | - } | |
| 157 | - } | |
| 158 | - } else { | |
| 159 | - expireConnectUser(key); | |
| 160 | - } | |
| 161 | - } | |
| 162 | - } | |
| 163 | - | |
| 164 | - private void execInterest() throws IOException { | |
| 165 | - if (selector.select(1000) == 0) { | |
| 166 | - return ; | |
| 167 | - } | |
| 168 | - Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); | |
| 169 | - List<Future<ReportUserDto>> list = new ArrayList<>(); | |
| 170 | - while (keys.hasNext()) { | |
| 171 | - SelectionKey key = keys.next(); | |
| 172 | - /* 키 셋에서 제거. */ | |
| 173 | - keys.remove(); | |
| 174 | - | |
| 175 | - if (key.isValid()) { | |
| 176 | - if (key.isAcceptable()) { // 접속일 경우.. | |
| 177 | - saveSystemLog("isAcceptable"); | |
| 178 | - accept(selector, key); | |
| 179 | - } else if (key.isReadable()) { // 수신일 경우.. | |
| 180 | - saveSystemLog("isReadable"); | |
| 181 | - Future<ReportUserDto> future = threadService.submit(new ReportReadTask(selector, key, logger)); | |
| 182 | - list.add(future); | |
| 183 | -// threadService.submit(selector, key, 2); | |
| 184 | - } | |
| 185 | - } else { | |
| 186 | - expireConnectUser(key); | |
| 187 | - } | |
| 188 | - } | |
| 189 | - for (Future<ReportUserDto> future : list) { | |
| 190 | - ReportUserDto reportUserDto = null; | |
| 191 | - try { | |
| 192 | - reportUserDto = future.get(); | |
| 193 | - } catch (InterruptedException e) { | |
| 194 | - } catch (ExecutionException e) { | |
| 195 | - } | |
| 196 | - | |
| 197 | - if (reportUserDto == null) { | |
| 198 | - saveSystemLog("Future : " + future); | |
| 199 | - } else { | |
| 200 | - saveSystemLog("Future : " + reportUserDto.toString()); | |
| 201 | - } | |
| 202 | - } | |
| 203 | - } | |
| 204 | - | |
| 205 | - private void accept(Selector selector, SelectionKey key) { | |
| 206 | - try { | |
| 207 | - /* 키 채널을 가져온다. */ | |
| 208 | - ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); | |
| 209 | - /* accept을 해서 Socket 채널을 가져온다. */ | |
| 210 | - SocketChannel channel = serverChannel.accept(); | |
| 211 | - channel.configureBlocking(false); | |
| 212 | - /* 소켓 취득 */ | |
| 213 | - Socket socket = channel.socket(); | |
| 214 | - SocketAddress remoteAddr = socket.getRemoteSocketAddress(); | |
| 215 | - saveSystemLog("Connected to: " + remoteAddr); | |
| 216 | - // Socket 채널을 channel에 수신 등록한다 | |
| 217 | - channel.register(selector, SelectionKey.OP_READ, ReportUserDto.builder().lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).queuePath(System.getProperty("ROOTPATH") + File.separator + getProp("QUEUE_PATH")).build()); | |
| 218 | - } catch (Exception e) { | |
| 219 | - throw new RuntimeException(e); | |
| 220 | - } | |
| 221 | - } | |
| 222 | - | |
| 223 | - private void expireConnectUser(SelectionKey key) { | |
| 224 | - if (key == null || !key.isValid()) { | |
| 225 | - return; | |
| 226 | - } | |
| 227 | - try { | |
| 228 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 229 | - ConnectUserDto userDto = (ConnectUserDto) key.attachment(); | |
| 230 | - if (userDto != null && userDto.getUserId() != null) { | |
| 231 | - reportUserQueue.removeUser(userDto.getUserId()); | |
| 232 | -// connectUserMap.remove(userDto.getUserId()); | |
| 233 | - key.attach(null); | |
| 234 | - } | |
| 235 | - // 소켓 채널 닫기 | |
| 236 | - channel.close(); | |
| 237 | - // 키 닫기 | |
| 238 | - key.cancel(); | |
| 239 | - } catch (IOException e) { | |
| 240 | - e.printStackTrace(); | |
| 241 | - } | |
| 242 | - } | |
| 243 | - | |
| 244 | - @Override | |
| 245 | - public JSONObject monitorService() { | |
| 246 | - return null; | |
| 247 | - } | |
| 248 | - | |
| 249 | - private static class ReadThreadService { | |
| 250 | - @Getter | |
| 251 | - private final int maxCore; | |
| 252 | - private final ExecutorService executor; | |
| 253 | - private ReportUserQueue reportUserQueue = ReportUserQueue.getInstance(); | |
| 254 | - private final LogUtil logger; | |
| 255 | - | |
| 256 | - public ReadThreadService(LogUtil logger) { | |
| 257 | - this(Runtime.getRuntime().availableProcessors(), logger); | |
| 258 | - } | |
| 259 | - | |
| 260 | - public ReadThreadService(int maxCore, LogUtil logger) { | |
| 261 | - this.maxCore = maxCore; | |
| 262 | - this.executor = Executors.newFixedThreadPool(maxCore); | |
| 263 | - this.logger = logger; | |
| 264 | - } | |
| 265 | - | |
| 266 | - public Future<ReportUserDto> submit(ReportReadTask reportReadTask) { | |
| 267 | - return executor.submit(reportReadTask); | |
| 268 | - } | |
| 269 | - private void saveSystemLog(Object obj) { | |
| 270 | - saveLog(obj, true); | |
| 271 | - } | |
| 272 | - | |
| 273 | - private void saveLog(Object obj) { | |
| 274 | - saveLog(obj, false); | |
| 275 | - } | |
| 276 | - | |
| 277 | - private void saveLog(Object obj, boolean isConsoleOutput) { | |
| 278 | - if (isConsoleOutput) { | |
| 279 | - System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{ReporterThreadService}} " + obj); | |
| 280 | - } | |
| 281 | - | |
| 282 | - if (logger == null) { | |
| 283 | - return; | |
| 284 | - } | |
| 285 | - | |
| 286 | - logger.log(obj); | |
| 287 | - } | |
| 288 | - | |
| 289 | - public void close() { | |
| 290 | - List<Runnable> unfinishedTasks = executor.shutdownNow(); | |
| 291 | - if (!unfinishedTasks.isEmpty()) { | |
| 292 | - saveSystemLog("Not all tasks finished before calling close: " + unfinishedTasks.size()); | |
| 293 | - } | |
| 294 | - } | |
| 295 | - } | |
| 296 | -} |
--- src/main/java/com/munjaon/server/server/service/Server.java
... | ... | @@ -1,117 +0,0 @@ |
| 1 | -package com.munjaon.server.server.service; | |
| 2 | - | |
| 3 | -import com.munjaon.server.server.config.ServerConfig; | |
| 4 | -import com.munjaon.server.server.dto.ConnectUserDto; | |
| 5 | - | |
| 6 | -import java.io.IOException; | |
| 7 | -import java.net.InetSocketAddress; | |
| 8 | -import java.net.Socket; | |
| 9 | -import java.net.SocketAddress; | |
| 10 | -import java.nio.channels.SelectionKey; | |
| 11 | -import java.nio.channels.Selector; | |
| 12 | -import java.nio.channels.ServerSocketChannel; | |
| 13 | -import java.nio.channels.SocketChannel; | |
| 14 | -import java.util.Iterator; | |
| 15 | - | |
| 16 | -public abstract class Server { | |
| 17 | - private InetSocketAddress listenAddress; | |
| 18 | - private Selector selector; | |
| 19 | - /* 마지막 통신 시간 */ | |
| 20 | - private Long lastTrafficCheckTime = System.currentTimeMillis(); | |
| 21 | - | |
| 22 | - private Server(InetSocketAddress listenAddress) { | |
| 23 | - this.listenAddress = listenAddress; | |
| 24 | - } | |
| 25 | - | |
| 26 | - protected Server(String address, int port) throws IOException { | |
| 27 | - this(new InetSocketAddress(address, port)); | |
| 28 | - selector = Selector.open(); | |
| 29 | - /* 채널 생성 */ | |
| 30 | - ServerSocketChannel serverChannel = ServerSocketChannel.open(); | |
| 31 | - /* non-Blocking 설정 */ | |
| 32 | - serverChannel.configureBlocking(false); | |
| 33 | - /* 서버 ip, port 설정 */ | |
| 34 | - serverChannel.socket().bind(listenAddress); | |
| 35 | - /* 채널에 accept 대기 설정 */ | |
| 36 | - serverChannel.register(selector, SelectionKey.OP_ACCEPT); | |
| 37 | - } | |
| 38 | - | |
| 39 | - protected Iterator<SelectionKey> selectInterest() throws IOException { | |
| 40 | - if (selector.select(1000) == 0) { | |
| 41 | - return null; | |
| 42 | - } | |
| 43 | - | |
| 44 | - return selector.selectedKeys().iterator(); | |
| 45 | - } | |
| 46 | - | |
| 47 | - protected void execInterest(Iterator<SelectionKey> keys) throws IOException { | |
| 48 | - while (keys != null && keys.hasNext()) { | |
| 49 | - SelectionKey key = keys.next(); | |
| 50 | - /* 키 셋에서 제거. */ | |
| 51 | - keys.remove(); | |
| 52 | - if (!key.isValid()) { | |
| 53 | - continue; | |
| 54 | - } | |
| 55 | - | |
| 56 | - if (key.isAcceptable()) { // 접속일 경우.. | |
| 57 | - this.accept(selector, key); | |
| 58 | - } else if (key.isReadable()) { // 수신일 경우.. | |
| 59 | - this.receive(selector, key); | |
| 60 | - } else if (key.isWritable()) { // 발신일 경우.. | |
| 61 | - this.send(selector, key); | |
| 62 | - } | |
| 63 | - } | |
| 64 | - } | |
| 65 | - | |
| 66 | - protected void accept(Selector selector, SelectionKey key) throws IOException { | |
| 67 | - /* 키 채널을 가져온다. */ | |
| 68 | - ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); | |
| 69 | - /* accept을 해서 Socket 채널을 가져온다. */ | |
| 70 | - SocketChannel channel = serverChannel.accept(); | |
| 71 | - channel.configureBlocking(false); | |
| 72 | - /* 소켓 취득 */ | |
| 73 | - Socket socket = channel.socket(); | |
| 74 | - SocketAddress remoteAddr = socket.getRemoteSocketAddress(); | |
| 75 | - System.out.println("Connected to: " + remoteAddr); | |
| 76 | - // Socket 채널을 channel에 수신 등록한다 | |
| 77 | - channel.register(selector, SelectionKey.OP_READ, ConnectUserDto.builder().lastTrafficTime(System.currentTimeMillis()).remoteIP(remoteAddr.toString()).build()); | |
| 78 | - } | |
| 79 | - | |
| 80 | - protected void checkInterest() throws IOException { | |
| 81 | - if (lastTrafficCheckTime - System.currentTimeMillis() < ServerConfig.CYCLE_SOCKET_TIMEOUT) { | |
| 82 | - return; | |
| 83 | - } | |
| 84 | - Iterator<SelectionKey> keys = selector.keys().iterator(); | |
| 85 | - while (keys.hasNext()) { | |
| 86 | - SelectionKey key = keys.next(); | |
| 87 | - if (key.interestOps() == SelectionKey.OP_READ) { | |
| 88 | - ConnectUserDto userDto = (ConnectUserDto) key.attachment(); | |
| 89 | - | |
| 90 | - if (userDto != null) { | |
| 91 | - if (userDto.isAlive() != 0) { | |
| 92 | - System.out.println("userDto is disconnet"); | |
| 93 | - // 키 채널을 가져온다. | |
| 94 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 95 | - // 소켓 취득 | |
| 96 | - Socket socket = channel.socket(); | |
| 97 | - // 소켓 채널 닫기 | |
| 98 | - channel.close(); | |
| 99 | - // 소켓 닫기 | |
| 100 | - socket.close(); | |
| 101 | - // 키 닫기 | |
| 102 | - key.attach(null); | |
| 103 | - key.cancel(); | |
| 104 | - } | |
| 105 | - } | |
| 106 | - } | |
| 107 | - } | |
| 108 | - lastTrafficCheckTime = System.currentTimeMillis(); | |
| 109 | - } | |
| 110 | - | |
| 111 | - protected void releaseServer() throws IOException { | |
| 112 | - selector.close(); | |
| 113 | - } | |
| 114 | - | |
| 115 | - protected abstract void receive(Selector selector, SelectionKey key) throws IOException; | |
| 116 | - protected abstract void send(Selector selector, SelectionKey key) throws IOException; | |
| 117 | -} |
--- src/main/java/com/munjaon/server/server/task/CollectReadTask.java
... | ... | @@ -1,572 +0,0 @@ |
| 1 | -package com.munjaon.server.server.task; | |
| 2 | - | |
| 3 | -import com.munjaon.server.cache.dto.MemberDto; | |
| 4 | -import com.munjaon.server.cache.enums.CacheService; | |
| 5 | -import com.munjaon.server.cache.service.MemberService; | |
| 6 | -import com.munjaon.server.queue.dto.BasicMessageDto; | |
| 7 | -import com.munjaon.server.queue.enums.QueueTypeWorker; | |
| 8 | -import com.munjaon.server.server.dto.ConnectUserDto; | |
| 9 | -import com.munjaon.server.server.packet.common.*; | |
| 10 | -import com.munjaon.server.server.queue.CollectUserQueue; | |
| 11 | -import com.munjaon.server.util.*; | |
| 12 | - | |
| 13 | -import java.io.File; | |
| 14 | -import java.io.IOException; | |
| 15 | -import java.io.UnsupportedEncodingException; | |
| 16 | -import java.nio.ByteBuffer; | |
| 17 | -import java.nio.channels.SelectionKey; | |
| 18 | -import java.nio.channels.Selector; | |
| 19 | -import java.nio.channels.SocketChannel; | |
| 20 | -import java.text.SimpleDateFormat; | |
| 21 | -import java.time.LocalDateTime; | |
| 22 | -import java.time.format.DateTimeFormatter; | |
| 23 | -import java.util.concurrent.Callable; | |
| 24 | - | |
| 25 | -public class CollectReadTask implements Callable<ConnectUserDto> { | |
| 26 | - public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]"); | |
| 27 | - public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]"; | |
| 28 | - | |
| 29 | - private Selector selector; | |
| 30 | - private SelectionKey key; | |
| 31 | - private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); | |
| 32 | - private ConnectUserDto connectUserDto; | |
| 33 | - private String serviceType; | |
| 34 | - private final LogUtil logger; | |
| 35 | - | |
| 36 | - public CollectReadTask(Selector selector, SelectionKey key, String serviceType, LogUtil logger) { | |
| 37 | - this.selector = selector; | |
| 38 | - this.key = key; | |
| 39 | - this.connectUserDto = (ConnectUserDto) key.attachment(); | |
| 40 | - this.serviceType = serviceType; | |
| 41 | - this.logger = logger; | |
| 42 | - } | |
| 43 | - | |
| 44 | - @Override | |
| 45 | - public ConnectUserDto call() throws Exception { | |
| 46 | - int size = -1; | |
| 47 | - try { | |
| 48 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 49 | - /* 1. Head 읽기 */ | |
| 50 | - ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); | |
| 51 | - try { | |
| 52 | - size = channel.read(headBuffer); | |
| 53 | - } catch (IOException e) {} | |
| 54 | - /* 2. Body 읽기 */ | |
| 55 | - if (size > 0) { | |
| 56 | -// Packet.printBuffer(headBuffer); | |
| 57 | - String command = Header.getCommand(headBuffer); | |
| 58 | - switch (Integer.parseInt(command)) { | |
| 59 | - case 1 : recvBind(channel, headBuffer); break; | |
| 60 | - case 3 : recvDeliver(channel, headBuffer); break; | |
| 61 | - case 7 : recvLinkCheck(channel); break; | |
| 62 | - default: expireConnectUser(); break; | |
| 63 | - } | |
| 64 | - } else { | |
| 65 | - expireConnectUser(); | |
| 66 | - } | |
| 67 | - } catch (Exception e) { | |
| 68 | - size = -1; | |
| 69 | - e.printStackTrace(); | |
| 70 | - } | |
| 71 | - | |
| 72 | - /* 읽은 데이터가 없는 경우 command -1 */ | |
| 73 | - if (size <= 0) { | |
| 74 | - connectUserDto.setCommand(-1); | |
| 75 | - } | |
| 76 | - | |
| 77 | - return connectUserDto; | |
| 78 | - } | |
| 79 | - | |
| 80 | - private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 81 | - /* 서비스 중지여부 체크 */ | |
| 82 | - if (isExpireService()) { | |
| 83 | - expireConnectUser(); | |
| 84 | - return; | |
| 85 | - } | |
| 86 | - switch (this.serviceType) { | |
| 87 | - case "SMS": | |
| 88 | - recvSmsDeliver(channel, headBuffer); | |
| 89 | - break; | |
| 90 | - case "LMS": | |
| 91 | - recvLmsDeliver(channel, headBuffer); | |
| 92 | - break; | |
| 93 | - case "MMS": | |
| 94 | - recvMmsDeliver(channel, headBuffer); | |
| 95 | - break; | |
| 96 | - case "KAT": | |
| 97 | - recvKatDeliver(channel, headBuffer); | |
| 98 | - break; | |
| 99 | - case "KFT": | |
| 100 | - recvKftDeliver(channel, headBuffer); | |
| 101 | - break; | |
| 102 | - default:break; | |
| 103 | - } | |
| 104 | - } | |
| 105 | - | |
| 106 | - private boolean isExpireService() { | |
| 107 | - ConnectUserDto checkConnectUserDto = collectUserQueue.getUser(this.serviceType, this.connectUserDto.getUserId()); | |
| 108 | - MemberDto memberDto = checkConnectUserDto.getMemberDto(); | |
| 109 | - saveSystemLog("[isExpireService : " + memberDto.toString() + "]"); | |
| 110 | - if (memberDto == null) { | |
| 111 | - return true; | |
| 112 | - } | |
| 113 | - if (collectUserQueue.isExist(this.serviceType, memberDto.getMberId()) == false) { | |
| 114 | - return true; | |
| 115 | - } | |
| 116 | - /* 회원 사용 상태 */ | |
| 117 | - if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { | |
| 118 | - return true; | |
| 119 | - } | |
| 120 | - /* 서비스 이용 상태 */ | |
| 121 | - if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { | |
| 122 | - return true; | |
| 123 | - } | |
| 124 | - if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { | |
| 125 | - return true; | |
| 126 | - } | |
| 127 | - if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { | |
| 128 | - return true; | |
| 129 | - } | |
| 130 | - if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { | |
| 131 | - return true; | |
| 132 | - } | |
| 133 | - if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { | |
| 134 | - return true; | |
| 135 | - } | |
| 136 | - | |
| 137 | - return false; | |
| 138 | - } | |
| 139 | - | |
| 140 | - public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) throws UnsupportedEncodingException { | |
| 141 | - if (deliverBuffer == null) { | |
| 142 | - return null; | |
| 143 | - } | |
| 144 | - BasicMessageDto messageDto = new BasicMessageDto(); | |
| 145 | - messageDto.setRouterSeq("40"); | |
| 146 | - messageDto.setServiceType("4"); | |
| 147 | - messageDto.setUserId(connectUserDto.getUserId()); | |
| 148 | - messageDto.setRemoteIP(connectUserDto.getRemoteIP()); | |
| 149 | - messageDto.setSendStatus("0"); | |
| 150 | - messageDto.setUserMsgID(CommonMessage.getMessageIdForDeliver(deliverBuffer)); | |
| 151 | - messageDto.setUserSender(CommonMessage.getSenderForDeliver(deliverBuffer)); | |
| 152 | - messageDto.setUserReceiver(CommonMessage.getReceiverForDeliver(deliverBuffer)); | |
| 153 | - messageDto.setReserveDt(CommonMessage.getReserveTimeForDeliver(deliverBuffer)); | |
| 154 | - messageDto.setRequestDt(CommonMessage.getRequestTimeForDeliver(deliverBuffer)); | |
| 155 | - messageDto.setUnitCost("10.4"); | |
| 156 | - | |
| 157 | - return messageDto; | |
| 158 | - } | |
| 159 | - | |
| 160 | - private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 161 | - try { | |
| 162 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH); | |
| 163 | - channel.read(bodyBuffer); | |
| 164 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + SmsMessage.DELIVER_SMS_BODY_LENGTH); | |
| 165 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 166 | - | |
| 167 | -// Packet.printBuffer(deliverBuffer); | |
| 168 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 169 | - messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer)); | |
| 170 | - | |
| 171 | - /* 사용자 단가, 발송망 설정 */ | |
| 172 | - MemberDto savedMemberDto = null; | |
| 173 | - if (this.connectUserDto != null) { | |
| 174 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 175 | - } | |
| 176 | - if (savedMemberDto != null) { | |
| 177 | - messageDto.setRouterSeq(savedMemberDto.getSmsAgentCode()); | |
| 178 | - messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice())); | |
| 179 | - } | |
| 180 | - | |
| 181 | - saveLog("[SMS] [MESSAGE : " + messageDto.toString() + "]"); | |
| 182 | - QueueTypeWorker worker = QueueTypeWorker.find("SMS"); | |
| 183 | - if (worker != null) { | |
| 184 | - worker.pushQueue(messageDto); | |
| 185 | - channel.write(SmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 186 | - } | |
| 187 | - } catch (Exception e) { | |
| 188 | - e.printStackTrace(); | |
| 189 | - } | |
| 190 | - } | |
| 191 | - | |
| 192 | - private void recvLmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 193 | - try { | |
| 194 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(LmsMessage.DELIVER_LMS_BODY_LENGTH); | |
| 195 | - channel.read(bodyBuffer); | |
| 196 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + LmsMessage.DELIVER_LMS_BODY_LENGTH); | |
| 197 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 198 | - | |
| 199 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 200 | - messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer)); | |
| 201 | - messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer)); | |
| 202 | - | |
| 203 | - /* 사용자 단가, 발송망 설정 */ | |
| 204 | - MemberDto savedMemberDto = null; | |
| 205 | - if (this.connectUserDto != null) { | |
| 206 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 207 | - } | |
| 208 | - if (savedMemberDto != null) { | |
| 209 | - messageDto.setRouterSeq(savedMemberDto.getLmsAgentCode()); | |
| 210 | - messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice())); | |
| 211 | - } | |
| 212 | - | |
| 213 | - saveLog("[LMS] [MESSAGE : " + messageDto.toString() + "]"); | |
| 214 | - QueueTypeWorker worker = QueueTypeWorker.find("LMS"); | |
| 215 | - if (worker != null) { | |
| 216 | - worker.pushQueue(messageDto); | |
| 217 | - channel.write(LmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 218 | - } | |
| 219 | - } catch (Exception e) { | |
| 220 | - e.printStackTrace(); | |
| 221 | - } | |
| 222 | - } | |
| 223 | - | |
| 224 | - private void recvMmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 225 | - try { | |
| 226 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_BODY_LENGTH); | |
| 227 | - channel.read(bodyBuffer); | |
| 228 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + MmsMessage.DELIVER_MMS_BODY_LENGTH); | |
| 229 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 230 | - | |
| 231 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 232 | - messageDto.setUserSubject(MmsMessage.getSubjectForDeliver(deliverBuffer)); | |
| 233 | - messageDto.setUserMessage(MmsMessage.getMessageForDeliver(deliverBuffer)); | |
| 234 | - String fileCount = MessageUtil.doNumber(MmsMessage.getFileCountForDeliver(deliverBuffer)); | |
| 235 | - int recvFileCount = 0; | |
| 236 | - if (fileCount != null && fileCount.length() > 0) { | |
| 237 | - recvFileCount = Integer.parseInt(fileCount); | |
| 238 | - messageDto.setUserFileCnt(recvFileCount); | |
| 239 | - } | |
| 240 | - | |
| 241 | - String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile"; | |
| 242 | - imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); | |
| 243 | - FileUtil.mkdirs(imagePath); | |
| 244 | - | |
| 245 | - for (int i = 0; i < recvFileCount; i++) { | |
| 246 | - ByteBuffer fileHeadBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_FILENAME_LENGTH + MmsMessage.DELIVER_MMS_FILESIZE_LENGTH); | |
| 247 | - channel.read(fileHeadBuffer); | |
| 248 | - String fileName = MmsMessage.getFileNameForDeliver(fileHeadBuffer); | |
| 249 | - String fileSize = MmsMessage.getFileSizeForDeliver(fileHeadBuffer); | |
| 250 | - ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); | |
| 251 | - channel.read(fileBuffer); | |
| 252 | - fileBuffer.flip(); | |
| 253 | - JobFileFactory.saveFileForByteBuffer(imagePath, fileName, fileBuffer); | |
| 254 | - if (i == 0) { | |
| 255 | - messageDto.setUserFileName01(imagePath + File.separator + fileName); | |
| 256 | - } else if (i == 1) { | |
| 257 | - messageDto.setUserFileName02(imagePath + File.separator + fileName); | |
| 258 | - } else if (i == 2) { | |
| 259 | - messageDto.setUserFileName03(imagePath + File.separator + fileName); | |
| 260 | - } | |
| 261 | - saveLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]"); | |
| 262 | - } | |
| 263 | - | |
| 264 | - /* 사용자 단가, 발송망 설정 */ | |
| 265 | - MemberDto savedMemberDto = null; | |
| 266 | - if (this.connectUserDto != null) { | |
| 267 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 268 | - } | |
| 269 | - if (savedMemberDto != null) { | |
| 270 | - messageDto.setRouterSeq(savedMemberDto.getMmsAgentCode()); | |
| 271 | - float mmsPrice = 0.0F; | |
| 272 | - if (recvFileCount == 1) { | |
| 273 | - mmsPrice = savedMemberDto.getPicturePrice(); | |
| 274 | - } else if (recvFileCount == 2) { | |
| 275 | - mmsPrice = savedMemberDto.getPicture2Price(); | |
| 276 | - } else { | |
| 277 | - mmsPrice = savedMemberDto.getPicture3Price(); | |
| 278 | - } | |
| 279 | - messageDto.setUnitCost(String.valueOf(mmsPrice)); | |
| 280 | - } | |
| 281 | - | |
| 282 | - saveLog("[MMS] [MESSAGE : " + messageDto.toString() + "]"); | |
| 283 | - QueueTypeWorker worker = QueueTypeWorker.find("MMS"); | |
| 284 | - if (worker != null) { | |
| 285 | - worker.pushQueue(messageDto); | |
| 286 | - channel.write(MmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 287 | - } | |
| 288 | - } catch (Exception e) { | |
| 289 | - e.printStackTrace(); | |
| 290 | - } | |
| 291 | - } | |
| 292 | - | |
| 293 | - private void recvKatDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 294 | - try { | |
| 295 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); | |
| 296 | - channel.read(bodyBuffer); | |
| 297 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); | |
| 298 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 299 | - | |
| 300 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 301 | - messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer)); | |
| 302 | - messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer)); | |
| 303 | - messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); | |
| 304 | - messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); | |
| 305 | - | |
| 306 | - String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; | |
| 307 | - jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); | |
| 308 | - FileUtil.mkdirs(jsonPath); | |
| 309 | - | |
| 310 | - ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH); | |
| 311 | - channel.read(fileHeadBuffer); | |
| 312 | - | |
| 313 | - String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer); | |
| 314 | - String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer); | |
| 315 | - | |
| 316 | - ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); | |
| 317 | - channel.read(fileBuffer); | |
| 318 | - fileBuffer.flip(); | |
| 319 | - JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); | |
| 320 | - | |
| 321 | - messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); | |
| 322 | - saveLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); | |
| 323 | - | |
| 324 | - /* 사용자 단가, 발송망 설정 */ | |
| 325 | - MemberDto savedMemberDto = null; | |
| 326 | - if (this.connectUserDto != null) { | |
| 327 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 328 | - } | |
| 329 | - if (savedMemberDto != null) { | |
| 330 | - messageDto.setRouterSeq(savedMemberDto.getKakaoAtAgentCode()); | |
| 331 | - messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice())); | |
| 332 | - } | |
| 333 | - | |
| 334 | - saveLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]"); | |
| 335 | - QueueTypeWorker worker = QueueTypeWorker.find("KAT"); | |
| 336 | - if (worker != null) { | |
| 337 | - worker.pushQueue(messageDto); | |
| 338 | - channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 339 | - } else { | |
| 340 | - saveLog("worker is null"); | |
| 341 | - } | |
| 342 | - } catch (Exception e) { | |
| 343 | - e.printStackTrace(); | |
| 344 | - } | |
| 345 | - } | |
| 346 | - | |
| 347 | - private void recvKftDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 348 | - try { | |
| 349 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); | |
| 350 | - channel.read(bodyBuffer); | |
| 351 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); | |
| 352 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 353 | - | |
| 354 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 355 | - messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer)); | |
| 356 | - messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer)); | |
| 357 | - messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); | |
| 358 | - messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); | |
| 359 | - | |
| 360 | - String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; | |
| 361 | - jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); | |
| 362 | - FileUtil.mkdirs(jsonPath); | |
| 363 | - | |
| 364 | - ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH); | |
| 365 | - channel.read(fileHeadBuffer); | |
| 366 | - | |
| 367 | - String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer); | |
| 368 | - String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer); | |
| 369 | - | |
| 370 | - ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); | |
| 371 | - channel.read(fileBuffer); | |
| 372 | - fileBuffer.flip(); | |
| 373 | - JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); | |
| 374 | - | |
| 375 | - messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); | |
| 376 | - saveLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); | |
| 377 | - | |
| 378 | - /* 사용자 단가, 발송망 설정 */ | |
| 379 | - MemberDto savedMemberDto = null; | |
| 380 | - if (this.connectUserDto != null) { | |
| 381 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 382 | - } | |
| 383 | - if (savedMemberDto != null) { | |
| 384 | - messageDto.setRouterSeq(savedMemberDto.getKakaoFtAgentCode()); | |
| 385 | - messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice())); | |
| 386 | - } | |
| 387 | - | |
| 388 | - saveLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]"); | |
| 389 | - QueueTypeWorker worker = QueueTypeWorker.find("KFT"); | |
| 390 | - if (worker != null) { | |
| 391 | - worker.pushQueue(messageDto); | |
| 392 | - channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 393 | - } | |
| 394 | - } catch (Exception e) { | |
| 395 | - e.printStackTrace(); | |
| 396 | - } | |
| 397 | - } | |
| 398 | - | |
| 399 | - private void recvLinkCheck(SocketChannel channel) throws IOException { | |
| 400 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH); | |
| 401 | - channel.read(bodyBuffer); | |
| 402 | -// SocketChannel channel = (SocketChannel) key.channel(); | |
| 403 | - channel.write(LinkCheck.makeLinkCheckAckBuffer()); | |
| 404 | - /* 서비스 중지여부 체크 */ | |
| 405 | - if (isExpireService()) { | |
| 406 | - expireConnectUser(); | |
| 407 | - return; | |
| 408 | - } | |
| 409 | - } | |
| 410 | - | |
| 411 | - private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { | |
| 412 | - String resultCode = "00"; | |
| 413 | - try { | |
| 414 | - ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); | |
| 415 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); | |
| 416 | - channel.read(bodyBuffer); | |
| 417 | - Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer); | |
| 418 | - | |
| 419 | - String id = Bind.getBindId(bindBuffer); | |
| 420 | - String pwd = Bind.getBindPwd(bindBuffer); | |
| 421 | - | |
| 422 | - MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); | |
| 423 | - MemberDto memberDto = null; | |
| 424 | - if (svc != null) { | |
| 425 | - memberDto = svc.get(id); | |
| 426 | - } | |
| 427 | - saveLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); | |
| 428 | - /* Bind Check */ | |
| 429 | - resultCode = checkBind(memberDto, this.serviceType, id, pwd); | |
| 430 | - | |
| 431 | - /* 접속 IP 체크 */ | |
| 432 | - if ("00".equals(resultCode)) { | |
| 433 | - boolean isPermit = false; | |
| 434 | - if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { | |
| 435 | - saveLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP()); | |
| 436 | - saveLog("Customize Toolbar... : " + memberDto.getAllowIpBasic()); | |
| 437 | - saveLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend()); | |
| 438 | - if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { | |
| 439 | - isPermit = true; | |
| 440 | - } | |
| 441 | - if (memberDto.getAllowIpExtend() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) { | |
| 442 | - isPermit = true; | |
| 443 | - } | |
| 444 | - } else { | |
| 445 | - isPermit = true; | |
| 446 | - } | |
| 447 | - if (isPermit) { | |
| 448 | - resultCode = "00"; | |
| 449 | - } else { | |
| 450 | - resultCode = "40"; | |
| 451 | - } | |
| 452 | - } | |
| 453 | - if ("00".equals(resultCode)) { | |
| 454 | - connectUserDto.setUserId(id); | |
| 455 | - connectUserDto.setLogin(true); | |
| 456 | - connectUserDto.setMemberDto(memberDto); | |
| 457 | - /* 사용자 Pool에 저장 */ | |
| 458 | - collectUserQueue.putUser(this.serviceType, connectUserDto); | |
| 459 | - /* 세션통신 시간 업데이트 */ | |
| 460 | - connectUserDto.updateLastTrafficTime(); | |
| 461 | - } | |
| 462 | - } catch (Exception e) { | |
| 463 | - resultCode = "10"; | |
| 464 | - e.printStackTrace(); | |
| 465 | - } | |
| 466 | - | |
| 467 | - try { | |
| 468 | - saveLog("[BIND RESULT : " + resultCode + "]"); | |
| 469 | - channel.write(Bind.makeBindAckBuffer(resultCode)); | |
| 470 | - if ("00".equals(resultCode) == false) { | |
| 471 | - expireConnectUser(); | |
| 472 | - } | |
| 473 | - } catch (IOException e) { | |
| 474 | - e.printStackTrace(); | |
| 475 | - } | |
| 476 | - } | |
| 477 | - | |
| 478 | - private String checkBind(MemberDto memberDto, String serviceType, String id, String pwd) { | |
| 479 | - if (id == null || pwd == null) { | |
| 480 | - return "50"; | |
| 481 | - } | |
| 482 | - if (collectUserQueue.isExist(this.serviceType, id)) { | |
| 483 | - return "60"; | |
| 484 | - } | |
| 485 | - if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { | |
| 486 | - return "20"; | |
| 487 | - } | |
| 488 | - /* 회원 사용 상태 */ | |
| 489 | - if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { | |
| 490 | - return "30"; | |
| 491 | - } | |
| 492 | - /* 서비스 이용 상태 */ | |
| 493 | - if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { | |
| 494 | - return "30"; | |
| 495 | - } | |
| 496 | - if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { | |
| 497 | - return "30"; | |
| 498 | - } | |
| 499 | - if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { | |
| 500 | - return "30"; | |
| 501 | - } | |
| 502 | - if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { | |
| 503 | - return "30"; | |
| 504 | - } | |
| 505 | - if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { | |
| 506 | - return "30"; | |
| 507 | - } | |
| 508 | - | |
| 509 | - return "00"; | |
| 510 | - } | |
| 511 | - | |
| 512 | - private String checkService(MemberDto memberDto, String serviceType) { | |
| 513 | - if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { | |
| 514 | - return "30"; | |
| 515 | - } | |
| 516 | - if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { | |
| 517 | - return "30"; | |
| 518 | - } | |
| 519 | - if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { | |
| 520 | - return "30"; | |
| 521 | - } | |
| 522 | - if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { | |
| 523 | - return "30"; | |
| 524 | - } | |
| 525 | - if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { | |
| 526 | - return "30"; | |
| 527 | - } | |
| 528 | - | |
| 529 | - return "00"; | |
| 530 | - } | |
| 531 | - | |
| 532 | - private void expireConnectUser() { | |
| 533 | - if (key == null || !key.isValid()) { | |
| 534 | - return; | |
| 535 | - } | |
| 536 | - try { | |
| 537 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 538 | - if (connectUserDto != null) { | |
| 539 | - if (connectUserDto.getUserId() != null) { | |
| 540 | - collectUserQueue.removeUser(connectUserDto.getServiceType(), connectUserDto.getUserId()); | |
| 541 | - } | |
| 542 | - key.attach(null); | |
| 543 | - } | |
| 544 | - // 소켓 채널 닫기 | |
| 545 | - channel.close(); | |
| 546 | - // 키 닫기 | |
| 547 | - key.cancel(); | |
| 548 | - } catch (IOException e) { | |
| 549 | - e.printStackTrace(); | |
| 550 | - } | |
| 551 | - } | |
| 552 | - | |
| 553 | - private void saveSystemLog(Object obj) { | |
| 554 | - saveLog(obj, true); | |
| 555 | - } | |
| 556 | - | |
| 557 | - private void saveLog(Object obj) { | |
| 558 | - saveLog(obj, false); | |
| 559 | - } | |
| 560 | - | |
| 561 | - private void saveLog(Object obj, boolean isConsoleOutput) { | |
| 562 | - if (isConsoleOutput) { | |
| 563 | - System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj); | |
| 564 | - } | |
| 565 | - | |
| 566 | - if (logger == null) { | |
| 567 | - return; | |
| 568 | - } | |
| 569 | - | |
| 570 | - logger.log(obj); | |
| 571 | - } | |
| 572 | -} |
--- src/main/java/com/munjaon/server/server/task/ReportReadTask.java
... | ... | @@ -1,290 +0,0 @@ |
| 1 | -package com.munjaon.server.server.task; | |
| 2 | - | |
| 3 | -import com.munjaon.server.cache.dto.MemberDto; | |
| 4 | -import com.munjaon.server.cache.enums.CacheService; | |
| 5 | -import com.munjaon.server.cache.service.MemberService; | |
| 6 | -import com.munjaon.server.queue.pool.ReportQueue; | |
| 7 | -import com.munjaon.server.server.dto.ReportUserDto; | |
| 8 | -import com.munjaon.server.server.packet.common.*; | |
| 9 | -import com.munjaon.server.server.queue.ReportUserQueue; | |
| 10 | -import com.munjaon.server.util.LogUtil; | |
| 11 | - | |
| 12 | -import java.io.IOException; | |
| 13 | -import java.nio.ByteBuffer; | |
| 14 | -import java.nio.channels.SelectionKey; | |
| 15 | -import java.nio.channels.Selector; | |
| 16 | -import java.nio.channels.SocketChannel; | |
| 17 | -import java.text.SimpleDateFormat; | |
| 18 | -import java.time.LocalDateTime; | |
| 19 | -import java.time.format.DateTimeFormatter; | |
| 20 | -import java.util.concurrent.Callable; | |
| 21 | - | |
| 22 | -public class ReportReadTask implements Callable<ReportUserDto> { | |
| 23 | - public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]"); | |
| 24 | - public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]"; | |
| 25 | - | |
| 26 | - private Selector selector; | |
| 27 | - private SelectionKey key; | |
| 28 | - private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance(); | |
| 29 | - private ReportUserDto reportUserDto; | |
| 30 | - private final LogUtil logger; | |
| 31 | - | |
| 32 | - public ReportReadTask(Selector selector, SelectionKey key, LogUtil logger) { | |
| 33 | - this.selector = selector; | |
| 34 | - this.key = key; | |
| 35 | - this.reportUserDto = (ReportUserDto) key.attachment(); | |
| 36 | - this.logger = logger; | |
| 37 | - } | |
| 38 | - | |
| 39 | - @Override | |
| 40 | - public ReportUserDto call() throws Exception { | |
| 41 | - int size = -1; | |
| 42 | - try { | |
| 43 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 44 | - /* 1. Head 읽기 */ | |
| 45 | - ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); | |
| 46 | - try { | |
| 47 | - size = channel.read(headBuffer); | |
| 48 | - } catch (IOException e) {} | |
| 49 | - /* 2. Body 읽기 */ | |
| 50 | - if (size > 0) { | |
| 51 | - String command = Header.getCommand(headBuffer); | |
| 52 | - switch (Integer.parseInt(command)) { | |
| 53 | - case 1 : recvBind(channel, headBuffer); break; | |
| 54 | - case 6 : recvReport(channel, headBuffer); break; | |
| 55 | - case 8 : recvLinkCheck(channel, headBuffer); break; | |
| 56 | - default: expireConnectUser(); break; | |
| 57 | - } | |
| 58 | - } else { | |
| 59 | - expireConnectUser(); | |
| 60 | - } | |
| 61 | - } catch (Exception e) { | |
| 62 | - size = -1; | |
| 63 | - e.printStackTrace(); | |
| 64 | - } | |
| 65 | - | |
| 66 | - /* 읽은 데이터가 없는 경우 command -1 */ | |
| 67 | - if (size <= 0) { | |
| 68 | - reportUserDto.setCommand(-1); | |
| 69 | - } | |
| 70 | - | |
| 71 | - return reportUserDto; | |
| 72 | - } | |
| 73 | - | |
| 74 | - private void recvLinkCheck(SocketChannel channel, ByteBuffer headBuffer) { | |
| 75 | - try { | |
| 76 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH); | |
| 77 | - int size = channel.read(bodyBuffer); | |
| 78 | - if (size > 0) { | |
| 79 | - saveLog("Recv link check"); | |
| 80 | - reportUserDto.updateLastTrafficTime(); | |
| 81 | - } | |
| 82 | - } catch (Exception e) { | |
| 83 | - e.printStackTrace(); | |
| 84 | - } | |
| 85 | - } | |
| 86 | - | |
| 87 | - private void recvReport(SocketChannel channel, ByteBuffer headBuffer) { | |
| 88 | - try { | |
| 89 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(Report.REPORT_ACK_BODY_LENGTH); | |
| 90 | - int size = channel.read(bodyBuffer); | |
| 91 | - if (size != Report.REPORT_ACK_BODY_LENGTH) { | |
| 92 | - return; | |
| 93 | - } | |
| 94 | - | |
| 95 | - saveLog("recv report"); | |
| 96 | - ReportQueue reportQueue = reportUserDto.getReportQueue(); | |
| 97 | - reportUserDto.updateLastTrafficTime(); | |
| 98 | - if (reportQueue != null) { | |
| 99 | - reportQueue.addReadCounter(); | |
| 100 | - } | |
| 101 | - } catch (Exception e) { | |
| 102 | - e.printStackTrace(); | |
| 103 | - } | |
| 104 | - } | |
| 105 | - | |
| 106 | - private String checkBind(MemberDto memberDto, String id, String pwd) { | |
| 107 | - if (id == null || pwd == null) { | |
| 108 | - return "50"; | |
| 109 | - } | |
| 110 | - if (reportUserQueue.isExist(id)) { | |
| 111 | - return "60"; | |
| 112 | - } | |
| 113 | - if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { | |
| 114 | - return "20"; | |
| 115 | - } | |
| 116 | - /* 회원 사용 상태 */ | |
| 117 | - if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { | |
| 118 | - return "30"; | |
| 119 | - } | |
| 120 | - | |
| 121 | - return "00"; | |
| 122 | - } | |
| 123 | - | |
| 124 | - private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { | |
| 125 | - String resultCode = "00"; | |
| 126 | - try { | |
| 127 | - ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); | |
| 128 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); | |
| 129 | - channel.read(bodyBuffer); | |
| 130 | - Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer); | |
| 131 | - | |
| 132 | - String id = Bind.getBindId(bindBuffer); | |
| 133 | - String pwd = Bind.getBindPwd(bindBuffer); | |
| 134 | - | |
| 135 | - MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); | |
| 136 | - MemberDto memberDto = null; | |
| 137 | - if (svc != null) { | |
| 138 | - memberDto = svc.get(id); | |
| 139 | - } | |
| 140 | - saveLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); | |
| 141 | - /* Bind Check */ | |
| 142 | - resultCode = checkBind(memberDto, id, pwd); | |
| 143 | - | |
| 144 | - /* 접속 IP 체크 */ | |
| 145 | - if ("00".equals(resultCode)) { | |
| 146 | - boolean isPermit = false; | |
| 147 | - if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { | |
| 148 | - saveLog("connectUserDto.getRemoteIP() : " + reportUserDto.getRemoteIP()); | |
| 149 | - saveLog("Customize Toolbar... : " + memberDto.getAllowIpBasic()); | |
| 150 | - saveLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend()); | |
| 151 | - if (memberDto.getAllowIpBasic() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { | |
| 152 | - isPermit = true; | |
| 153 | - } | |
| 154 | - if (memberDto.getAllowIpExtend() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) { | |
| 155 | - isPermit = true; | |
| 156 | - } | |
| 157 | - } else { | |
| 158 | - isPermit = true; | |
| 159 | - } | |
| 160 | - if (isPermit) { | |
| 161 | - resultCode = "00"; | |
| 162 | - } else { | |
| 163 | - resultCode = "40"; | |
| 164 | - } | |
| 165 | - } | |
| 166 | - | |
| 167 | - if ("00".equals(resultCode)) { | |
| 168 | - reportUserDto.setUserId(id); | |
| 169 | - reportUserDto.setLogin(true); | |
| 170 | - reportUserDto.setMemberDto(memberDto); | |
| 171 | - /* 리포트 큐 생성 */ | |
| 172 | - ReportQueue reportQueue = new ReportQueue(reportUserDto.getQueuePath(), reportUserDto.getUserId()); | |
| 173 | - reportUserDto.setReportQueue(reportQueue); | |
| 174 | - /* 사용자 Pool에 저장 */ | |
| 175 | - reportUserQueue.putUser(reportUserDto); | |
| 176 | - /* 세션통신 시간 업데이트 */ | |
| 177 | - reportUserDto.updateLastTrafficTime(); | |
| 178 | - } | |
| 179 | - } catch (Exception e) { | |
| 180 | - resultCode = "10"; | |
| 181 | - e.printStackTrace(); | |
| 182 | - } | |
| 183 | - | |
| 184 | - try { | |
| 185 | - saveLog("Bind ResultCode : " + resultCode); | |
| 186 | - channel.write(Bind.makeBindAckBuffer(resultCode)); | |
| 187 | - if ("00".equals(resultCode) == false) { | |
| 188 | - expireConnectUser(); | |
| 189 | - } | |
| 190 | - } catch (IOException e) { | |
| 191 | - e.printStackTrace(); | |
| 192 | - } | |
| 193 | - } | |
| 194 | - | |
| 195 | - private void recvBind_bak(SocketChannel channel, ByteBuffer headBuffer) { | |
| 196 | - String resultCode = "00"; | |
| 197 | - try { | |
| 198 | - ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); | |
| 199 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); | |
| 200 | - channel.read(bodyBuffer); | |
| 201 | - Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer); | |
| 202 | - | |
| 203 | - String id = Bind.getBindId(bindBuffer); | |
| 204 | - String pwd = Bind.getBindPwd(bindBuffer); | |
| 205 | - saveLog("Bind id : " + id); | |
| 206 | - saveLog("Bind pwd : " + pwd); | |
| 207 | - if (id == null || pwd == null) { | |
| 208 | - resultCode = "50"; | |
| 209 | - } else { | |
| 210 | - if (reportUserQueue.isExist(id)) { | |
| 211 | - resultCode = "60"; | |
| 212 | - } else { | |
| 213 | - MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); | |
| 214 | - MemberDto memberDto = null; | |
| 215 | - if (svc != null) { | |
| 216 | - memberDto = svc.get(id); | |
| 217 | - } | |
| 218 | - if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { | |
| 219 | - resultCode = "20"; | |
| 220 | - } else { | |
| 221 | - reportUserDto.setUserId(id); | |
| 222 | - reportUserDto.setLogin(true); | |
| 223 | - reportUserDto.setMemberDto(memberDto); | |
| 224 | - /* 리포트 큐 생성 */ | |
| 225 | - ReportQueue reportQueue = new ReportQueue(reportUserDto.getQueuePath(), reportUserDto.getUserId()); | |
| 226 | - reportUserDto.setReportQueue(reportQueue); | |
| 227 | - /* 사용자 Pool에 저장 */ | |
| 228 | - reportUserQueue.putUser(reportUserDto); | |
| 229 | - /* 세션통신 시간 업데이트 */ | |
| 230 | - reportUserDto.updateLastTrafficTime(); | |
| 231 | - } | |
| 232 | - } | |
| 233 | - } | |
| 234 | - } catch (Exception e) { | |
| 235 | - resultCode = "10"; | |
| 236 | - e.printStackTrace(); | |
| 237 | - } | |
| 238 | - | |
| 239 | - try { | |
| 240 | - saveLog("Bind ResultCode : " + resultCode); | |
| 241 | - channel.write(Bind.makeBindAckBuffer(resultCode)); | |
| 242 | - if ("00".equals(resultCode) == false) { | |
| 243 | - expireConnectUser(); | |
| 244 | - } | |
| 245 | - } catch (IOException e) { | |
| 246 | - e.printStackTrace(); | |
| 247 | - } | |
| 248 | - } | |
| 249 | - | |
| 250 | - private void expireConnectUser() { | |
| 251 | - if (key == null || !key.isValid()) { | |
| 252 | - return; | |
| 253 | - } | |
| 254 | - try { | |
| 255 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 256 | - if (reportUserDto != null) { | |
| 257 | - if (reportUserDto.getUserId() != null) { | |
| 258 | - reportUserQueue.removeUser(reportUserDto.getUserId()); | |
| 259 | - } | |
| 260 | - key.attach(null); | |
| 261 | - } | |
| 262 | - // 소켓 채널 닫기 | |
| 263 | - channel.close(); | |
| 264 | - // 키 닫기 | |
| 265 | - key.cancel(); | |
| 266 | - } catch (IOException e) { | |
| 267 | - e.printStackTrace(); | |
| 268 | - } | |
| 269 | - } | |
| 270 | - | |
| 271 | - private void saveSystemLog(Object obj) { | |
| 272 | - saveLog(obj, true); | |
| 273 | - } | |
| 274 | - | |
| 275 | - private void saveLog(Object obj) { | |
| 276 | - saveLog(obj, false); | |
| 277 | - } | |
| 278 | - | |
| 279 | - private void saveLog(Object obj, boolean isConsoleOutput) { | |
| 280 | - if (isConsoleOutput) { | |
| 281 | - System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{REPORT_READ_TASK}} " + obj); | |
| 282 | - } | |
| 283 | - | |
| 284 | - if (logger == null) { | |
| 285 | - return; | |
| 286 | - } | |
| 287 | - | |
| 288 | - logger.log(obj); | |
| 289 | - } | |
| 290 | -} |
--- src/main/java/com/munjaon/server/server/task/ReportServerTask.java
... | ... | @@ -1,430 +0,0 @@ |
| 1 | -package com.munjaon.server.server.task; | |
| 2 | - | |
| 3 | -import com.munjaon.server.cache.dto.MemberDto; | |
| 4 | -import com.munjaon.server.cache.enums.CacheService; | |
| 5 | -import com.munjaon.server.cache.service.MemberService; | |
| 6 | -import com.munjaon.server.queue.pool.ReportQueue; | |
| 7 | -import com.munjaon.server.server.config.ServerConfig; | |
| 8 | -import com.munjaon.server.server.dto.ReportDto; | |
| 9 | -import com.munjaon.server.server.dto.ReportUserDto; | |
| 10 | -import com.munjaon.server.server.packet.common.*; | |
| 11 | -import com.munjaon.server.server.queue.ReportUserQueue; | |
| 12 | -import com.munjaon.server.server.service.HealthCheckServer; | |
| 13 | -import com.munjaon.server.server.service.PropertyLoader; | |
| 14 | -import com.munjaon.server.util.LogUtil; | |
| 15 | - | |
| 16 | -import java.io.IOException; | |
| 17 | -import java.io.UnsupportedEncodingException; | |
| 18 | -import java.nio.ByteBuffer; | |
| 19 | -import java.nio.channels.SelectionKey; | |
| 20 | -import java.nio.channels.Selector; | |
| 21 | -import java.nio.channels.SocketChannel; | |
| 22 | -import java.text.SimpleDateFormat; | |
| 23 | -import java.time.LocalDateTime; | |
| 24 | -import java.time.format.DateTimeFormatter; | |
| 25 | - | |
| 26 | -public class ReportServerTask extends Thread { | |
| 27 | - public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]"); | |
| 28 | - public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]"; | |
| 29 | - | |
| 30 | - private Selector selector; | |
| 31 | - private final SelectionKey key; | |
| 32 | - private final SocketChannel channel; | |
| 33 | - private final ReportUserQueue reportUserQueue = ReportUserQueue.getInstance(); | |
| 34 | - private final ReportUserDto reportUserDto; | |
| 35 | - private final ReportQueue reportQueue; | |
| 36 | - private final String serviceName; | |
| 37 | - private final LogUtil logger; | |
| 38 | - | |
| 39 | - private boolean IS_SERVER_RUN; // 서버가 구동중인지 여부 | |
| 40 | - private boolean IS_RUN_YN; | |
| 41 | - private long RUN_FLAG_CHECK_TIME; | |
| 42 | - private long SEND_CYCLE_CHECK_TIME; | |
| 43 | - private long LAST_PACKET_SEND_TIME = System.currentTimeMillis(); // 패킷 송수신 시간을 체크하기 위한 변수(최대 3초간 요청이 없는 경우 Thread 종료) | |
| 44 | - private boolean IS_ERROR = false; | |
| 45 | - | |
| 46 | - /* 세션이 만료되었는지 체크 */ | |
| 47 | - private boolean isExpiredYn; | |
| 48 | - /* 클라이언트 요청 데이터 수신 */ | |
| 49 | - private final ByteBuffer headBuffer = ByteBuffer.allocateDirect(Header.HEADER_LENGTH); | |
| 50 | - private ReportDto reportDto; // 전송 리포트 | |
| 51 | - /* Packet을 전송했는지 여부 */ | |
| 52 | - private boolean isPacketSendYn; | |
| 53 | - | |
| 54 | - public ReportServerTask(Selector selector, SelectionKey key, String serviceName, LogUtil logger) { | |
| 55 | - this.selector = selector; | |
| 56 | - this.key = key; | |
| 57 | - this.channel = (SocketChannel) key.channel(); | |
| 58 | - this.reportUserDto = (ReportUserDto) key.attachment(); | |
| 59 | - this.reportUserDto.setRunningMode(true); | |
| 60 | - this.serviceName = serviceName; | |
| 61 | - this.reportQueue = reportUserDto.getReportQueue(); | |
| 62 | - this.logger = logger; | |
| 63 | - if (reportUserDto.isLogin()) { | |
| 64 | - saveLog("[REPORT SERVER READ] [ID : " + reportUserDto.getUserId() + "]"); | |
| 65 | - } else { | |
| 66 | - saveLog("[REPORT SERVER READ] [FIRST CONNECTION ... ... ... ... ... ... ...]"); | |
| 67 | - } | |
| 68 | - } | |
| 69 | - | |
| 70 | - protected String getProp(String name) { | |
| 71 | - return getProp(this.serviceName, name); | |
| 72 | - } | |
| 73 | - | |
| 74 | - public static String getProp(String svc, String name) { | |
| 75 | - return PropertyLoader.getProp(svc, name); | |
| 76 | - } | |
| 77 | - | |
| 78 | - private void reloadRunFlag() { | |
| 79 | - if (System.currentTimeMillis() - RUN_FLAG_CHECK_TIME > ServerConfig.INTERVAL_PROPERTY_RELOAD_TIME) { | |
| 80 | - this.IS_RUN_YN = getProp("RUN_FLAG") != null && "Y".equals(getProp("RUN_FLAG")); | |
| 81 | - this.IS_SERVER_RUN = getProp("server", "run") != null && "Y".equals(getProp("server", "run")); | |
| 82 | - RUN_FLAG_CHECK_TIME = System.currentTimeMillis(); | |
| 83 | - } | |
| 84 | - } | |
| 85 | - | |
| 86 | - public boolean isRun() { | |
| 87 | - return IS_SERVER_RUN && IS_RUN_YN; | |
| 88 | - } | |
| 89 | - | |
| 90 | - /* 로그 헤더 생성 */ | |
| 91 | - private String printTaskLog() { | |
| 92 | - StringBuilder builder = new StringBuilder(); | |
| 93 | - builder.append("[ReportServerTask]"); | |
| 94 | - if (reportUserDto.isLogin()) { | |
| 95 | - builder.append("[ID : ").append(reportUserDto.getUserId()).append("]"); | |
| 96 | - } else { | |
| 97 | - builder.append("[FIRST CONNECTION ... ... ... ... ... ... ...]"); | |
| 98 | - } | |
| 99 | - | |
| 100 | - return builder.toString(); | |
| 101 | - } | |
| 102 | - | |
| 103 | - @Override | |
| 104 | - public void run() { | |
| 105 | - saveLog(printTaskLog() + "[### Start ### ### ### ### ### ### ###]"); | |
| 106 | - /* 최초 RUN Flag 체크 */ | |
| 107 | - reloadRunFlag(); | |
| 108 | - try { | |
| 109 | - /* BIND 체크 및 처리 */ | |
| 110 | - bindInterest(); | |
| 111 | - SEND_CYCLE_CHECK_TIME = System.currentTimeMillis(); | |
| 112 | - while (reportUserDto.isLogin() && isRun()) { | |
| 113 | - /* 만료 여부 체크 */ | |
| 114 | - if (isExpiredYn) { | |
| 115 | - break; | |
| 116 | - } | |
| 117 | - /* 2. Packet Timeout Check */ | |
| 118 | - if (checkTimeOut()) { | |
| 119 | - saveLog(printTaskLog() + "[checkTimeOut : Expired ... ... ... ... ... ... ...]"); | |
| 120 | - expireConnectUser(); | |
| 121 | - saveLog(printTaskLog() + "[### End ### ### ### ### ### ### ###]"); | |
| 122 | - break; | |
| 123 | - } | |
| 124 | - | |
| 125 | - sendInterest(); | |
| 126 | - recvInterest(); | |
| 127 | - /* RUN Flag 체크 */ | |
| 128 | - reloadRunFlag(); | |
| 129 | - /* 쓰레드 완료 시점 체크 */ | |
| 130 | - if (System.currentTimeMillis() - LAST_PACKET_SEND_TIME > ServerConfig.REPORT_EXEC_CYCLE_TIME) { | |
| 131 | - break; | |
| 132 | - } | |
| 133 | - } | |
| 134 | - } catch (Exception e) { | |
| 135 | - /* 세션 만료 여부 */ | |
| 136 | - this.isExpiredYn = true; | |
| 137 | - this.IS_ERROR = true; | |
| 138 | - saveLog(e); | |
| 139 | - } | |
| 140 | - /* 중요 : 사용자 Thread 실행모드 Off */ | |
| 141 | - reportUserDto.setRunningMode(false); | |
| 142 | - /* 에러가 발생한 경우 세션을 종료힌다. */ | |
| 143 | - if (IS_ERROR) { | |
| 144 | - expireConnectUser(); | |
| 145 | - } | |
| 146 | - saveLog(printTaskLog() + "[### End ### ### ### ### ### ### ###]"); | |
| 147 | - } | |
| 148 | - | |
| 149 | - private boolean checkTimeOut() { | |
| 150 | - if (System.currentTimeMillis() - this.reportUserDto.getLastTrafficTime() >= Packet.LIMIT_PACKET_TIMEOUT) { | |
| 151 | - return true; | |
| 152 | - } | |
| 153 | - | |
| 154 | - return false; | |
| 155 | - } | |
| 156 | - | |
| 157 | - private void initHeaderBuffer() { | |
| 158 | - this.headBuffer.clear(); | |
| 159 | - for (int loopCnt = 0; loopCnt < Header.HEADER_LENGTH; loopCnt++) { | |
| 160 | - this.headBuffer.put(Packet.SET_DEFAULT_BYTE); | |
| 161 | - } | |
| 162 | - this.headBuffer.position(0); | |
| 163 | - } | |
| 164 | - | |
| 165 | - private int readHeader() { | |
| 166 | - initHeaderBuffer(); | |
| 167 | - int size = -1; | |
| 168 | - try { | |
| 169 | - size = channel.read(headBuffer); | |
| 170 | - } catch (IOException e) { | |
| 171 | - throw new RuntimeException(e); | |
| 172 | - } | |
| 173 | - | |
| 174 | - return size; | |
| 175 | - } | |
| 176 | - | |
| 177 | - private void bindInterest() throws UnsupportedEncodingException { | |
| 178 | - if (reportUserDto.isLogin()) { | |
| 179 | - return; | |
| 180 | - } | |
| 181 | - long bind_check_start_time = System.currentTimeMillis(); | |
| 182 | - while(true) { | |
| 183 | - /* 1. Head 읽기 */ | |
| 184 | - int size = readHeader(); | |
| 185 | - /* 2. Body 읽기 */ | |
| 186 | - if (size > 0) { | |
| 187 | - String command = Header.getCommand(this.headBuffer); | |
| 188 | - if (Integer.parseInt(command) == 1) { | |
| 189 | - recvBind(channel, headBuffer); | |
| 190 | - } else { | |
| 191 | - expireConnectUser(); | |
| 192 | - } | |
| 193 | - /* 패킷 수신한 경우 무조건 루프를 빠져나간다 */ | |
| 194 | - break; | |
| 195 | - } | |
| 196 | - /* 3초 이내에 로그인 실패시 종료 */ | |
| 197 | - if (System.currentTimeMillis() - bind_check_start_time > ServerConfig.LIMIT_BIND_TIMEOUT) { | |
| 198 | - expireConnectUser(); | |
| 199 | - break; | |
| 200 | - } | |
| 201 | - } | |
| 202 | - } | |
| 203 | - | |
| 204 | - private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { | |
| 205 | - String resultCode = "00"; | |
| 206 | - try { | |
| 207 | - ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); | |
| 208 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); | |
| 209 | - channel.read(bodyBuffer); | |
| 210 | - Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer); | |
| 211 | - | |
| 212 | - String id = Bind.getBindId(bindBuffer); | |
| 213 | - String pwd = Bind.getBindPwd(bindBuffer); | |
| 214 | - | |
| 215 | - MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); | |
| 216 | - MemberDto memberDto = null; | |
| 217 | - if (svc != null) { | |
| 218 | - memberDto = svc.get(id); | |
| 219 | - } | |
| 220 | - saveLog(printTaskLog() + "[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); | |
| 221 | - /* Bind Check */ | |
| 222 | - resultCode = checkBind(memberDto, id, pwd); | |
| 223 | - | |
| 224 | - /* 접속 IP 체크 */ | |
| 225 | - if ("00".equals(resultCode)) { | |
| 226 | - boolean isPermit = false; | |
| 227 | - if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { | |
| 228 | - saveLog(printTaskLog() + "[REMOTE IP : " + reportUserDto.getRemoteIP() + "]"); | |
| 229 | - saveLog(printTaskLog() + "[ALLOW IP BASIC : " + memberDto.getAllowIpBasic() + "]"); | |
| 230 | - saveLog(printTaskLog() + "[ALLOW IP EXTEND : " + memberDto.getAllowIpExtend() + "]"); | |
| 231 | - if (memberDto.getAllowIpBasic() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { | |
| 232 | - isPermit = true; | |
| 233 | - } | |
| 234 | - if (memberDto.getAllowIpExtend() != null && reportUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) { | |
| 235 | - isPermit = true; | |
| 236 | - } | |
| 237 | - } else { | |
| 238 | - isPermit = true; | |
| 239 | - } | |
| 240 | - if (isPermit) { | |
| 241 | - resultCode = "00"; | |
| 242 | - } else { | |
| 243 | - resultCode = "40"; | |
| 244 | - } | |
| 245 | - } | |
| 246 | - | |
| 247 | - /* BIND 성공인 경우 사용자 정보 저장 */ | |
| 248 | - if ("00".equals(resultCode)) { | |
| 249 | - reportUserDto.setUserId(id); | |
| 250 | - reportUserDto.setLogin(true); | |
| 251 | - reportUserDto.setMemberDto(memberDto); | |
| 252 | - /* 리포트 큐 생성 */ | |
| 253 | - ReportQueue reportQueue = new ReportQueue(reportUserDto.getQueuePath(), reportUserDto.getUserId()); | |
| 254 | - reportUserDto.setReportQueue(reportQueue); | |
| 255 | - /* 세션통신 시간 업데이트 */ | |
| 256 | - reportUserDto.updateLastTrafficTime(); | |
| 257 | - } | |
| 258 | - } catch (Exception e) { | |
| 259 | - resultCode = "10"; | |
| 260 | - saveLog(e); | |
| 261 | - } | |
| 262 | - | |
| 263 | - try { | |
| 264 | - saveLog(printTaskLog() + "[BIND RESULT : " + resultCode + "]"); | |
| 265 | - channel.write(Bind.makeBindAckBuffer(resultCode)); | |
| 266 | - if ("00".equals(resultCode)) { | |
| 267 | - /* BIND 성공인 경우 사용자 Pool에 저장 */ | |
| 268 | - reportUserQueue.putUser(reportUserDto); | |
| 269 | - } else { | |
| 270 | - expireConnectUser(); | |
| 271 | - } | |
| 272 | - /* 모니터링 로그 */ | |
| 273 | - HealthCheckServer.saveMonitorLog("[REPORT SERVER][ID : " + reportUserDto.getUserId() + "][BIND RESULT : " + resultCode + "]"); | |
| 274 | - } catch (IOException e) { | |
| 275 | - saveLog(e); | |
| 276 | - throw new RuntimeException(e); | |
| 277 | - } | |
| 278 | - } | |
| 279 | - | |
| 280 | - private String checkBind(MemberDto memberDto, String id, String pwd) { | |
| 281 | - if (id == null || pwd == null) { | |
| 282 | - return "50"; | |
| 283 | - } | |
| 284 | - if (reportUserQueue.isExist(id)) { | |
| 285 | - return "60"; | |
| 286 | - } | |
| 287 | - if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { | |
| 288 | - return "20"; | |
| 289 | - } | |
| 290 | - /* 회원 사용 상태 */ | |
| 291 | - if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { | |
| 292 | - return "30"; | |
| 293 | - } | |
| 294 | - | |
| 295 | - return "00"; | |
| 296 | - } | |
| 297 | - | |
| 298 | - private void recvInterest() throws IOException, Exception { | |
| 299 | - while (isPacketSendYn) { | |
| 300 | - /* 1. Head 읽기 */ | |
| 301 | - ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); | |
| 302 | - int size = channel.read(headBuffer); | |
| 303 | - if (size > 0) { | |
| 304 | - String command = Header.getCommand(headBuffer); | |
| 305 | - switch (Integer.parseInt(command)) { | |
| 306 | - case 6 : recvReport(channel); break; | |
| 307 | - case 8 : recvLinkCheck(channel); break; | |
| 308 | - default: saveLog(printTaskLog() + "[INVALID REQUEST][command : " + command + "]"); | |
| 309 | - expireConnectUser(); break; | |
| 310 | - } | |
| 311 | - /* 마지막 패킷 수신시간 체크 */ | |
| 312 | - LAST_PACKET_SEND_TIME = System.currentTimeMillis(); | |
| 313 | - } else if (size == 0) { | |
| 314 | - Thread.sleep(1); | |
| 315 | - if (System.currentTimeMillis() - SEND_CYCLE_CHECK_TIME >= ServerConfig.REPORT_EXEC_CYCLE_TIME) { | |
| 316 | - saveLog(printTaskLog() + "[SEND_CYCLE_CHECK_TIME IS OVER : 3000ms]"); | |
| 317 | - expireConnectUser(); | |
| 318 | - this.isExpiredYn = true; | |
| 319 | - break; | |
| 320 | - } | |
| 321 | - } else { | |
| 322 | - saveLog(printTaskLog() + "[recvInterest : size is zero]"); | |
| 323 | - expireConnectUser(); | |
| 324 | - throw new IOException("[recvInterest : size is zero]"); | |
| 325 | - } | |
| 326 | - } | |
| 327 | - } | |
| 328 | - | |
| 329 | - private void recvLinkCheck(SocketChannel channel) throws IOException { | |
| 330 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH); | |
| 331 | - int size = channel.read(bodyBuffer); | |
| 332 | - if (size > 0) { | |
| 333 | - saveLog(printTaskLog() + "[RECEIVE LINK CHECK ACK ... ... ... ... ... ... ...]"); | |
| 334 | - reportUserDto.updateLastTrafficTime(); | |
| 335 | - this.isPacketSendYn = false; | |
| 336 | - } | |
| 337 | - } | |
| 338 | - | |
| 339 | - private void recvReport(SocketChannel channel) throws Exception { | |
| 340 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(Report.REPORT_ACK_BODY_LENGTH); | |
| 341 | - int size = channel.read(bodyBuffer); | |
| 342 | - if (size != Report.REPORT_ACK_BODY_LENGTH) { | |
| 343 | - return; | |
| 344 | - } | |
| 345 | - | |
| 346 | - saveLog(printTaskLog() + "[RECEIVE REPORT ACK ... ... ... ... ... ... ...]"); | |
| 347 | - ReportQueue reportQueue = reportUserDto.getReportQueue(); | |
| 348 | - reportUserDto.updateLastTrafficTime(); | |
| 349 | - this.isPacketSendYn = false; | |
| 350 | - if (reportQueue != null && this.reportDto != null) { | |
| 351 | - saveLog(printTaskLog() + "[RECEIVE REPORT : " + this.reportDto.toString() + "]"); | |
| 352 | - reportQueue.addReadCounter(); | |
| 353 | - } | |
| 354 | - } | |
| 355 | - | |
| 356 | - private void sendInterest() throws Exception { | |
| 357 | - if (isPacketSendYn) { | |
| 358 | - return; | |
| 359 | - } | |
| 360 | - if (reportUserDto.isAlive() == 2) { | |
| 361 | - channel.write(LinkCheck.makeLinkCheckBuffer()); | |
| 362 | - saveLog(printTaskLog() + "[SEND LINK CHECK ... ... ... ... ... ... ...]"); | |
| 363 | - SEND_CYCLE_CHECK_TIME = System.currentTimeMillis(); | |
| 364 | - /* Packet 전송했는지 여부 */ | |
| 365 | - isPacketSendYn = true; | |
| 366 | - } else { | |
| 367 | - if (this.reportQueue != null && this.reportQueue.isRemainReport()) { | |
| 368 | - this.reportDto = this.reportQueue.popReportFromQueue(); | |
| 369 | - if (reportDto == null) { | |
| 370 | - return; | |
| 371 | - } | |
| 372 | - saveLog(printTaskLog() + "[REPORT SEND : " + reportDto.toString() + "]"); | |
| 373 | - ByteBuffer reportBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Report.REPORT_BODY_LENGTH); | |
| 374 | - Packet.setDefaultByte(reportBuffer); | |
| 375 | - Header.putHeader(reportBuffer, Header.COMMAND_REPORT, Report.REPORT_BODY_LENGTH); | |
| 376 | - Report.putReport(reportBuffer, reportDto); | |
| 377 | - channel.write(reportBuffer); | |
| 378 | - /* Packet 전송했는지 여부 */ | |
| 379 | - SEND_CYCLE_CHECK_TIME = System.currentTimeMillis(); | |
| 380 | - isPacketSendYn = true; | |
| 381 | - } | |
| 382 | - } | |
| 383 | - } | |
| 384 | - | |
| 385 | - private void expireConnectUser() { | |
| 386 | - if (key == null || !key.isValid()) { | |
| 387 | - return; | |
| 388 | - } | |
| 389 | - try { | |
| 390 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 391 | - saveLog("[ReportServerTask]Expire connect user: " + reportUserDto); | |
| 392 | - if (reportUserDto != null) { | |
| 393 | - if (reportUserDto.getUserId() != null) { | |
| 394 | - reportUserQueue.removeUser(reportUserDto.getUserId()); | |
| 395 | - } | |
| 396 | - key.attach(null); | |
| 397 | - /* 모니터링 로그 */ | |
| 398 | - HealthCheckServer.saveMonitorLog("[REPORT SERVER][ID : " + reportUserDto.getUserId() + "][EXPIRE CONNECT USER]"); | |
| 399 | - } | |
| 400 | - /* 세션 만료 여부 */ | |
| 401 | - this.isExpiredYn = true; | |
| 402 | - // 소켓 채널 닫기 | |
| 403 | - channel.close(); | |
| 404 | - // 키 닫기 | |
| 405 | - key.cancel(); | |
| 406 | - } catch (IOException e) { | |
| 407 | - saveLog(e); | |
| 408 | - } | |
| 409 | - } | |
| 410 | - | |
| 411 | - private void saveSystemLog(Object obj) { | |
| 412 | - saveLog(obj, true); | |
| 413 | - } | |
| 414 | - | |
| 415 | - private void saveLog(Object obj) { | |
| 416 | - saveLog(obj, false); | |
| 417 | - } | |
| 418 | - | |
| 419 | - private void saveLog(Object obj, boolean isConsoleOutput) { | |
| 420 | - if (isConsoleOutput) { | |
| 421 | - System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{" + this.serviceName + "}} " + obj); | |
| 422 | - } | |
| 423 | - | |
| 424 | - if (logger == null) { | |
| 425 | - return; | |
| 426 | - } | |
| 427 | - | |
| 428 | - logger.log(obj); | |
| 429 | - } | |
| 430 | -} |
--- src/main/java/com/munjaon/server/server/task/SendReadTask.java
... | ... | @@ -1,565 +0,0 @@ |
| 1 | -package com.munjaon.server.server.task; | |
| 2 | - | |
| 3 | -import com.munjaon.server.cache.dto.MemberDto; | |
| 4 | -import com.munjaon.server.cache.enums.CacheService; | |
| 5 | -import com.munjaon.server.cache.service.MemberService; | |
| 6 | -import com.munjaon.server.queue.dto.BasicMessageDto; | |
| 7 | -import com.munjaon.server.queue.enums.QueueTypeWorker; | |
| 8 | -import com.munjaon.server.server.dto.ConnectUserDto; | |
| 9 | -import com.munjaon.server.server.packet.common.*; | |
| 10 | -import com.munjaon.server.server.queue.CollectUserQueue; | |
| 11 | -import com.munjaon.server.util.*; | |
| 12 | - | |
| 13 | -import java.io.File; | |
| 14 | -import java.io.IOException; | |
| 15 | -import java.io.UnsupportedEncodingException; | |
| 16 | -import java.nio.ByteBuffer; | |
| 17 | -import java.nio.channels.SelectionKey; | |
| 18 | -import java.nio.channels.Selector; | |
| 19 | -import java.nio.channels.SocketChannel; | |
| 20 | -import java.text.SimpleDateFormat; | |
| 21 | -import java.time.LocalDateTime; | |
| 22 | -import java.time.format.DateTimeFormatter; | |
| 23 | - | |
| 24 | -public class SendReadTask implements Runnable { | |
| 25 | - public static final SimpleDateFormat sdf = new SimpleDateFormat("[MM-dd HH:mm:ss]"); | |
| 26 | - public static final String LOG_DATE_FORMAT = "[MM-dd HH:mm:ss]"; | |
| 27 | - | |
| 28 | - private Selector selector; | |
| 29 | - private SelectionKey key; | |
| 30 | - private CollectUserQueue collectUserQueue = CollectUserQueue.getInstance(); | |
| 31 | - private ConnectUserDto connectUserDto; | |
| 32 | - private String serviceType; | |
| 33 | - private final LogUtil logger; | |
| 34 | - | |
| 35 | - public SendReadTask(Selector selector, SelectionKey key, String serviceType, LogUtil logger) { | |
| 36 | - this.selector = selector; | |
| 37 | - this.key = key; | |
| 38 | - this.connectUserDto = (ConnectUserDto) key.attachment(); | |
| 39 | - this.serviceType = serviceType; | |
| 40 | - this.logger = logger; | |
| 41 | - } | |
| 42 | - | |
| 43 | - @Override | |
| 44 | - public void run() { | |
| 45 | - System.out.println("SendReadTask start : " + Thread.currentThread().getName()); | |
| 46 | - int size = -1; | |
| 47 | - try { | |
| 48 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 49 | - /* 1. Head 읽기 */ | |
| 50 | - ByteBuffer headBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH); | |
| 51 | - try { | |
| 52 | - size = channel.read(headBuffer); | |
| 53 | - } catch (IOException e) {} | |
| 54 | - /* 2. Body 읽기 */ | |
| 55 | - if (size > 0) { | |
| 56 | -// Packet.printBuffer(headBuffer); | |
| 57 | - String command = Header.getCommand(headBuffer); | |
| 58 | - switch (Integer.parseInt(command)) { | |
| 59 | - case 1 : recvBind(channel, headBuffer); break; | |
| 60 | - case 3 : recvDeliver(channel, headBuffer); break; | |
| 61 | - case 7 : recvLinkCheck(channel); break; | |
| 62 | - default: expireConnectUser(); break; | |
| 63 | - } | |
| 64 | - } else { | |
| 65 | - expireConnectUser(); | |
| 66 | - } | |
| 67 | - } catch (Exception e) { | |
| 68 | - size = -1; | |
| 69 | - e.printStackTrace(); | |
| 70 | - } | |
| 71 | - } | |
| 72 | - | |
| 73 | - private void recvDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 74 | - /* 서비스 중지여부 체크 */ | |
| 75 | - if (isExpireService()) { | |
| 76 | - expireConnectUser(); | |
| 77 | - return; | |
| 78 | - } | |
| 79 | - switch (this.serviceType) { | |
| 80 | - case "SMS": | |
| 81 | - recvSmsDeliver(channel, headBuffer); | |
| 82 | - break; | |
| 83 | - case "LMS": | |
| 84 | - recvLmsDeliver(channel, headBuffer); | |
| 85 | - break; | |
| 86 | - case "MMS": | |
| 87 | - recvMmsDeliver(channel, headBuffer); | |
| 88 | - break; | |
| 89 | - case "KAT": | |
| 90 | - recvKatDeliver(channel, headBuffer); | |
| 91 | - break; | |
| 92 | - case "KFT": | |
| 93 | - recvKftDeliver(channel, headBuffer); | |
| 94 | - break; | |
| 95 | - default:break; | |
| 96 | - } | |
| 97 | - } | |
| 98 | - | |
| 99 | - private boolean isExpireService() { | |
| 100 | - ConnectUserDto checkConnectUserDto = collectUserQueue.getUser(this.serviceType, this.connectUserDto.getUserId()); | |
| 101 | - MemberDto memberDto = checkConnectUserDto.getMemberDto(); | |
| 102 | - saveLog("[isExpireService : " + memberDto.toString() + "]"); | |
| 103 | - if (memberDto == null) { | |
| 104 | - return true; | |
| 105 | - } | |
| 106 | - if (collectUserQueue.isExist(this.serviceType, memberDto.getMberId()) == false) { | |
| 107 | - return true; | |
| 108 | - } | |
| 109 | - /* 회원 사용 상태 */ | |
| 110 | - if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { | |
| 111 | - return true; | |
| 112 | - } | |
| 113 | - /* 서비스 이용 상태 */ | |
| 114 | - if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { | |
| 115 | - return true; | |
| 116 | - } | |
| 117 | - if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { | |
| 118 | - return true; | |
| 119 | - } | |
| 120 | - if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { | |
| 121 | - return true; | |
| 122 | - } | |
| 123 | - if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { | |
| 124 | - return true; | |
| 125 | - } | |
| 126 | - if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { | |
| 127 | - return true; | |
| 128 | - } | |
| 129 | - | |
| 130 | - return false; | |
| 131 | - } | |
| 132 | - | |
| 133 | - public BasicMessageDto recvCommonMessage(ByteBuffer deliverBuffer) throws UnsupportedEncodingException { | |
| 134 | - if (deliverBuffer == null) { | |
| 135 | - return null; | |
| 136 | - } | |
| 137 | - BasicMessageDto messageDto = new BasicMessageDto(); | |
| 138 | - messageDto.setRouterSeq("40"); | |
| 139 | - messageDto.setServiceType("4"); | |
| 140 | - messageDto.setUserId(connectUserDto.getUserId()); | |
| 141 | - messageDto.setRemoteIP(connectUserDto.getRemoteIP()); | |
| 142 | - messageDto.setSendStatus("0"); | |
| 143 | - messageDto.setUserMsgID(CommonMessage.getMessageIdForDeliver(deliverBuffer)); | |
| 144 | - messageDto.setUserSender(CommonMessage.getSenderForDeliver(deliverBuffer)); | |
| 145 | - messageDto.setUserReceiver(CommonMessage.getReceiverForDeliver(deliverBuffer)); | |
| 146 | - messageDto.setReserveDt(CommonMessage.getReserveTimeForDeliver(deliverBuffer)); | |
| 147 | - messageDto.setRequestDt(CommonMessage.getRequestTimeForDeliver(deliverBuffer)); | |
| 148 | - messageDto.setUnitCost("10.4"); | |
| 149 | - | |
| 150 | - return messageDto; | |
| 151 | - } | |
| 152 | - | |
| 153 | - private void recvSmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 154 | - try { | |
| 155 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(SmsMessage.DELIVER_SMS_BODY_LENGTH); | |
| 156 | - channel.read(bodyBuffer); | |
| 157 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + SmsMessage.DELIVER_SMS_BODY_LENGTH); | |
| 158 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 159 | - | |
| 160 | -// Packet.printBuffer(deliverBuffer); | |
| 161 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 162 | - messageDto.setUserMessage(SmsMessage.getMessageForDeliver(deliverBuffer)); | |
| 163 | - | |
| 164 | - /* 사용자 단가, 발송망 설정 */ | |
| 165 | - MemberDto savedMemberDto = null; | |
| 166 | - if (this.connectUserDto != null) { | |
| 167 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 168 | - } | |
| 169 | - if (savedMemberDto != null) { | |
| 170 | - messageDto.setRouterSeq(savedMemberDto.getSmsAgentCode()); | |
| 171 | - messageDto.setUnitCost(String.valueOf(savedMemberDto.getShortPrice())); | |
| 172 | - } | |
| 173 | - | |
| 174 | - saveLog("[SMS] [MESSAGE : " + messageDto.toString() + "]"); | |
| 175 | - QueueTypeWorker worker = QueueTypeWorker.find("SMS"); | |
| 176 | - if (worker != null) { | |
| 177 | - worker.pushQueue(messageDto); | |
| 178 | - channel.write(SmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 179 | - } | |
| 180 | - } catch (Exception e) { | |
| 181 | - e.printStackTrace(); | |
| 182 | - } | |
| 183 | - } | |
| 184 | - | |
| 185 | - private void recvLmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 186 | - try { | |
| 187 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(LmsMessage.DELIVER_LMS_BODY_LENGTH); | |
| 188 | - channel.read(bodyBuffer); | |
| 189 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + LmsMessage.DELIVER_LMS_BODY_LENGTH); | |
| 190 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 191 | - | |
| 192 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 193 | - messageDto.setUserSubject(LmsMessage.getSubjectForDeliver(deliverBuffer)); | |
| 194 | - messageDto.setUserMessage(LmsMessage.getMessageForDeliver(deliverBuffer)); | |
| 195 | - | |
| 196 | - /* 사용자 단가, 발송망 설정 */ | |
| 197 | - MemberDto savedMemberDto = null; | |
| 198 | - if (this.connectUserDto != null) { | |
| 199 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 200 | - } | |
| 201 | - if (savedMemberDto != null) { | |
| 202 | - messageDto.setRouterSeq(savedMemberDto.getLmsAgentCode()); | |
| 203 | - messageDto.setUnitCost(String.valueOf(savedMemberDto.getLongPrice())); | |
| 204 | - } | |
| 205 | - | |
| 206 | - saveLog("[LMS] [MESSAGE : " + messageDto.toString() + "]"); | |
| 207 | - QueueTypeWorker worker = QueueTypeWorker.find("LMS"); | |
| 208 | - if (worker != null) { | |
| 209 | - worker.pushQueue(messageDto); | |
| 210 | - channel.write(LmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 211 | - } | |
| 212 | - } catch (Exception e) { | |
| 213 | - e.printStackTrace(); | |
| 214 | - } | |
| 215 | - } | |
| 216 | - | |
| 217 | - private void recvMmsDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 218 | - try { | |
| 219 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_BODY_LENGTH); | |
| 220 | - channel.read(bodyBuffer); | |
| 221 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + MmsMessage.DELIVER_MMS_BODY_LENGTH); | |
| 222 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 223 | - | |
| 224 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 225 | - messageDto.setUserSubject(MmsMessage.getSubjectForDeliver(deliverBuffer)); | |
| 226 | - messageDto.setUserMessage(MmsMessage.getMessageForDeliver(deliverBuffer)); | |
| 227 | - String fileCount = MessageUtil.doNumber(MmsMessage.getFileCountForDeliver(deliverBuffer)); | |
| 228 | - int recvFileCount = 0; | |
| 229 | - if (fileCount != null && fileCount.length() > 0) { | |
| 230 | - recvFileCount = Integer.parseInt(fileCount); | |
| 231 | - messageDto.setUserFileCnt(recvFileCount); | |
| 232 | - } | |
| 233 | - | |
| 234 | - String imagePath = System.getProperty("ROOTPATH") + File.separator + "mmsfile"; | |
| 235 | - imagePath = imagePath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); | |
| 236 | - FileUtil.mkdirs(imagePath); | |
| 237 | - | |
| 238 | - for (int i = 0; i < recvFileCount; i++) { | |
| 239 | - ByteBuffer fileHeadBuffer = ByteBuffer.allocate(MmsMessage.DELIVER_MMS_FILENAME_LENGTH + MmsMessage.DELIVER_MMS_FILESIZE_LENGTH); | |
| 240 | - channel.read(fileHeadBuffer); | |
| 241 | - String fileName = MmsMessage.getFileNameForDeliver(fileHeadBuffer); | |
| 242 | - String fileSize = MmsMessage.getFileSizeForDeliver(fileHeadBuffer); | |
| 243 | - ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); | |
| 244 | - channel.read(fileBuffer); | |
| 245 | - fileBuffer.flip(); | |
| 246 | - JobFileFactory.saveFileForByteBuffer(imagePath, fileName, fileBuffer); | |
| 247 | - if (i == 0) { | |
| 248 | - messageDto.setUserFileName01(imagePath + File.separator + fileName); | |
| 249 | - } else if (i == 1) { | |
| 250 | - messageDto.setUserFileName02(imagePath + File.separator + fileName); | |
| 251 | - } else if (i == 2) { | |
| 252 | - messageDto.setUserFileName03(imagePath + File.separator + fileName); | |
| 253 | - } | |
| 254 | - saveLog("[MMS IMAGE] [File : " + fileName + ", Size : " + fileSize + "]"); | |
| 255 | - } | |
| 256 | - | |
| 257 | - /* 사용자 단가, 발송망 설정 */ | |
| 258 | - MemberDto savedMemberDto = null; | |
| 259 | - if (this.connectUserDto != null) { | |
| 260 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 261 | - } | |
| 262 | - if (savedMemberDto != null) { | |
| 263 | - messageDto.setRouterSeq(savedMemberDto.getMmsAgentCode()); | |
| 264 | - float mmsPrice = 0.0F; | |
| 265 | - if (recvFileCount == 1) { | |
| 266 | - mmsPrice = savedMemberDto.getPicturePrice(); | |
| 267 | - } else if (recvFileCount == 2) { | |
| 268 | - mmsPrice = savedMemberDto.getPicture2Price(); | |
| 269 | - } else { | |
| 270 | - mmsPrice = savedMemberDto.getPicture3Price(); | |
| 271 | - } | |
| 272 | - messageDto.setUnitCost(String.valueOf(mmsPrice)); | |
| 273 | - } | |
| 274 | - | |
| 275 | - saveLog("[MMS] [MESSAGE : " + messageDto.toString() + "]"); | |
| 276 | - QueueTypeWorker worker = QueueTypeWorker.find("MMS"); | |
| 277 | - if (worker != null) { | |
| 278 | - worker.pushQueue(messageDto); | |
| 279 | - channel.write(MmsMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 280 | - } | |
| 281 | - } catch (Exception e) { | |
| 282 | - e.printStackTrace(); | |
| 283 | - } | |
| 284 | - } | |
| 285 | - | |
| 286 | - private void recvKatDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 287 | - try { | |
| 288 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); | |
| 289 | - channel.read(bodyBuffer); | |
| 290 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); | |
| 291 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 292 | - | |
| 293 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 294 | - messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer)); | |
| 295 | - messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer)); | |
| 296 | - messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); | |
| 297 | - messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); | |
| 298 | - | |
| 299 | - String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; | |
| 300 | - jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); | |
| 301 | - FileUtil.mkdirs(jsonPath); | |
| 302 | - | |
| 303 | - ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH); | |
| 304 | - channel.read(fileHeadBuffer); | |
| 305 | - | |
| 306 | - String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer); | |
| 307 | - String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer); | |
| 308 | - | |
| 309 | - ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); | |
| 310 | - channel.read(fileBuffer); | |
| 311 | - fileBuffer.flip(); | |
| 312 | - JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); | |
| 313 | - | |
| 314 | - messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); | |
| 315 | - saveLog("[KAT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); | |
| 316 | - | |
| 317 | - /* 사용자 단가, 발송망 설정 */ | |
| 318 | - MemberDto savedMemberDto = null; | |
| 319 | - if (this.connectUserDto != null) { | |
| 320 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 321 | - } | |
| 322 | - if (savedMemberDto != null) { | |
| 323 | - messageDto.setRouterSeq(savedMemberDto.getKakaoAtAgentCode()); | |
| 324 | - messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoAtPrice())); | |
| 325 | - } | |
| 326 | - | |
| 327 | - saveLog("[KAKAO ALARM] [MESSAGE : " + messageDto.toString() + "]"); | |
| 328 | - QueueTypeWorker worker = QueueTypeWorker.find("KAT"); | |
| 329 | - if (worker != null) { | |
| 330 | - worker.pushQueue(messageDto); | |
| 331 | - channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 332 | - } else { | |
| 333 | - saveLog("worker is null"); | |
| 334 | - } | |
| 335 | - } catch (Exception e) { | |
| 336 | - e.printStackTrace(); | |
| 337 | - } | |
| 338 | - } | |
| 339 | - | |
| 340 | - private void recvKftDeliver(SocketChannel channel, ByteBuffer headBuffer) throws IOException { | |
| 341 | - try { | |
| 342 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); | |
| 343 | - channel.read(bodyBuffer); | |
| 344 | - ByteBuffer deliverBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + KakaoMessage.DELIVER_KAKAO_BODY_LENGTH); | |
| 345 | - Packet.mergeBuffers(deliverBuffer, headBuffer, bodyBuffer); | |
| 346 | - | |
| 347 | - BasicMessageDto messageDto = recvCommonMessage(deliverBuffer); | |
| 348 | - messageDto.setUserSubject(KakaoMessage.getSubjectForDeliver(deliverBuffer)); | |
| 349 | - messageDto.setUserMessage(KakaoMessage.getMessageForDeliver(deliverBuffer)); | |
| 350 | - messageDto.setKakaoSenderKey(KakaoMessage.getKakaoSenderKeyForDeliver(deliverBuffer)); | |
| 351 | - messageDto.setKakaoTemplateCode(KakaoMessage.getKakaoTemplateCodeForDeliver(deliverBuffer)); | |
| 352 | - | |
| 353 | - String jsonPath = System.getProperty("ROOTPATH") + File.separator + "kakaofile"; | |
| 354 | - jsonPath = jsonPath + File.separator + MessageUtil.getDate() + File.separator + SerialNoUtil.getSerialNo(); | |
| 355 | - FileUtil.mkdirs(jsonPath); | |
| 356 | - | |
| 357 | - ByteBuffer fileHeadBuffer = ByteBuffer.allocate(KakaoMessage.DELIVER_JSON_FILENAME_LENGTH + KakaoMessage.DELIVER_JSON_FILESIZE_LENGTH); | |
| 358 | - channel.read(fileHeadBuffer); | |
| 359 | - | |
| 360 | - String fileName = KakaoMessage.getFileNameForDeliver(fileHeadBuffer); | |
| 361 | - String fileSize = KakaoMessage.getFileSizeForDeliver(fileHeadBuffer); | |
| 362 | - | |
| 363 | - ByteBuffer fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize)); | |
| 364 | - channel.read(fileBuffer); | |
| 365 | - fileBuffer.flip(); | |
| 366 | - JobFileFactory.saveFileForByteBuffer(jsonPath, fileName, fileBuffer); | |
| 367 | - | |
| 368 | - messageDto.setKakaoJsonFile(jsonPath + File.separator + fileName); | |
| 369 | - saveLog("[KFT JSON] [File : " + fileName + ", Size : " + fileSize + "]"); | |
| 370 | - | |
| 371 | - /* 사용자 단가, 발송망 설정 */ | |
| 372 | - MemberDto savedMemberDto = null; | |
| 373 | - if (this.connectUserDto != null) { | |
| 374 | - savedMemberDto = this.connectUserDto.getMemberDto(); | |
| 375 | - } | |
| 376 | - if (savedMemberDto != null) { | |
| 377 | - messageDto.setRouterSeq(savedMemberDto.getKakaoFtAgentCode()); | |
| 378 | - messageDto.setUnitCost(String.valueOf(savedMemberDto.getKakaoFtPrice())); | |
| 379 | - } | |
| 380 | - | |
| 381 | - saveLog("[KAKAO FRIEND] [MESSAGE : " + messageDto.toString() + "]"); | |
| 382 | - QueueTypeWorker worker = QueueTypeWorker.find("KFT"); | |
| 383 | - if (worker != null) { | |
| 384 | - worker.pushQueue(messageDto); | |
| 385 | - channel.write(KakaoMessage.makeDeliverAckBuffer(messageDto.getUserMsgID(), messageDto.getSendStatus())); | |
| 386 | - } | |
| 387 | - } catch (Exception e) { | |
| 388 | - e.printStackTrace(); | |
| 389 | - } | |
| 390 | - } | |
| 391 | - | |
| 392 | - private void recvLinkCheck(SocketChannel channel) throws IOException { | |
| 393 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(LinkCheck.LINK_CHECK_ACK_BODY_LENGTH); | |
| 394 | - channel.read(bodyBuffer); | |
| 395 | -// SocketChannel channel = (SocketChannel) key.channel(); | |
| 396 | - channel.write(LinkCheck.makeLinkCheckAckBuffer()); | |
| 397 | - /* 서비스 중지여부 체크 */ | |
| 398 | - if (isExpireService()) { | |
| 399 | - expireConnectUser(); | |
| 400 | - return; | |
| 401 | - } | |
| 402 | - } | |
| 403 | - | |
| 404 | - private void recvBind(SocketChannel channel, ByteBuffer headBuffer) { | |
| 405 | - String resultCode = "00"; | |
| 406 | - try { | |
| 407 | - ByteBuffer bindBuffer = ByteBuffer.allocate(Header.HEADER_LENGTH + Bind.BIND_BODY_LENGTH); | |
| 408 | - ByteBuffer bodyBuffer = ByteBuffer.allocate(Bind.BIND_BODY_LENGTH); | |
| 409 | - channel.read(bodyBuffer); | |
| 410 | - Packet.mergeBuffers(bindBuffer, headBuffer, bodyBuffer); | |
| 411 | - | |
| 412 | - String id = Bind.getBindId(bindBuffer); | |
| 413 | - String pwd = Bind.getBindPwd(bindBuffer); | |
| 414 | - | |
| 415 | - MemberService svc = (MemberService) CacheService.LOGIN_SERVICE.getService(); | |
| 416 | - MemberDto memberDto = null; | |
| 417 | - if (svc != null) { | |
| 418 | - memberDto = svc.get(id); | |
| 419 | - } | |
| 420 | - saveLog("[BIND REQUEST] [ID : " + id + ", PWD : " + pwd + "]"); | |
| 421 | - /* Bind Check */ | |
| 422 | - resultCode = checkBind(memberDto, this.serviceType, id, pwd); | |
| 423 | - | |
| 424 | - /* 접속 IP 체크 */ | |
| 425 | - if ("00".equals(resultCode)) { | |
| 426 | - boolean isPermit = false; | |
| 427 | - if (memberDto.getIpLimitYn() == null || "Y".equals(memberDto.getIpLimitYn())) { | |
| 428 | - saveLog("connectUserDto.getRemoteIP() : " + connectUserDto.getRemoteIP()); | |
| 429 | - saveLog("Customize Toolbar... : " + memberDto.getAllowIpBasic()); | |
| 430 | - saveLog("memberDto.getAllowIpExtend() : " + memberDto.getAllowIpExtend()); | |
| 431 | - if (memberDto.getAllowIpBasic() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpBasic())) { | |
| 432 | - isPermit = true; | |
| 433 | - } | |
| 434 | - if (memberDto.getAllowIpExtend() != null && connectUserDto.getRemoteIP().equals(memberDto.getAllowIpExtend())) { | |
| 435 | - isPermit = true; | |
| 436 | - } | |
| 437 | - } else { | |
| 438 | - isPermit = true; | |
| 439 | - } | |
| 440 | - if (isPermit) { | |
| 441 | - resultCode = "00"; | |
| 442 | - } else { | |
| 443 | - resultCode = "40"; | |
| 444 | - } | |
| 445 | - } | |
| 446 | - if ("00".equals(resultCode)) { | |
| 447 | - connectUserDto.setUserId(id); | |
| 448 | - connectUserDto.setLogin(true); | |
| 449 | - connectUserDto.setMemberDto(memberDto); | |
| 450 | - /* 사용자 Pool에 저장 */ | |
| 451 | - collectUserQueue.putUser(this.serviceType, connectUserDto); | |
| 452 | - /* 세션통신 시간 업데이트 */ | |
| 453 | - connectUserDto.updateLastTrafficTime(); | |
| 454 | - } | |
| 455 | - } catch (Exception e) { | |
| 456 | - resultCode = "10"; | |
| 457 | - e.printStackTrace(); | |
| 458 | - } | |
| 459 | - | |
| 460 | - try { | |
| 461 | - saveLog("[BIND RESULT : " + resultCode + "]"); | |
| 462 | - channel.write(Bind.makeBindAckBuffer(resultCode)); | |
| 463 | - if ("00".equals(resultCode) == false) { | |
| 464 | - expireConnectUser(); | |
| 465 | - } | |
| 466 | - } catch (IOException e) { | |
| 467 | - e.printStackTrace(); | |
| 468 | - } | |
| 469 | - } | |
| 470 | - | |
| 471 | - private String checkBind(MemberDto memberDto, String serviceType, String id, String pwd) { | |
| 472 | - if (id == null || pwd == null) { | |
| 473 | - return "50"; | |
| 474 | - } | |
| 475 | - if (collectUserQueue.isExist(this.serviceType, id)) { | |
| 476 | - return "60"; | |
| 477 | - } | |
| 478 | - if (memberDto == null || !pwd.equals(memberDto.getAccessKey())) { | |
| 479 | - return "20"; | |
| 480 | - } | |
| 481 | - /* 회원 사용 상태 */ | |
| 482 | - if (memberDto.getMberSttus() == null || "N".equals(memberDto.getMberSttus())) { | |
| 483 | - return "30"; | |
| 484 | - } | |
| 485 | - /* 서비스 이용 상태 */ | |
| 486 | - if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { | |
| 487 | - return "30"; | |
| 488 | - } | |
| 489 | - if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { | |
| 490 | - return "30"; | |
| 491 | - } | |
| 492 | - if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { | |
| 493 | - return "30"; | |
| 494 | - } | |
| 495 | - if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { | |
| 496 | - return "30"; | |
| 497 | - } | |
| 498 | - if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { | |
| 499 | - return "30"; | |
| 500 | - } | |
| 501 | - | |
| 502 | - return "00"; | |
| 503 | - } | |
| 504 | - | |
| 505 | - private String checkService(MemberDto memberDto, String serviceType) { | |
| 506 | - if ("SMS".equals(serviceType) && "N".equals(memberDto.getSmsUseYn())) { | |
| 507 | - return "30"; | |
| 508 | - } | |
| 509 | - if ("LMS".equals(serviceType) && "N".equals(memberDto.getLmsUseYn())) { | |
| 510 | - return "30"; | |
| 511 | - } | |
| 512 | - if ("MMS".equals(serviceType) && "N".equals(memberDto.getMmsUseYn())) { | |
| 513 | - return "30"; | |
| 514 | - } | |
| 515 | - if ("KAT".equals(serviceType) && "N".equals(memberDto.getKakaoAtUseYn())) { | |
| 516 | - return "30"; | |
| 517 | - } | |
| 518 | - if ("KFT".equals(serviceType) && "N".equals(memberDto.getKakaoFtUseYn())) { | |
| 519 | - return "30"; | |
| 520 | - } | |
| 521 | - | |
| 522 | - return "00"; | |
| 523 | - } | |
| 524 | - | |
| 525 | - private void expireConnectUser() { | |
| 526 | - if (key == null || !key.isValid()) { | |
| 527 | - return; | |
| 528 | - } | |
| 529 | - try { | |
| 530 | - SocketChannel channel = (SocketChannel) key.channel(); | |
| 531 | - if (connectUserDto != null) { | |
| 532 | - if (connectUserDto.getUserId() != null) { | |
| 533 | - collectUserQueue.removeUser(connectUserDto.getServiceType(), connectUserDto.getUserId()); | |
| 534 | - } | |
| 535 | - key.attach(null); | |
| 536 | - } | |
| 537 | - // 소켓 채널 닫기 | |
| 538 | - channel.close(); | |
| 539 | - // 키 닫기 | |
| 540 | - key.cancel(); | |
| 541 | - } catch (IOException e) { | |
| 542 | - e.printStackTrace(); | |
| 543 | - } | |
| 544 | - } | |
| 545 | - | |
| 546 | - private void saveSystemLog(Object obj) { | |
| 547 | - saveLog(obj, true); | |
| 548 | - } | |
| 549 | - | |
| 550 | - private void saveLog(Object obj) { | |
| 551 | - saveLog(obj, false); | |
| 552 | - } | |
| 553 | - | |
| 554 | - private void saveLog(Object obj, boolean isConsoleOutput) { | |
| 555 | - if (isConsoleOutput) { | |
| 556 | - System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern(LOG_DATE_FORMAT)) + " {{COLLECT_READ_TASK}} " + obj); | |
| 557 | - } | |
| 558 | - | |
| 559 | - if (logger == null) { | |
| 560 | - return; | |
| 561 | - } | |
| 562 | - | |
| 563 | - logger.log(obj); | |
| 564 | - } | |
| 565 | -} |
--- src/main/java/com/munjaon/server/util/XmlUtil.java
... | ... | @@ -1,125 +0,0 @@ |
| 1 | -package com.munjaon.server.util; | |
| 2 | - | |
| 3 | -import org.jdom2.Document; | |
| 4 | -import org.jdom2.Element; | |
| 5 | -import org.jdom2.JDOMException; | |
| 6 | -import org.jdom2.input.SAXBuilder; | |
| 7 | -import org.jdom2.output.Format; | |
| 8 | -import org.jdom2.output.XMLOutputter; | |
| 9 | - | |
| 10 | -import java.io.File; | |
| 11 | -import java.io.FileOutputStream; | |
| 12 | -import java.io.IOException; | |
| 13 | -import java.io.StringReader; | |
| 14 | -import java.util.List; | |
| 15 | - | |
| 16 | -public class XmlUtil { | |
| 17 | -// private static Document getDOMParsedDocument(final String fileName) { | |
| 18 | -// Document document = null; | |
| 19 | -// try { | |
| 20 | -// | |
| 21 | -// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
| 22 | -// //If want to make namespace aware. | |
| 23 | -// //factory.setNamespaceAware(true); | |
| 24 | -// DocumentBuilder documentBuilder = factory.newDocumentBuilder(); | |
| 25 | -// document = documentBuilder.parse(new File("C:\\Docs\\JDS\\ITN\\MMS01Header.xml")); | |
| 26 | -// | |
| 27 | -// NodeList nodeList = document.getDocumentElement().getChildNodes(); | |
| 28 | -// for (int i = 0; i < nodeList.getLength(); i++) { | |
| 29 | -// Node node = nodeList.item(i); | |
| 30 | -// if (node.getNodeType() == Node.ELEMENT_NODE) { | |
| 31 | -// Element elem = (Element) node; | |
| 32 | -// System.out.println("createDate : " + elem.getAttribute("createDate")); | |
| 33 | -// System.out.println("getTagName : " + elem.getTagName()); | |
| 34 | -// System.out.println("getNodeName : " + elem.getNodeName()); | |
| 35 | -// System.out.println("getTextContent : " + elem.getTextContent()); | |
| 36 | -//// String createDate = elem.getElementsByTagName("createDate").item(0).getChildNodes().item(0).getNodeValue(); | |
| 37 | -//// System.out.println("createDate : " + createDate); | |
| 38 | -//// String PopCounter = elem.getElementsByTagName("PopCounter").item(0).getChildNodes().item(0).getNodeValue(); | |
| 39 | -//// System.out.println("PopCounter : " + PopCounter); | |
| 40 | -//// Double salary = Double.parseDouble(elem.getElementsByTagName("salary").item(0).getChildNodes().item(0).getNodeValue()); | |
| 41 | -// } | |
| 42 | -// } | |
| 43 | -// } | |
| 44 | -// catch (IOException | SAXException | ParserConfigurationException e) { | |
| 45 | -// e.printStackTrace(); | |
| 46 | -// } | |
| 47 | -// return document; | |
| 48 | -// } | |
| 49 | - | |
| 50 | - private static Document getSaxParsedDocument(final String fileName) { | |
| 51 | - Document document = null; | |
| 52 | - | |
| 53 | - String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
| 54 | - + " <catalog>\r\n" | |
| 55 | - + " <book id=\"bk101\">" | |
| 56 | - + " <author>Gambardella, Matthew</author> " | |
| 57 | - + "<title>XML Developer's Guide</title>" | |
| 58 | - + " <genre>Computer</genre>" | |
| 59 | - + " <price>44.95</price> " | |
| 60 | - + "<publish_date>2000-10-01</publish_date> " | |
| 61 | - + "<description>An in-depth look at creating applications with XML.</description> " | |
| 62 | - + "</book>" | |
| 63 | - + " <book id=\"bk102\">" | |
| 64 | - + " <author>Ralls, Kim</author>" | |
| 65 | - + " <title>Midnight Rain</title>" | |
| 66 | - + " <genre>Fantasy</genre>" | |
| 67 | - + " <price>5.95</price>" | |
| 68 | - + " <publish_date>2000-12-16</publish_date>" | |
| 69 | - + " <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>" | |
| 70 | - + " </book> \r\n" | |
| 71 | - + "</catalog>\r\n"; | |
| 72 | - try { | |
| 73 | - | |
| 74 | - SAXBuilder sax = new SAXBuilder(); | |
| 75 | - // String that contains XML | |
| 76 | - Document doc = (Document) sax.build(new File("C:\\Docs\\JDS\\ITN\\MMS01Header.xml")); | |
| 77 | -// org.jdom2.Document doc = sax.build(new StringReader(xml)); | |
| 78 | - | |
| 79 | - Element rootNode = doc.getRootElement(); | |
| 80 | - List<Element> bookElements = rootNode.getChildren(); | |
| 81 | - System.out.println("bookElements: " + bookElements); | |
| 82 | - for(Element bookElement : bookElements){ | |
| 83 | - String name = bookElement.getName(); | |
| 84 | - String value = bookElement.getValue(); | |
| 85 | - System.out.println(name + " : " + value); | |
| 86 | - } | |
| 87 | - | |
| 88 | - } catch (IOException | JDOMException e) { | |
| 89 | - e.printStackTrace(); | |
| 90 | - } | |
| 91 | - return document; | |
| 92 | - } | |
| 93 | - | |
| 94 | - private static void writeSimpleXml() throws JDOMException, IOException { | |
| 95 | - | |
| 96 | - String xml = "<root><child id=\"100\">mkyong</child></root>"; | |
| 97 | - SAXBuilder sb = new SAXBuilder(); | |
| 98 | - Document doc = sb.build(new StringReader(xml)); | |
| 99 | - | |
| 100 | - | |
| 101 | - Document docFile = new Document(); | |
| 102 | - | |
| 103 | - Element rootElement = new Element("ReadQueue"); | |
| 104 | - rootElement.addContent(new Element("createDate").setText("20240527")); | |
| 105 | - rootElement.addContent(new Element("PopCounter").setText(Integer.toString(0))); | |
| 106 | - | |
| 107 | - docFile.setRootElement(rootElement); | |
| 108 | - | |
| 109 | - // default in compact mode | |
| 110 | - // XMLOutputter xmlOutputter = new XMLOutputter(); | |
| 111 | - | |
| 112 | - // pretty print format | |
| 113 | - XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat()); | |
| 114 | - | |
| 115 | - // output to console | |
| 116 | - FileOutputStream fileOutputStream = new FileOutputStream("C:\\Docs\\JDS\\ITN\\file.xml"); | |
| 117 | - xmlOutputter.output(docFile, fileOutputStream); | |
| 118 | - | |
| 119 | - } | |
| 120 | - public static void main(String[] args) throws IOException, JDOMException { | |
| 121 | -// XmlUtil.getDOMParsedDocument("C:\\Docs\\JDS\\ITN\\MMS01Header.xml"); | |
| 122 | - XmlUtil.getSaxParsedDocument("C:\\Docs\\JDS\\ITN\\MMS01Header.xml"); | |
| 123 | - XmlUtil.writeSimpleXml(); | |
| 124 | - } | |
| 125 | -} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?