알림서비스를 구현하기 위해서는 gRPC 와 RESTFul API 서버가 동시에 사용해야 했다. EXPO 에서는 네이티브 모듈을 직접 추가할 수 없기 때문에 gRPC 를 직접 호출하는 것은 불가능했다. 따라서 이것을 해결하기 위해 채팅서비스와 알림서비스 간의 통신은 gRPC 를 활용하고, EXPO 에는 REST API 를 사용해야 했다.
0. 두개의 서버를 동시에 사용해야 하는 이유
처음 설계시, 채팅서비스와 알림서비스 그리고 EXPO 간 통신을 모두 gRPC 를 사용하기로 하였다. 새로운 기술을 사용해 보고자 했으며 알림 서비스의 경우 무결성의 제약에 엄격하지 않았기 때문이다. 하지만 개발을 진행하는 과정에서 EXPO 는 gRPC 를 기본적으로 지원하지 않는다는 것을 알게 되었다. 또한, 알림 기능을 사용하려면 Push Token 이 필요하며, EXPO 에서 로그인 시 알림 동의 여부에 따라 Push Token 이 발급된다는 점도 확인했다. 해당 Push Token 은 Firebase 또는 자체 구축한 DB 에 저장되어야 하며, Push Token 이 없으면 EXPO 에서 푸시 알림을 받을 수 없다. 따라서 채팅 서비스와 알림 서비스 간에는 gRPC 를 유지하고, 알림 서비스와 EXPO 간 통신은 REST API 방식으로 변경했다.
1. 의존성

