Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/deploy #8

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
429c005
feat : websocketDTO
david-parkk Apr 14, 2024
5ee53ad
feat : websocket handler
david-parkk Apr 14, 2024
650e30c
feat : test controller
david-parkk Apr 14, 2024
7a477ad
feat : test view
david-parkk Apr 14, 2024
185cf30
feat : scheduler
david-parkk Apr 14, 2024
94f8c6d
refactor : testController -> WebSocketController
david-parkk Apr 14, 2024
eebd105
refactor : naming change
david-parkk Apr 14, 2024
4354564
feat : websocket custom handler
david-parkk Apr 14, 2024
e08bb00
refactor : handler 분리
david-parkk Apr 14, 2024
dd31428
Merge branch 'main' of https://github.com/KU-Taverse/game-server-BE- …
david-parkk Apr 15, 2024
30d5c39
feat : user entity 변경
david-parkk Apr 16, 2024
e350c1c
feat : add builder
david-parkk Apr 16, 2024
ac78d50
feat : dto 관련 update function 추가
david-parkk Apr 16, 2024
fa44c1e
fix : custom handler, mapping (더 나은 방법이 분명 있을 것 입니다)
david-parkk Apr 16, 2024
3250a56
feat : sendMessageToClients 변경
david-parkk Apr 16, 2024
a019431
feat : Status class
david-parkk Apr 16, 2024
02861d4
fix : test code
david-parkk Apr 16, 2024
45df74c
fixed : 1초 schduler
david-parkk Apr 18, 2024
c292cff
fix : index.html
david-parkk Apr 18, 2024
9cf1953
fix : message Mono<List<User>>으로 보내도록 설정
david-parkk Apr 18, 2024
5361be1
fix: status 처리
david-parkk May 1, 2024
e65941b
feat: dockerfile
david-parkk May 1, 2024
36ac22f
fix : gitignore 수정
david-parkk May 1, 2024
890bcdb
feat: compose.yml
david-parkk May 1, 2024
68ea338
feat: 배포 스크립트 추가
david-parkk May 1, 2024
f1ee9bd
feat : workflow_dispatcher
david-parkk May 1, 2024
eb172a5
feat: workfloew_dispatch
david-parkk May 1, 2024
b940977
nothing : PR text
david-parkk May 1, 2024
a0868f4
fix : conflict 해결
david-parkk May 1, 2024
f0a4ee6
fix : conflict 해결
david-parkk May 1, 2024
314753c
feat : port 추가
david-parkk May 1, 2024
1160932
fix : rm command 제거
david-parkk May 1, 2024
d9aa11f
fix : rm 삭제
david-parkk May 1, 2024
d9eeb5e
fix
david-parkk May 1, 2024
af78520
fix
david-parkk May 1, 2024
3f9dc24
fix
david-parkk May 1, 2024
668f6f1
fix
david-parkk May 1, 2024
d52d7f9
fix
david-parkk May 1, 2024
4deaf7d
fix
david-parkk May 1, 2024
5ce2244
fix
david-parkk May 1, 2024
59f27f2
fix
david-parkk May 1, 2024
c9338f3
fix
david-parkk May 3, 2024
815b2d0
fix
david-parkk May 3, 2024
48b3b4f
fix
david-parkk May 3, 2024
67c05cb
fix
david-parkk May 3, 2024
64cbb8b
fix
david-parkk May 3, 2024
438f654
fix
david-parkk May 3, 2024
1682f04
fix
david-parkk May 3, 2024
5588915
fix
david-parkk May 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/pr-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:
branches: [ "main" ]
workflow_dispatch:


jobs:
build:

Expand Down Expand Up @@ -79,4 +80,60 @@ jobs:
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0

deploy:
runs-on: ubuntu-latest
permissions:
write-all
#contents: read

steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

# Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Setup Gradle
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0

- name: Build with Gradle Wrapper
run: ./gradlew build
# dockerfile을 통해 이미지를 빌드하고, 이를 docker repo로 push 합니다.
# 이 때 사용되는 ${{ secrets.DOCKER_REPO }} 가 위에서 만든 도커 repository 입니다.
- name: Docker build & push to docker repo
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -f Dockerfile -t ${{ secrets.DOCKER_REPO }} .
docker push ${{ secrets.DOCKER_REPO }}

