Home Spring Boot SocketIO 사용하기
Post
Cancel

Spring Boot SocketIO 사용하기

Spring Boot SocketIO 사용하기

🎊 시작하기 전에..

필자는 STOMP와 RSocket를 사용해보며 Spring Boot에서 소켓 서버를 만드는데 두려움이 존재했었다. 하지만, SocketIO를 사용하면서 신세계를 맛봤다. 그래서 SocketIO의 사용법을 대략적으로 알려주려고 한다. 그리고 이 글을 본다고 해서 이 글의 SocketIO를 사용할 수 있는 것이 아님을 명시하자. 여러 번 사용하면서 체득하는게 제일 좋은 것 같다.

또한 이 글에서는 어노테이션을 커스텀해서 사용했다는 점 알고있었으면 한다.

또, 예시 코드를 보고 싶다면 김한울 백엔드를 참고하라.

1️⃣ 가장 먼저

SocketIO 의존성을 추가 해줘야한다.

implementation 'com.corundumstudio.socketio:netty-socketio:${version}'

위의 의존성을 추가해줘야 하는데, 위 라이브러리는 SocketIO 구현을 편하게 해주는 라이브러리이다.

2️⃣ 두 번째로

우선 커스텀 어노테이션을 설정해주는 클래스를 만들어야 한다. 아래는 커스텀 어노테이션과 설정해주는 클래스이다.

1
2
3
4
5
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@RestController
public @interface SocketController {
}
1
2
3
4
5
6
7
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SocketMapping {
	String endpoint();

	Class<?> requestCls() default Void.class;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@RequiredArgsConstructor
@Component
public class WebSocketAddMappingSupporter {

	private final ConfigurableListableBeanFactory beanFactory;
	private SocketIOServer socketIOServer;

	public void addListeners(SocketIOServer socketIOServer) {
		this.socketIOServer = socketIOServer;
		final List<Class<?>> classes = beanFactory.getBeansWithAnnotation(SocketController.class).values()
				.stream().map(Object::getClass)
				.collect(Collectors.toList());

		for (Class<?> cls : classes) {
			List<Method> methods = findSocketMappingAnnotatedMethods(cls);
			addSocketServerEventListener(cls, methods);
		}

	}

	private void addSocketServerEventListener(Class<?> controller, List<Method> methods) {
		for (Method method : methods) {
			SocketMapping socketMapping = method.getAnnotation(SocketMapping.class);
			String endpoint = socketMapping.endpoint();
			Class<?> dtoClass = socketMapping.requestCls();

			socketIOServer.addEventListener(endpoint, dtoClass, ((client, data, ackSender) -> {
				List<Object> args = new ArrayList<>();
				for (Class<?> params : method.getParameterTypes()) {                        // Controller 메소드의 파라미터들
					if (params.equals(SocketIOServer.class)) args.add(socketIOServer);      // SocketIOServer 면 주입
					else if (params.equals(SocketIOClient.class)) args.add(client);         // 마찬가지
					else if (params.equals(dtoClass)) args.add(data);
				}
				method.invoke(beanFactory.getBean(controller), args.toArray());
			}));
		}
	}

	private List<Method> findSocketMappingAnnotatedMethods(Class<?> cls) {
		return Arrays.stream(cls.getMethods())
				.filter(method -> method.getAnnotation(SocketMapping.class) != null)
				.collect(Collectors.toList());
	}

}

SocketIO server를 실행시켜줘야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
@RequiredArgsConstructor
@Component
@Order(1)
public class SocketRunner implements CommandLineRunner {

	private final SocketIOServer socketIOServer;

	@Override
	public void run(String... args) throws Exception {
		socketIOServer.start();
	}

}

3️⃣ 세 번째로

SocketIO를 설정해줘야하는데 해당 라이브러리의 Configuration 객체를 이용해서 설정한다. 또 Connection되었거나 DisConnection되었을 때의 Listener 또한 여기에서 설정해준다.

This post is licensed under CC BY 4.0 by the author.