Browse Source

feat: websocket client drone data 전송 방식 변경(scheduled -> call)

https://www.notion.so/PAV-KAC-websocket-client-schedule-call-25d5df23be114f8997aee9b2b51697f4?pvs=4
feature/socket
지대한 6 months ago
parent
commit
7f0a159b9e
  1. 2
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/SandboxDroneCommandImpl.java
  2. 1
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/handler/DroneHandler.java
  3. 2
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/socket/SocketServer.java
  4. 3
      app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/service/ScheduledService.java
  5. 40
      app/kac-socket-app/src/main/resources/application.yml
  6. 49
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/codec/ControlDecoder.java
  7. 44
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/handler/WebSocketHandler.java
  8. 15
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/model/BoundaryCoordinates.java
  9. 19
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/model/ControlRq.java
  10. 15
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/model/ErrorRs.java
  11. 2
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/socket/ChannelInitializer.java
  12. 13
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/service/ControlService.java
  13. 2
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/service/ScheduledService.java
  14. 33
      app/kac-websocket-app/src/main/resources/application.yml
  15. 17
      http-client/http/ws.http
  16. 1
      web/security/src/main/java/kr/co/palnet/kac/config/security/filter/JwtCheckFilter.java

2
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/command/impl/SandboxDroneCommandImpl.java