Spring Boot 는 기본적으로 Tomcat 을 내장 WAS 로 사용하여 REST API 를 실행한다. 하지만 gRPC 는 HTTP/2 기반의 바이너리 프로토콜을 사용하기 떄문에 이를 지원하는 gRPC 서버를 별도로 띄워야 한다. 필자는 springframework 에서 제공하는 REST API 와 gRPC 를 사용하였다.
2. gRPC 서버를 별도로 설정
Spring Boot 에서 두개의 서버가 충돌 없이 실행되기 위해서는 각 서비스를 병렬로 실행시켜야 한다. 따라서 @Configuration 클래스를 활용하여 Bean 을 설정한다. 이를 통해 gRPC 서버가 Spring Boot 에서 독립적으로 실행되도록 설정한다. 라고 구글링을 하면 나오게 되는데 @GrpcService 를 붙여서 사용하게 되었을 경우 자동으로 인식한다고 하지만 필자의 경우 gRPC 서버가 실행되면 REST API 서버가 실행되지 않고, 반대로 REST API 가 실행되면 gRPC 서버가 실행되지 않아, @Component 를 사용하여 gRPC 서버를 강제적으로 띄웠다. (권장되는 방식은 아니라고 하기 때문에 추후 변경해야할 것 같다.)
@Component
public class GrpcServerRunner {
private final ChatService chatService;
private Server server;
public GrpcServerRunner(ChatService chatService) {
this.chatService = chatService;
}
@PostConstruct
public void start() {
new Thread(() -> {
try {
server = ServerBuilder.forPort(9091)
.addService(chatService)
.build()
.start();
System.out.println("✅ gRPC Server started on port 9091...");
server.awaitTermination();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}).start(); // 새로운 쓰레드에서 실행
}
@PreDestroy
public void stop() {
if (server != null) {
server.shutdown();
System.out.println("gRPC Server stopped");
}
}
}
@Component 를 사용하여 gRPC 서버를 Spring Boot 빈으로 등록했다.
@PostConstruct 를 사용하여 Spring Boot 실행 시 자동으로 gRPC 서버를 실행한다.
@PreDestroy 를 사용하여 애플리케이션 종료시 gRPC 서버도 종료하게 하였다.
여기서 server.awaitTermination(); 을 사용하여 서버가 종료될 때 까지 현재 실행 중인 스레드를 대기시킨다. 만약 해당 코드가 없다면 gRPC 서버가 실행 직후 즉시 종료될 수 있다.
3. 결과

Spring Boot 를 실행 후 REST API 와 gRPC 포트가 정상적으로 열려 있는지 확인하였다. 8080 포트와 9091 포트가 잘 열려 있는 것을 확인할 수 있다.
'Project > ST00CK' 카테고리의 다른 글
EXPO -> React Vite 로 리펙토링 (추후 방향성) (0) | 2025.03.31 |
---|---|
EXPO 에서 Push Token 발급 및 Redis 에서 관리하기 (0) | 2025.03.05 |
Redis 를 활용한 오프라인 유저 찾기 로직 (0) | 2025.02.27 |
KafkaConsumer 중복 실행 오류 수정 (0) | 2025.02.26 |
socket.io 방 나가기 기능 및 연결 해제 처리 (0) | 2025.02.25 |
알림서비스를 구현하기 위해서는 gRPC 와 RESTFul API 서버가 동시에 사용해야 했다. EXPO 에서는 네이티브 모듈을 직접 추가할 수 없기 때문에 gRPC 를 직접 호출하는 것은 불가능했다. 따라서 이것을 해결하기 위해 채팅서비스와 알림서비스 간의 통신은 gRPC 를 활용하고, EXPO 에는 REST API 를 사용해야 했다.
0. 두개의 서버를 동시에 사용해야 하는 이유
처음 설계시, 채팅서비스와 알림서비스 그리고 EXPO 간 통신을 모두 gRPC 를 사용하기로 하였다. 새로운 기술을 사용해 보고자 했으며 알림 서비스의 경우 무결성의 제약에 엄격하지 않았기 때문이다. 하지만 개발을 진행하는 과정에서 EXPO 는 gRPC 를 기본적으로 지원하지 않는다는 것을 알게 되었다. 또한, 알림 기능을 사용하려면 Push Token 이 필요하며, EXPO 에서 로그인 시 알림 동의 여부에 따라 Push Token 이 발급된다는 점도 확인했다. 해당 Push Token 은 Firebase 또는 자체 구축한 DB 에 저장되어야 하며, Push Token 이 없으면 EXPO 에서 푸시 알림을 받을 수 없다. 따라서 채팅 서비스와 알림 서비스 간에는 gRPC 를 유지하고, 알림 서비스와 EXPO 간 통신은 REST API 방식으로 변경했다.
1. 의존성

Spring Boot 는 기본적으로 Tomcat 을 내장 WAS 로 사용하여 REST API 를 실행한다. 하지만 gRPC 는 HTTP/2 기반의 바이너리 프로토콜을 사용하기 떄문에 이를 지원하는 gRPC 서버를 별도로 띄워야 한다. 필자는 springframework 에서 제공하는 REST API 와 gRPC 를 사용하였다.
2. gRPC 서버를 별도로 설정
Spring Boot 에서 두개의 서버가 충돌 없이 실행되기 위해서는 각 서비스를 병렬로 실행시켜야 한다. 따라서 @Configuration 클래스를 활용하여 Bean 을 설정한다. 이를 통해 gRPC 서버가 Spring Boot 에서 독립적으로 실행되도록 설정한다. 라고 구글링을 하면 나오게 되는데 @GrpcService 를 붙여서 사용하게 되었을 경우 자동으로 인식한다고 하지만 필자의 경우 gRPC 서버가 실행되면 REST API 서버가 실행되지 않고, 반대로 REST API 가 실행되면 gRPC 서버가 실행되지 않아, @Component 를 사용하여 gRPC 서버를 강제적으로 띄웠다. (권장되는 방식은 아니라고 하기 때문에 추후 변경해야할 것 같다.)
@Component
public class GrpcServerRunner {
private final ChatService chatService;
private Server server;
public GrpcServerRunner(ChatService chatService) {
this.chatService = chatService;
}
@PostConstruct
public void start() {
new Thread(() -> {
try {
server = ServerBuilder.forPort(9091)
.addService(chatService)
.build()
.start();
System.out.println("✅ gRPC Server started on port 9091...");
server.awaitTermination();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}).start(); // 새로운 쓰레드에서 실행
}
@PreDestroy
public void stop() {
if (server != null) {
server.shutdown();
System.out.println("gRPC Server stopped");
}
}
}
@Component 를 사용하여 gRPC 서버를 Spring Boot 빈으로 등록했다.
@PostConstruct 를 사용하여 Spring Boot 실행 시 자동으로 gRPC 서버를 실행한다.
@PreDestroy 를 사용하여 애플리케이션 종료시 gRPC 서버도 종료하게 하였다.
여기서 server.awaitTermination(); 을 사용하여 서버가 종료될 때 까지 현재 실행 중인 스레드를 대기시킨다. 만약 해당 코드가 없다면 gRPC 서버가 실행 직후 즉시 종료될 수 있다.
3. 결과

Spring Boot 를 실행 후 REST API 와 gRPC 포트가 정상적으로 열려 있는지 확인하였다. 8080 포트와 9091 포트가 잘 열려 있는 것을 확인할 수 있다.
'Project > ST00CK' 카테고리의 다른 글
EXPO -> React Vite 로 리펙토링 (추후 방향성) (0) | 2025.03.31 |
---|---|
EXPO 에서 Push Token 발급 및 Redis 에서 관리하기 (0) | 2025.03.05 |
Redis 를 활용한 오프라인 유저 찾기 로직 (0) | 2025.02.27 |
KafkaConsumer 중복 실행 오류 수정 (0) | 2025.02.26 |
socket.io 방 나가기 기능 및 연결 해제 처리 (0) | 2025.02.25 |