@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);
}
}
}
}
@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값으로 통신을 구분할 수 있다.