Browse Source

feat: WebSocket 실시간 수정 데이터 반영기능추가, WebSocket 접속 유저 그룹 분리

feature/dos/statistics
lkd9125(이경도) 2 weeks ago
parent
commit
81ad455de0
  1. 8
      http/server/server.http
  2. 23
      pav-websocket/src/main/java/com/palnet/server/collection/ChannelCollection.java
  3. 23
      pav-websocket/src/main/java/com/palnet/server/controller/SocketReceiverController.java
  4. 5
      pav-websocket/src/main/java/com/palnet/server/handler/WebHandler.java
  5. 34
      pav-websocket/src/main/java/com/palnet/server/handler/WebPathHandler.java
  6. 28
      pav-websocket/src/main/java/com/palnet/server/initializer/WebInitializer.java
  7. 11
      pav-websocket/src/main/java/com/palnet/server/model/DosUpdateRQ.java
  8. 2
      pav-websocket/src/main/java/com/palnet/server/task/ctr/CtrCntrlTask.java

8
http/server/server.http

@ -265,4 +265,10 @@ Authorization: {{accessToken}}
### 비행 관제 사용자 권한 정보
GET {{appHost}}/api/ctr/cntrl/group
Authorization: {{accessToken}}
Authorization: {{accessToken}}
### WS
WEBSOCKET ws://localhost:8081/ws
### DOS
WEBSOCKET ws://localhost:8081/ws/dos

23
pav-websocket/src/main/java/com/palnet/server/collection/ChannelCollection.java

@ -12,15 +12,36 @@ public class ChannelCollection {
//접속 되어있는 모든 Channel
private static final ChannelGroup allChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
private static final ChannelGroup wsChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
private static final ChannelGroup dosChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
public void setAllChannels(Channel ch) {
allChannels.add(ch);
}
public static void setChannels(Channel ch, String uri) {
switch (uri){
case "/ws":
wsChannels.add(ch);
break;
case "/dos":
dosChannels.add(ch);
break;
}
}
public ChannelGroup getAllChannels() {
public static ChannelGroup getAllChannels() {
return allChannels;
}
public static ChannelGroup getWsChannels() {
return wsChannels;
}
public static ChannelGroup getDosChannels() {
return dosChannels;
}
}

23
pav-websocket/src/main/java/com/palnet/server/controller/SocketReceiverController.java

@ -5,7 +5,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.palnet.comn.model.CtrCntrlModel;
import com.palnet.comn.model.CtrHistoryShareContext;
import com.palnet.comn.model.GPModel;
import com.palnet.server.collection.ChannelCollection;
import com.palnet.server.model.DosUpdateRQ;
import com.palnet.server.task.ctr.service.CtrCntrlTaskService;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
@ -64,4 +68,23 @@ public class SocketReceiverController {
return "OK";
};
}
@PostMapping("/dos/flush")
public void dataFlush(@RequestBody DosUpdateRQ rq){
log.warn("rq => {}", rq);
if(rq.getPlanAreaSnoList() != null){
try {
String json = objectMapper.writeValueAsString(rq);
ChannelGroup dosChannel = ChannelCollection.getDosChannels();
dosChannel.writeAndFlush(new TextWebSocketFrame(json));
} catch (JsonProcessingException e) {
log.error("", e);
}
} else {
log.error("RQ IS NULL :: {}", rq);
}
}
}

5
pav-websocket/src/main/java/com/palnet/server/handler/WebHandler.java

@ -119,5 +119,8 @@ public class WebHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
logger.info("==================== [ channelRegistered ] ==================== ");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.error("", cause);
}
}

34
pav-websocket/src/main/java/com/palnet/server/handler/WebPathHandler.java

@ -0,0 +1,34 @@
package com.palnet.server.handler;
import com.palnet.server.collection.ChannelCollection;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import lombok.extern.slf4j.Slf4j;
import java.net.URI;
@Slf4j
public class WebPathHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
if(msg != null){
URI url = new URI(msg.uri());
String uri = url.getPath();
switch (uri) {
case "/dos":
case "/ws":
ChannelCollection.setChannels(ctx.channel(), uri);
break;
default:
throw new RuntimeException("Path Not Found");
}
msg.setUri("/ws");
ctx.fireChannelRead(msg.retain());
}
}
}

28
pav-websocket/src/main/java/com/palnet/server/initializer/WebInitializer.java

@ -3,31 +3,39 @@ package com.palnet.server.initializer;
import com.palnet.server.codec.WebPayLoadDecoder;
import com.palnet.server.codec.WebPayLoadEncorder;
import com.palnet.server.handler.WebHandler;
import com.palnet.server.handler.WebPathHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpServerExpectContinueHandler;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.codec.json.JsonObjectDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class WebInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline
.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(65536))
.addLast(new WebSocketServerCompressionHandler())
.addLast(new WebSocketServerProtocolHandler("/ws", null, true))
.addLast(new IdleStateHandler(0, 0, 180)) // [5]
.addLast(new WebPayLoadDecoder() , new WebPayLoadEncorder())
.addLast(new WebHandler());
.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(65536))
.addLast(new WebSocketServerCompressionHandler())
.addLast(new HttpServerExpectContinueHandler())
.addLast(new WebPathHandler()) // 분기처리 핸들러
.addLast(new WebSocketServerProtocolHandler("/ws")) // 핸드쉐이크를 위한 핸들러 [핸드쉐이크가 성공해야 연결]
.addLast(new WebHandler()) // 웹소켓 연결 후 핸들러
.addLast(new IdleStateHandler(0, 0, 180)) // [5]
.addLast(new WebPayLoadDecoder() , new WebPayLoadEncorder())
;
}
}

11
pav-websocket/src/main/java/com/palnet/server/model/DosUpdateRQ.java

@ -0,0 +1,11 @@
package com.palnet.server.model;
import lombok.Data;
import java.util.List;
@Data
public class DosUpdateRQ {
private List<Integer> planAreaSnoList;
}

2
pav-websocket/src/main/java/com/palnet/server/task/ctr/CtrCntrlTask.java

@ -26,7 +26,7 @@ public class CtrCntrlTask implements Runnable{
public void run() {
try {
// logger.info(">>> run : {}", cc.getAllChannels());
cc.getAllChannels().stream().forEach(c -> { // 접속되어 있는 모든 사용자에게 전달 처리
cc.getWsChannels().stream().forEach(c -> { // 접속되어 있는 모든 사용자에게 전달 처리
c.writeAndFlush(new TextWebSocketFrame(JsonUtils.toJson(service.getList())));
});
}catch(Exception e) {

Loading…
Cancel
Save