JiYoung Dev 🖥

[Spring Boot 웹소켓] @ServerEndPoint가 있는 컨트롤러에서 의존성 주입 에러 본문

Question

[Spring Boot 웹소켓] @ServerEndPoint가 있는 컨트롤러에서 의존성 주입 에러

Shinjio 2023. 9. 2. 22:13
@SeverEndPoint가 있는 컨트롤러에서 @Autowired 사용 시 오류 발생 시 해결 방법

 

  • @ServerEndPoint로 어노테이션이 달린 클래스는 WebSocket이 연결될 때마다 인스턴스가 생성되고 JWA구현에 의해 관리가 되어 내부의 @Autowired가 설정된 멤버가 정상적으로 초기화 되지 않는다.
  • @Autowired를 사용하기 위해서 ServerEndpointConfig.Configurator를 상속받아 ServerEndPoint의 컨텍스트에 BeanFactory 또는 ApplicationContext를 연결해 주는 작업을 하는 설정을 추가해야 한다.

 

MyServerEndPointConfig

package com.sjy.chat.websocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import jakarta.websocket.server.ServerEndpointConfig;

@Component
public class MyServerEndPointConfig extends ServerEndpointConfig.Configurator{

	private static ApplicationContext context;

    @Autowired
    public void setApplicationContext(ApplicationContext context) {
        MyServerEndPointConfig.context = context;
    }

    @Override
    public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
        return context.getBean(endpointClass);
    }
	
}

 

WebSocketService

package com.sjy.chat.service;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sjy.chat.websocket.MyServerEndPointConfig;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;


//클라이언트가 접속될 때마다 생성되어 클라이언트와 직접 통신하는 클래스
//클라이언트가 접속할 때마다 session 관련 정보를 정적으로 저장하여 1:N 통신이 가능하도록 한다. 
@ServerEndpoint(value="/chat", configurator =  MyServerEndPointConfig.class)
@Service
public class WebSocketService {
	
	private static Set<Session> CLIENTS = Collections.synchronizedSet(new HashSet<>());
    private final ChatService chatService;

    @Autowired
    public WebSocketService(ChatService chatService) {
        this.chatService = chatService;
    }
//	@Autowired
//	private ChatService chatService;
//	
	@OnOpen //클라이언트가 접속할 때마다 실행
	public void onOpen(Session session) {
		System.out.println(session.toString());
		
		if(CLIENTS.contains(session)) {
			System.out.println("이미 연결된 세션입니다. > " + session);
		}else {
			CLIENTS.add(session);
			System.out.println("새로운 세션입니다. > " + session);
		}
	}
	
	@OnClose //클라이언트가 접속을 종료할 때
	public void onClose(Session session) throws Exception {
		CLIENTS.remove(session);
		System.out.println("세션을 닫습니다. : " + session);
	}
	
	@OnMessage //메세지 수신시
	public void onMessage(String message, Session session) throws Exception {
		System.out.println("입력된 메세지입니다. > " + message);
		
		for(Session client : CLIENTS) {
			System.out.println("메세지를 전달합니다. > " + message);
			client.getBasicRemote().sendText(message);

			chatService.addMessage(message);
			
		}
	}
}

 

'Question' 카테고리의 다른 글

REST API 규칙  (0) 2023.09.04
[JAVA] List에서 배열(Array)로 변환하기  (0) 2023.08.24
[JAVA] List 정렬 - sort()  (0) 2023.08.24
[Spring boot] 첨부파일 기능 추가  (0) 2023.08.22
[python] 소수점 자릿수 지정 (round)  (0) 2023.08.22