# appleboy/ssh-action@master 액션을 사용하여 지정한 서버에 ssh로 접속하고, script를 실행합니다.
# script의 내용은 도커의 기존 프로세스들을 제거하고, docker repo로부터 방금 위에서 push한 내용을 pull 받아 실행하는 것입니다.
# 실행 시, docker-compose를 사용합니다.
- name: Deploy to server
uses: appleboy/ssh-action@master
env:
COMPOSE: ${{ secrets.DOCKER_PATH }}
id: deploy
with:
host: ${{ secrets.HOST }}
username: ubuntu
port: 22
key: ${{ secrets.KEY }}
envs: GITHUB_SHA
script: |
sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
echo ${{secrets.PROJECT_PATH}}
cd ${{secrets.PROJECT_PATH}}
sudo docker-compose stop

sudo docker rm $(docker ps -a -q)
sudo docker rmi ${{ secrets.DOCKER_USERNAME }}/sample-repository
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/sample-repository

sudo docker-compose up --build -d
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*.yml
application.yml
HELP.md
.gradle
build/
Expand Down
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#FROM openjdk:17-jdk
#LABEL maintainer="email"
#ARG JAR_FILE=build/libs/docker-0.0.1-SNAPSHOT.jar
#ADD ${JAR_FILE} docker-springboot.jar
#ENTRYPOINT ["java","-jar","/docker-springboot.jar"]

FROM openjdk:17-jdk

