[ 개발 ] Spring Websocket 서버 Elastic Beanstalk으로 배포하기 - 1

장태규·2024년 10월 23일

[ WebSocket ]

목록 보기
1/8

프로젝트 세팅


#0

https://start.spring.io/

프로젝트 다운


프로젝트 이름 설정
설치할 JDK 버전 선택

Dependencies 설치 ( 보통 )
-Web
-Thymeleaf
-Lombok
-MariaDB ( 별도 설정 필요 )
-Spring Data JPA ( MariaDB 세트 )

#1

-프로젝트 구조 - 프로젝트 : SDK 설치한 jdk ( 없으면 JDK 다운로드 )
-프로젝트 구조 - 모듈 : 프로젝트 디폴트
-프로젝트 구조 - SDK - JDK 홈 경로 : 설치한 jdk 경로 지정

#2

-설정 - 빌드, 실행, 배포 - Gradle - Gradle JVM : 설치한 jdk 경로 지정
-설정 - 빌드, 실행, 배포 - Java 컴파일러 - 프로젝트 바이트코드 버전 : 설치한 jdk 버전

#3


리프레시

#4

src - main - resources - application.properties


WebSocket


#0 Dependency 추가

dependencies 
{
    implementation 'org.springframework.boot:spring-boot-starter-websocket'
}

build.gradle에 dependency 추가


#1 Handler 작성

#1-1 import

package com.example.quizSever21; //프로젝트 이름

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

필요한 라이브러리 import

#1-2 Handler 작성

public class MyWebSocketHandler extends TextWebSocketHandler
{~}

TextWebSocketHandler를 상속

#1-3 연결 및 연결 종료

// 연결
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception 
{
    System.out.println("새로운 소켓 연결 : " + session.getId());
}

// 연결 종료
@Override
public void afterConnectionClosed(WebSocketSession session, org.springframework.web.socket.CloseStatus status) throws Exception 
{
    System.out.println("소켓 연결 종료 : " + session.getId());
}

afterConnectionEstablished : 연결이 되었을 때 호출하는 함수
afterConnectionClosed : 연결이 종료 되었을 때 호출하는 함수

#1-4 메시지

@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception
{
    // 클라이언트로부터 메시지를 받음
    String payload = message.getPayload();
    System.out.println("Received message: " + payload);

    // 클라이언트에게 메시지 보내기
    session.sendMessage(new TextMessage("Echo: " + payload));
}

message.getPayload() : 메시지를 String으로 반환


#2 WebSocketConfig

#2-1 import

package com.example.quizSever21; //프로젝트 이름

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

#2-2 Configuration 작성

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer 
{~}

@EnableWebSocket : WebSocket 활성화, 프레임워크에서 알아서 실행
WebSocketConfigurer : 웹소켓에 대한 설정

#2-3 핸들러 등록

private final MyWebSocketHandler myWebSocketHandler;

public WebSocketConfig(MyWebSocketHandler myWebSocketHandler) {
    this.myWebSocketHandler = myWebSocketHandler;
}

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry)
{
    registry.addHandler(myWebSocketHandler, "/chat")// "/chat" 경로로 웹소켓 핸들러를 등록
            .setAllowedOrigins("*");  // CORS 허용 설정, 모든 오리진에서의 접근을 허용
}

registerWebSocketHandlers() : 핸들러 및 엔드 포인트 등록


#3 테스트 스크립트

const socket = new WebSocket('ws://localhost:8080/chat');

socket.onopen = function(event) {
    console.log("WebSocket is open now.");
    socket.send("Hello Server!"); // 메시지 전송
};

socket.onmessage = function(event) {
    console.log("Message from server ", event.data); // 서버로부터의 응답
};

socket.onclose = function(event) {
    console.log("WebSocket is closed now.");
};

JSON


#0

dependencies 
{
	implementation 'com.fasterxml.jackson.core:jackson-databind'
}

dependency 추가

#1 받은 json 형태의 메시지를 객체로 변환

package com.example.springmodel;

import lombok.*;

//DTO
@NoArgsConstructor @AllArgsConstructor
@Getter @Setter @ToString

public class Message 
{
    private String name;
    private int age;
}

-전달할 구조에 맞는 DTO 객체 생성
-l0mbok

//클래스 내부
private final ObjectMapper objectMapper = new ObjectMapper();

@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception
{
    // JSON 문자열을 Message 객체로 변환
    Player msg = objectMapper.readValue(message.getPayload(), Player.class);

    // 처리 결과 출력
    System.out.println("Received message: " + msg.getName() + ", Age: " + msg.getAge());

    // 클라이언트로 응답
    session.sendMessage(new TextMessage("Received: " + msg.getName()));

    // 클라이언트로부터 메시지를 받았을 때 처리하는 로직
    String payload = message.getPayload();
    System.out.println("Received message: " + payload);

    // 메시지를 그대로 다시 클라이언트로 보내기 (Echo 서버)
    session.sendMessage(new TextMessage("Echo: " + payload));
}

objectMapper : json 변환해주는 객체
objectMapper.readValue("message", 반환할 객체.class) : json 메시지 읽어서 객체로 반환

#2 보낼 데이터를 json 형태로 변환

#2-1 import

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.Map;

#2-2 변환

public class ChatWebSocketHandler extends TextWebSocketHandler {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 응답할 데이터 객체 생성 (예: Map 또는 DTO 객체)
        Map<String, Object> responseData = Map.of(
            "type", "greeting",
            "content", "Hello, Client!",
            "timestamp", System.currentTimeMillis()
        );

        // 객체를 JSON으로 변환
        String jsonResponse = objectMapper.writeValueAsString(responseData);

        // WebSocket을 통해 JSON 응답 전송
        session.sendMessage(new TextMessage(jsonResponse));
    }
}

objectMapper.writeValueAsString(data) : 데이터 Json(String)으로 변환
session.sendMessage(new TextMessage(jsonResponse)); :
-session.sendMessage() : 해당 세션의 클라이언트에게 데이터 전송
-TextMessage() : webSocket 데이터 보내는 객체

profile
무럭무럭 자라나는 중

0개의 댓글