국비학원 52일차 : Spring Boot_12 Websocket

Digeut·2023년 5월 11일
0

국비학원

목록 보기
44/44

Websocket

WebSocketProvider

@Getter
@AllArgsConstructor
class SessionGroup{
    private String room;
    private WebSocketSession session;

}
@Component
public class WebSocketProvider extends TextWebSocketHandler {
    //실제로는 handler에 진행해야하는것. 수업때만 provider에서 진행한다
    
//private List<WebSocketSession> sessionList = new ArrayList<>();
//접속되어 있는 세션의 리스트를 관리해줄수 있다.
    private List<SessionGroup> sessionList = new ArrayList<>();
    //group을 지어서 서버간 통신 가능하게 함.
    

    //모두 AbstractWebSocketHandler에서 기본적인 틀 가져옴

    // 1. 연결 (클라이언트와 서버 간의 연결) 
    @Override
	public void afterConnectionEstablished(
    				WebSocketSession session) throws Exception {
        
        String room = session.getHandshakeHeaders().getFirst("room"); 
       						 //특정한 키를 이용해 값을 가져올수 있다. 
        					//json형태
		
        //sessionList.add(session);
        sessionList.add(new SessionGroup(room, session)); 
        	//session = room 이므로 하나로 관리를 하게 된다.
        System.out.println(room + " / " + session.getId() 
        					+ " Web Socket Conneted!!");
	}

    // 2. 메세지 송수신
    @Override
    protected void handleTextMessage(WebSocketSession session,
    							TextMessage message) throws Exception {
        //서버상에 메시지 수신했을때의 출력
        //System.out.println(message.getPayload());
        String room = session.getHandshakeHeaders().getFirst("room");
        for(SessionGroup sessionGroup : sessionList) {
            if(sessionGroup.getRoom().equals(room) && 
            !sessionGroup.getSession().equals(session)
            // 내가 보낸 메시지는 나한테 안보이게 하는것){
                sessionGroup.getSession().sendMessage(message);
            }
        }
	}

    // 3. 연결 해제
    @Override
	public void afterConnectionClosed(WebSocketSession session, 
    						CloseStatus status) throws Exception {
        System.out.println(session.getId() + "WebSocket Closed!");
        
        //관리하는 대상에서도 지우는 작업
        //for(WebSocketSession sessionItem : sessionList) 
            //if(sessionItem.equals(session)){
                //sessionList.remove(sessionItem);
        for(SessionGroup sessionGroup : sessionList){
            if(sessionGroup.getSession().equals(session)){
                sessionList.remove(sessionGroup);
            }
        }
            
                
	}
}

WebSecurityConfig

@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
    
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Autowired
    public WebSecurityConfig(
        JwtAuthenticationFilter jwtAuthenticationFilter
    ){
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    @Bean
    protected SecurityFilterChain configure(HttpSecurity httpSecurity) 
    									throws Exception{ 
    			//모든 예외를 호출부로
        httpSecurity.cors().and()
                    .csrf().disable()
                    .httpBasic().disable()
                    .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                    .authorizeRequests().antMatchers("/jwt/**","/file/**")
                    .permitAll()
                    .antMatchers("/web-socket/**").permitAll()
                    .anyRequest().authenticated();

        httpSecurity.addFilterBefore(jwtAuthenticationFilter, 
        				UsernamePasswordAuthenticationFilter.class);
        //실행되는 필터 위치 지정해준것
        return httpSecurity.build();
    }
}

포스트맨에서 웹소켓 서버열기

웹소켓에서는 ws:// 서버를 사용한다

웹소켓 서버가 연결되었을때 화면

Message에 보냈을때 (연결만 된 상황에서)

웹소켓 연결 끊겼을때의 화면

VSC에서 아이디를 확인할 수 있다

포스트맨과 WebSocket test Client가 같은 서버에서 메시지 보낼때 화면


키를 room으로 잡고 각각의 value값으로 통신을 구분할 수 있다.

profile
개발자가 될 거야!

0개의 댓글