# build가 되는 시점에 JAR_FILE이라는 변수 명에 build/libs/*.jar 선언
# build/libs - gradle로 빌드했을 때 jar 파일이 생성되는 경로
ARG JAR_FILE=build/libs/*.jar

# JAR_FILE을 app.jar로 복사
COPY ${JAR_FILE} app.jar

# 운영 및 개발에서 사용되는 환경 설정을 분리
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "/app.jar"]
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ dependencies {
tasks.named('test') {
useJUnitPlatform()
}
jar {
enabled = false
}

16 changes: 16 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: '3'
services:
redis:
image: redis
ports:
- 6379:6379
springbootapp:
image: ji0513ji/sample-repository:v1.0.0
# build:
# context: .
# dockerfile: Dockerfile
ports:
- 8080:8080
depends_on:
- redis

2 changes: 2 additions & 0 deletions src/main/java/kutaverse/game/DemoApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package kutaverse.game.map.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.reactive.result.view.Rendering;
import reactor.core.publisher.Mono;

@Controller
public class WebSocketController {
@GetMapping("/")
public Mono<Rendering> home() {
return Mono.just(Rendering.view("index").build());
}
}
5 changes: 5 additions & 0 deletions src/main/java/kutaverse/game/map/domain/Status.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package kutaverse.game.map.domain;

public enum Status {
JUMP,STAND
}
29 changes: 22 additions & 7 deletions src/main/java/kutaverse/game/map/domain/User.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
package kutaverse.game.map.domain;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;

@Getter
@RedisHash(value = "user", timeToLive = 30) //초단위
@NoArgsConstructor
@ToString
public class User {

@Id
private String key;

private String name;

private Integer positionX;

private Integer positionY;

private Integer positionZ;

private Integer eulerAngleX;

private Integer eulerAngleY;

public User(String key, String name) {
this.key=key;
this.name = name;
positionX=0;
positionY=0;
private Integer eulerAngleZ;

private Status status;

@Builder
public User(String key, Integer positionX, Integer positionY, Integer positionZ, Integer eulerAngleX, Integer eulerAngleY, Integer eulerAngleZ, Status status) {
this.key = key;
this.positionX = positionX;
this.positionY = positionY;
this.positionZ = positionZ;
this.eulerAngleX = eulerAngleX;
this.eulerAngleY = eulerAngleY;
this.eulerAngleZ = eulerAngleZ;
this.status = status;
}

}
35 changes: 35 additions & 0 deletions src/main/java/kutaverse/game/map/dto/UserRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package kutaverse.game.map.dto;

import kutaverse.game.map.domain.Status;
import kutaverse.game.map.domain.User;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
public class UserRequestDto {

private String userId;
private String positionX;
private String positionY;
private String positionZ;
private String eulerAngleX;
private String eulerAngleY;
private String eulerAngleZ;
private String status;

public User toEntity(){
return User.builder()
.key(userId)
.positionX(Integer.valueOf(positionX))
.positionY(Integer.valueOf(positionY))
.positionZ(Integer.valueOf(positionZ))
.eulerAngleX(Integer.valueOf(eulerAngleX))
.eulerAngleY(Integer.valueOf(eulerAngleY))
.eulerAngleZ(Integer.valueOf(eulerAngleZ))
.status(Status.valueOf(status))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kutaverse.game.map.service;

import kutaverse.game.map.domain.User;
import kutaverse.game.map.dto.UserRequestDto;
import kutaverse.game.map.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -32,4 +33,10 @@ public Mono<User> findOne(String id) {
public Mono<Long> deleteById(String key) {
return userRepository.delete(key);
}

@Override
public Mono<User> update(UserRequestDto userRequestDto) {
return create(userRequestDto.toEntity());
}

}
3 changes: 3 additions & 0 deletions src/main/java/kutaverse/game/map/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kutaverse.game.map.service;

import kutaverse.game.map.domain.User;
import kutaverse.game.map.dto.UserRequestDto;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

Expand All @@ -13,4 +14,6 @@ public interface UserService {
Mono<User> findOne(String key);

Mono<Long> deleteById(String key);

Mono<User> update(UserRequestDto userRequestDto);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package kutaverse.game.map.websocket;

import kutaverse.game.map.websocket.handler.WebSocketHandler;
import kutaverse.game.map.websocket.handler.WebSocketHandlerMapping;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.socket.WebSocketSession;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Sinks;


@Component
@Slf4j
public class CustomWebSocketHandler implements org.springframework.web.reactive.socket.WebSocketHandler {

private final Sinks.Many<String> sink;

public CustomWebSocketHandler(Sinks.Many<String> sink) {
this.sink = sink;
}
public Mono<Void> sendMessageToAllClients(String message) {
sink.emitNext(message, Sinks.EmitFailureHandler.FAIL_FAST);
return null;
}

@Override
public Mono<Void> handle(WebSocketSession session) {
var output = session.receive()
// 메시지를 JSON 객체로 변환
.map(e -> e.getPayloadAsText())
.map(e -> {
WebSocketHandler webSocketHandler= WebSocketHandlerMapping.getHandler(e);
return webSocketHandler.handle(e);
});

output.subscribe(s -> sink.emitNext(s, Sinks.EmitFailureHandler.FAIL_FAST));

return session.send(sink.asFlux().map(session::textMessage));
}
}
54 changes: 54 additions & 0 deletions src/main/java/kutaverse/game/map/websocket/MessageSender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package kutaverse.game.map.websocket;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import kutaverse.game.map.domain.User;
import kutaverse.game.map.service.UserService;
import lombok.RequiredArgsConstructor;
import org.reactivestreams.Publisher;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class MessageSender {

private final CustomWebSocketHandler webSocketHandler;

private final UserService userService;

ObjectMapper objectMapper=new ObjectMapper();

@Scheduled(fixedRate = 1000) // 5초마다 실행
public void sendMessageToClients() {
Mono<String> result=Mono.just("");

userService.findAll()
.collectList()
.flatMap(u -> {
String combinedUsers = u.stream()
.map(Object::toString)
.collect(Collectors.joining(" "));
// 기존의 result Mono에 새로운 값을 추가하여 반환
return result.map(existingValue -> existingValue + " " + combinedUsers);

}).subscribe(this::sendUsersAsJsonToClients);

}

private Mono<Void> sendUsersAsJsonToClients(String user) {
try {
String json = objectMapper.writeValueAsString(user);
return webSocketHandler.sendMessageToAllClients(json);

} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
Loading
Loading