@ -107,7 +107,7 @@ public class SandboxDroneCommandImpl implements DroneCommand {
}
Long end = System.currentTimeMillis();
log.debug(">>> during time : {} - {}", drone.getObjectId(), end - start);
// log.debug(">>> during time : {} - {}", drone.getObjectId(), end - start);
} else {
log.error("좌표 정보가 존재하지 않습니다.");

1
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/handler/DroneHandler.java

@ -65,7 +65,6 @@ public class DroneHandler extends SimpleChannelInboundHandler<DroneRq> {
return;
}
log.debug(">>> rq : {}", rq);
DroneCommand commandService = commandMap.get(rq.getCommand().trim());
if (commandService == null) {

2
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/core/socket/SocketServer.java

@ -19,7 +19,6 @@ public class SocketServer {
private Channel serverChannel;
public void start() {
log.debug(">>>>> start <<<<<");
try {
// ChannelFuture: I/O operation의 결과나 상태를 제공하는 객체
// 지정한 host, port로 소켓을 바인딩하고 incoming connections을 받도록 준비함
@ -36,7 +35,6 @@ public class SocketServer {
// Bean을 제거하기 전에 해야할 작업이 있을 때 설정
@PreDestroy
public void stop() {
log.debug(">>>>> stop <<<<<");
if (serverChannel != null) {
serverChannel.close();
serverChannel.parent().closeFuture();

3
app/kac-socket-app/src/main/java/kr/co/palnet/kac/socket/service/ScheduledService.java

@ -104,10 +104,7 @@ public class ScheduledService {
// 사용을 다한 데이터 제거
@Scheduled(fixedDelay = 30 * 1000)
public void removeDrone() {
log.info(">>>> removeDrone <<<<<");
DroneStorage droneStorage = DroneStorage.getInstance();
Map<String, List<DroneDto>> all = droneStorage.getAll();
droneStorage.removeByCondition();
}

40
app/kac-socket-app/src/main/resources/application.yml

@ -1,3 +1,8 @@
spring:
threads:
virtual:
enabled: true
netty:
socket:
tcp-port: 8003
@ -6,6 +11,9 @@ netty:
tcp-nodelay: false
backlog: 3000
server:
port: 8004
app:
kac-app:
host: http://127.0.0.1:8000
@ -14,14 +22,6 @@ app:
web-socket-web:
host: http://127.0.0.1:8002
server:
port: 8004
spring:
threads:
virtual:
enabled: true
logging:
level:
kr.co.palnet: debug
@ -33,9 +33,17 @@ spring:
activate:
on-profile: local
app:
kac-app:
host: http://127.0.0.1:8000
web-socket:
host: http://127.0.0.1:8001
web-socket-web:
host: http://127.0.0.1:8002
logging:
level:
kr.co.palnet: info
kr.co.palnet: debug
---
@ -43,17 +51,6 @@ spring:
config:
activate:
on-profile: docker
threads:
virtual:
enabled: true
netty:
socket:
tcp-port: 8003
boss-count: 1
keep-alive: false
tcp-nodelay: false
backlog: 3000
app:
kac-app:
@ -63,9 +60,6 @@ app:
web-socket-web:
host: http://kac-websocket-app:8002
server:
port: 8004
logging:
level:
kr.co.palnet: info

49
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/codec/ControlDecoder.java

@ -0,0 +1,49 @@
package kr.co.palnet.kac.websocket.core.codec;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionDecoder;
import kr.co.palnet.kac.util.ObjectMapperUtil;
import kr.co.palnet.kac.websocket.core.model.BoundaryCoordinates;
import kr.co.palnet.kac.websocket.core.model.ControlRq;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
@RequiredArgsConstructor
public class ControlDecoder extends WebSocketExtensionDecoder {
private final ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
@Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame msg, List<Object> out) throws Exception {
try {
if (msg instanceof TextWebSocketFrame textWebSocketFrame) {
String json = textWebSocketFrame.text();
JsonNode jsonNode = objectMapper.readTree(json);
String type = jsonNode.get("type").asText();
switch (type) {
case "CURRENT_DRONE":
ControlRq<List<BoundaryCoordinates>> controlRq = objectMapper.readValue(json, new TypeReference<>() {
});
out.add(controlRq);
break;
default:
log.warn("decode type is empty.");
break;
}
}
} catch (Exception e) {
log.warn("decode parsing error : {}\ndata in : {}", e.getMessage(), msg);
}
}
}

44
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/handler/WebSocketHandler.java

@ -1,23 +1,57 @@
package kr.co.palnet.kac.websocket.core.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import kr.co.palnet.kac.util.ObjectMapperUtil;
import kr.co.palnet.kac.websocket.core.model.BoundaryCoordinates;
import kr.co.palnet.kac.websocket.core.model.ControlRq;
import kr.co.palnet.kac.websocket.core.model.ErrorRs;
import kr.co.palnet.kac.websocket.core.storage.ChannelStorage;
import kr.co.palnet.kac.websocket.service.ControlService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@RequiredArgsConstructor
@ChannelHandler.Sharable
@Component
public class WebSocketHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
public class WebSocketHandler extends SimpleChannelInboundHandler<ControlRq<Object>> {
public WebSocketHandler() {
}
private final ControlService controlService;
private final ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
@Override
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
protected void channelRead0(ChannelHandlerContext ctx, ControlRq rq) throws Exception {
log.info("read :: {}", rq);
Object result = null;
switch (rq.getType()) {
case "CURRENT_DRONE":
if (rq.getBody() == null) {
// BoundaryCoordinates
log.warn("CURRENT_DRONE::boundary coordinates is null");
return;
}
log.info(">>class {}", rq.getBody().getClass().getName());
List<BoundaryCoordinates> list = (List<BoundaryCoordinates>) rq.getBody();
result = controlService.getList(list);
break;
default:
log.warn("type is not supported.");
result = ErrorRs.builder()
.code("-400")
.message("bad request : type error")
.build();
break;
}
String json = objectMapper.writeValueAsString(result);
ctx.channel().writeAndFlush(new TextWebSocketFrame(json));
}
@Override

15
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/model/BoundaryCoordinates.java

@ -0,0 +1,15 @@
package kr.co.palnet.kac.websocket.core.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BoundaryCoordinates {
private double lat;
private double lon;
}

19
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/model/ControlRq.java

@ -0,0 +1,19 @@
package kr.co.palnet.kac.websocket.core.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ControlRq<T> {
private String type;
private T body;
}

15
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/model/ErrorRs.java

@ -0,0 +1,15 @@
package kr.co.palnet.kac.websocket.core.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ErrorRs {
private String code;
private String message;
}

2
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/core/socket/ChannelInitializer.java

@ -7,6 +7,7 @@ import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.timeout.IdleStateHandler;
import kr.co.palnet.kac.websocket.core.codec.ControlDecoder;
import kr.co.palnet.kac.websocket.core.handler.WebSocketHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -29,6 +30,7 @@ public class ChannelInitializer extends io.netty.channel.ChannelInitializer<Sock
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler("/ws", null, true));
pipeline.addLast(new IdleStateHandler(0, 0, 180));
pipeline.addLast(new ControlDecoder());
pipeline.addLast(webSocketHandler);
}
}

13
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/service/ControlService.java

@ -2,6 +2,7 @@ package kr.co.palnet.kac.websocket.service;
import kr.co.palnet.kac.common.model.common.DroneControlDto;
import kr.co.palnet.kac.common.model.common.DroneDto;
import kr.co.palnet.kac.websocket.core.model.BoundaryCoordinates;
import kr.co.palnet.kac.websocket.core.storage.ControlStorage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -14,6 +15,18 @@ import java.util.*;
@Service
public class ControlService {
public List<DroneControlDto> getList(List<BoundaryCoordinates> coordinatesList) {
ControlStorage controlStorage = ControlStorage.getInstance();
List<DroneControlDto> controlDtoList = controlStorage.getList();
if (controlDtoList == null || controlDtoList.isEmpty()) return new ArrayList<>();
controlDtoList.sort(Comparator.reverseOrder());
return controlDtoList;
}
public DroneControlDto dronDtoToControlDtoConvert(DroneDto dronDto) {
ControlStorage controlCache = ControlStorage.getInstance();

2
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/service/ScheduledService.java

@ -25,7 +25,7 @@ public class ScheduledService {
// 접속한 모든 채널에 데이터 전송
@Scheduled(fixedDelay = 10 * 1000) // 10초
// @Scheduled(fixedDelay = 10 * 1000) // 10초
public void sendAllChannel() {
// 채널 가져오기
ChannelStorage channelStorage = ChannelStorage.getInstance();

33
app/kac-websocket-app/src/main/resources/application.yml

@ -1,3 +1,8 @@
spring:
threads:
virtual:
enabled: true
netty:
socket:
tcp-port: 8001
@ -6,36 +11,30 @@ netty:
tcp-nodelay: true
backlog: 3000
---
spring:
config:
activate:
on-profile: local
app:
kac-app:
host: http://127.0.0.1:8000
spring:
threads:
virtual:
enabled: true
host: http://kac-app:8000
server:
port: 8002
logging:
level:
kr.co.palnet: debug
---
spring:
config:
activate:
on-profile: docker
threads:
virtual:
enabled: true
netty:
socket:
tcp-port: 8001
boss-count: 1
keep-alive: true
tcp-nodelay: true
backlog: 3000
app:
kac-app:

17
http-client/http/ws.http

@ -1,5 +1,20 @@
### 신규 websocket
WEBSOCKET {{wsHost}}/ws
#Content-Type: application-json
{
"type": "CURRENT_DRONE",
"body": [
{
"lat": 111.000,
"lon": 222.22
}
]
}
===
### 신규 websocket
WEBSOCKET {{wsHost}}/ws
### 신규 websocket
@ -15,6 +30,7 @@ WEBSOCKET ws://localhost:18001/ws
### 기존 websocket
WEBSOCKET ws://localhost:8081/ws
#Content-Type: application-json
#
#{"test": "test"}
@ -22,3 +38,4 @@ WEBSOCKET ws://localhost:8081/ws
#{"test2": "test2"}
#=== wait-for-server
#{"test3": "test3"}

1
web/security/src/main/java/kr/co/palnet/kac/config/security/filter/JwtCheckFilter.java

@ -53,7 +53,6 @@ public class JwtCheckFilter extends BasicAuthenticationFilter {
} catch (TokenExpiredException e) {
throw new BaseAuthenticationException(BaseAuthErrorCode.EXPIRED_TOKEN);
} catch (Exception e) {
log.debug(">>> e : {}", e.getClass().getName());
throw new BaseAuthenticationException(BaseAuthErrorCode.INVALID_TOKEN);
}

Loading…
Cancel
Save