실패기 이므로 과정에 궁금하지 않으면 이 문서보지 말고 다른 문서를 참조한다.
저번에 Gemini에 react with typescript와 spring boot 연계방법을 물었을 때 REST API로 연계하는 방법 말고 웹소켓으로도 연계가 가능하다고 했다. 그래서 이번엔 웹소켓으로 연계해본다.
react + spring boot 연계하기
먼저 react 환경과 spring boot 백엔드 환경을 구축한다. 아래 글 2개를 참고한다. https://cgdev.tistory.com/43 react + typescript 개발환경 세팅하기먼저 Copilot에 물어보자물론입니다! React와 TypeScript를 함
cgdev.tistory.com
이제 다시 웹소켓으로 연계하는 방법을 Gemini에 물어본다.
React with Typescript와 Spring Boot를 이용해서 웹소켓을 연동하는 방법은 다음과 같습니다.
1. Spring Boot 서버 설정
Spring Boot에서 WebSocket을 사용하기 위해 spring-boot-starter-websocket 의존성을 추가합니다.
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
코드를 사용할 때는 주의가 필요합니다.
content_copy
STOMP (Simple Text Oriented Messaging Protocol)를 사용하여 WebSocket 메시지를 처리합니다. STOMP는 메시지 전송 및 구독을 위한 간단한 텍스트 기반 프로토콜입니다.
Spring Boot에서 STOMP를 사용하려면 @EnableWebSocketMessageBroker 어노테이션을 사용하여 메시지 브로커를 설정해야 합니다.
Java
@SpringBootApplication
@EnableWebSocketMessageBroker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Configuration
@EnableWebSocketMessaging
public static class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBrokers(AbstractMessageBrokerConfigurer.MessageBrokerConfigurer configurer) {
configurer.enableSimpleBroker("/topic");
}
}
}
코드를 사용할 때는 주의가 필요합니다.
content_copy
@Controller 어노테이션을 사용하여 WebSocket 클라이언트와의 연결을 처리하는 컨트롤러를 만듭니다.
Java
@Controller
public class WebSocketController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/message")
public void sendMessage(@Payload Message message) {
messagingTemplate.convertAndSend("/topic", message);
}
}
코드를 사용할 때는 주의가 필요합니다.
content_copy
2. React 클라이언트 설정
@stomp/stompjs 라이브러리를 사용하여 WebSocket 연결을 구현합니다.
JavaScript
import Stomp from '@stomp/stompjs';
const stompClient = Stomp.overWebSocket('ws://localhost:8080/websocket-endpoint');
stompClient.connect();
코드를 사용할 때는 주의가 필요합니다.
content_copy
subscribe() 메서드를 사용하여 서버에서 보낸 메시지를 구독합니다.
JavaScript
stompClient.subscribe('/topic', (message) => {
console.log(message.body);
});
코드를 사용할 때는 주의가 필요합니다.
content_copy
send() 메서드를 사용하여 서버로 메시지를 전송합니다.
JavaScript
stompClient.send('/message', { message: 'Hello from React!' });
코드를 사용할 때는 주의가 필요합니다.
content_copy
3. 예제 코드
다음은 React with Typescript와 Spring Boot를 이용한 웹소켓 연동을 위한 간단한 예제 코드입니다.
Spring Boot 서버
Java
@SpringBootApplication
@EnableWebSocketMessageBroker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Configuration
@EnableWebSocketMessaging
public static class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBrokers(AbstractMessageBrokerConfigurer.MessageBrokerConfigurer configurer) {
configurer.enableSimpleBroker("/topic");
}
}
@Controller
public class WebSocketController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/message")
public void sendMessage(@Payload Message message) {
messagingTemplate.convertAndSend("/topic", message);
}
}
}
코드를 사용할 때는 주의가 필요합니다.
content_copy
React 클라이언트
TypeScript
import React from 'react';
import Stomp from '@stomp/stompjs';
const App: React.FC = () => {
const [message, setMessage] = React.useState('');
const sendMessage = () => {
stompClient.send('/message', { message });
};
return (
<div>
<input type="text" value={message} onChange={(event) => setMessage(event.target.value)} />
<button onClick={sendMessage}>Send</button>
</div>
);
};
const stompClient = Stomp.overWebSocket('ws://localhost:8080/websocket-endpoint');
stompClient.connect();
stompClient.subscribe('/topic', (message) => {
console.log(message.body);
});
export default App;
코드를 사용할 때는 주의가 필요합니다.
content_copy
4. 참고자료
소스
info
github.com/asemchenko/reverse-chess
github.com/Abhinav2510/yaksha-prashna
my.oschina.net/u/3421984/blog/1517704
github.com/ZFGCCP/ZFGC3라이선스 적용(MIT)
github.com/katthigokul/poc-spring-websocket
1. spring boot에서 웹소켓 설정
pom.xml에 spring-boot-starter-websocket 의존성을 추가한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2. 웹소켓 서버 생성
위에서 Application.java 를 그대로 가져온다.
@SpringBootApplication
@EnableWebSocketMessageBroker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Configuration
@EnableWebSocketMessaging
public static class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBrokers(AbstractMessageBrokerConfigurer.MessageBrokerConfigurer configurer) {
configurer.enableSimpleBroker("/topic");
}
}
@Controller
public class WebSocketController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/message")
public void sendMessage(@Payload Message message) {
messagingTemplate.convertAndSend("/topic", message);
}
}
}
근데 AbstractWebSocketMessageBrokerConfigurer 가 없다고 나온다. 그래서 다시 Gemini에 물어보니 아래와 같은 답변을 얻었다.
Spring Boot 3.2.5에서 AbstractWebSocketMessageBrokerConfigurer 클래스가 없다고 나오는 문제는 Spring Framework 6.0 이후 버전에서 발생하는 변화 때문입니다.
변경 내용:
Spring Framework 6.0 이후 버전에서는 AbstractWebSocketMessageBrokerConfigurer 클래스가 제거되었습니다.
대신, WebSocketMessageBrokerConfigurer 인터페이스를 직접 구현하거나 @EnableWebSocketMessageBroker 어노테이션을 사용하여 메시지 브로커를 설정해야 합니다.
해결 방법:
1. WebSocketMessageBrokerConfigurer 인터페이스 구현:
WebSocketMessageBrokerConfigurer 인터페이스를 직접 구현하여 메시지 브로커를 설정하는 방법입니다.
configureMessageBrokers() 메서드를 오버라이드하여 메시지 브로커 설정을 정의합니다.
예시:
Java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBrokers(AbstractMessageBrokerConfigurer.MessageBrokerConfigurer configurer) {
configurer.enableSimpleBroker("/topic");
}
}
코드를 사용할 때는 주의가 필요합니다.
content_copy
2. @EnableWebSocketMessageBroker 어노테이션 사용:
@EnableWebSocketMessageBroker 어노테이션을 사용하여 메시지 브로커를 간편하게 설정하는 방법입니다.
어노테이션의 simpleBroker() 속성을 사용하여 메시지 브로커가 사용할 대상 경로를 설정합니다.
예시:
Java
@SpringBootApplication
@EnableWebSocketMessageBroker(simpleBroker = "/topic")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
코드를 사용할 때는 주의가 필요합니다.
content_copy
참고:
Spring Boot 공식 문서 - WebSocket: [유효하지 않은 URL 삭제됨]
@EnableWebSocketMessageBroker 어노테이션: [유효하지 않은 URL 삭제됨]
WebSocketMessageBrokerConfigurer 인터페이스: [유효하지 않은 URL 삭제됨]
SingleBroker 속성을 사용하여 개발하려고 했으나 또 속성이 없다는 에러가 발생하여 다시 물어보니 Spring Boot 3.2.5 이후 버전에서는 더이상 사용되지 않는다고 한다... 그리고 Spring Framework 6.0 이후 버전에서는 AbstractMessageBrokerConfigurer 클래스도 제거되었다고 한다.
그래서 다시 Spring Boot 3.2.5에서 웹소켓 서버 만드는 법을 물어봤다.
다음은 Spring Boot 3.2.5를 사용하여 /topic 웹소켓 서버를 생성하는 방법입니다.
1. 프로젝트 설정
Spring Boot 프로젝트를 설정하고 다음 종속성을 추가해야 합니다.
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
코드를 사용할 때는 주의가 필요합니다.
content_copy
2. WebSocket 구성
WebSocketConfig 클래스를 만들고 다음과 같이 구성합니다.
Java
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new TopicHandler(), "/topic");
}
}
코드를 사용할 때는 주의가 필요합니다.
content_copy
3. TopicHandler 클래스
TopicHandler 클래스를 만들고 다음과 같이 구현합니다.
Java
@Component
public class TopicHandler extends TextWebSocketHandler {
private final ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.put(session.getId(), session);
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String messageContent = message.getPayload();
for (WebSocketSession otherSession : sessions.values()) {
if (otherSession != session) {
otherSession.sendMessage(new TextMessage(messageContent));
}
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
sessions.remove(session.getId());
}
}
코드를 사용할 때는 주의가 필요합니다.
content_copy
4. 실행
프로젝트를 실행하면 /topic 엔드포인트에서 웹소켓 서버가 시작됩니다. 클라이언트는 웹소켓 라이브러리를 사용하여 서버에 연결하고 메시지를 전송하고 수신할 수 있습니다.
참고:
이 예제는 기본적인 웹소켓 서버를 보여줍니다. 실제 응용 프로그램에서는 인증, 메시지 처리 및 오류 처리와 같은 추가 기능을 구현해야 할 수도 있습니다.
Spring Boot는 웹소켓을 사용하여 다양한 종류의 응용 프로그램을 구축할 수 있는 강력한 프레임워크를 제공합니다. 자세한 내용은 [Spring Boot 웹소켓 문서]([유효하지 않은 URL 삭제됨] 참조하십시오.
소스
info
github.com/dkbnull/SpringBootDemo
caucho.com/category/newsletter
http://www.baeldung.com/postman-websocket-apis
github.com/Lincest/websocket-impl
stackoverflow.com/questions/32728030/heroku-h15-error-on-web-socket-close
github.com/kekewest/lightpay
github.com/DongqingWang/Live
위의 가이드대로 Application.java와 TopicHandler.java를 생성한다.
Application.java
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@SpringBootApplication
@EnableWebSocketMessageBroker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new TopicHandler(), "/topic");
}
}
@Controller
public class WebSocketController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/message")
public void sendMessage(@Payload Message message) {
messagingTemplate.convertAndSend("/topic", message);
}
}
}
TopicHandler.java
package com.example.demo;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class TopicHandler extends TextWebSocketHandler {
private final ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.put(session.getId(), session);
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String messageContent = message.getPayload();
for (WebSocketSession otherSession : sessions.values()) {
if (otherSession != session) {
otherSession.sendMessage(new TextMessage(messageContent));
}
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
sessions.remove(session.getId());
}
}
실행 시키니 아래와 같이 에러가 뜬다.
org.springframework.context.ApplicationContextException: Failed to start bean 'subProtocolWebSocketHandler'
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:291) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:281) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:471) ~[spring-context-6.1.6.jar:6.1.6]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:260) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:205) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:981) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-3.2.5.jar:3.2.5]
at cohttp://m.example.demo.Application.main(Application.java:20) ~[classes/:na]
Caused by: java.lang.IllegalStateException: No handlers
at org.springframework.util.Assert.state(Assert.java:76) ~[spring-core-6.1.6.jar:6.1.6]
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.start(SubProtocolWebSocketHandler.java:289) ~[spring-websocket-6.1.6.jar:6.1.6]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:288) ~[spring-context-6.1.6.jar:6.1.6]
... 14 common frames omitted
다시 한번 Gemini에 구체적으로 물어본다.
React with Typescript와 Spring Boot 3.2.5를 이용한 웹소켓 연동 방법 (TextWebSocketHandler 사용)
React with Typescript와 Spring Boot 3.2.5를 이용하여 웹소켓을 연동하는 방법은 다음과 같습니다.
1. Spring Boot 서버 설정
1.1 Maven 설정
먼저, pom.xml 파일에 다음과 같은 의존성을 추가합니다.
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
코드를 사용할 때는 주의가 필요합니다.
content_copy
1.2 WebSocket 설정
WebSocket 엔드포인트를 설정하고 TextWebSocketHandler를 구현합니다.
Java
@Configuration
@EnableWebSocket
public class WebSocketConfig extends AbstractWebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/websocket").setAllowedOrigins("*");
}
}
@Component
public class MyWebSocketHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// 수신된 메시지 처리
String textMessage = message.getPayload();
System.out.println("Received message: " + textMessage);
// 클라이언트에게 메시지 전송
session.sendMessage(new TextMessage("Hello from server!"));
}
}
코드를 사용할 때는 주의가 필요합니다.
content_copy
2. React with Typescript 클라이언트 설정
2.1 WebSocket 연결
WebSocket 연결을 수립하고 메시지 전송 및 수신을 처리합니다.
TypeScript
import React, { useState, useEffect } from 'react';
import { useRef } from 'react';
import { WebSocket } from 'ws';
const App: React.FC = () => {
const [message, setMessage] = useState('');
const [messages, setMessages] = useState<string[]>([]);
const wsRef = useRef<WebSocket | null>(null);
useEffect(() => {
const ws = new WebSocket('ws://localhost:8080/websocket');
wsRef.current = ws;
ws.onmessage = (event) => {
const newMessage = event.data;
setMessages((prevMessages) => [...prevMessages, newMessage]);
};
return () => {
if (wsRef.current) {
wsRef.current.close();
}
};
}, []);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setMessage(event.target.value);
};
const handleSubmit = () => {
if (wsRef.current) {
wsRef.current.send(message);
setMessage('');
}
};
return (
<div>
<input type="text" value={message} onChange={handleChange} />
<button onClick={handleSubmit}>Send</button>
<ul>
{messages.map((message) => (
<li key={message}>{message}</li>
))}
</ul>
</div>
);
};
export default App;
코드를 사용할 때는 주의가 필요합니다.
content_copy
3. 실행
Spring Boot 서버를 실행합니다.
React with Typescript 클라이언트를 실행합니다.
웹 브라우저에서 React 애플리케이션에 접속합니다.
메시지 입력 후 "Send" 버튼을 클릭하면 서버로 메시지가 전송됩니다.
서버에서 메시지를 수신하면 클라이언트 화면에 표시됩니다.
참고:
위 코드는 예시이며, 실제 프로젝트에서는 필요에 따라 추가적인 기능을 구현해야 할 수 있습니다.
보안을 위해 실제 프로덕션 환경에서는 웹소켓 연결을 HTTPS를 통해 설정하는 것이 좋습니다.
웹소켓 프레임워크나 라이브러리를 사용하면 더욱 쉽게 웹소켓 기능을 구현할 수 있습니다.
추가 정보:
Spring Boot WebSocket [유효하지 않은 URL 삭제됨]
React WebSocket [유효하지 않은 URL 삭제됨]
소스
info
http://www.yugabyte.com/blog/building-serverless-applications-using-spring-boot-aws-lambda-yugabytedb/
medium.com/xebia-engineering/simulating-real-time-stock-prices-using-web-socket-8d9696c66503
juejin.cn/s/spring-cloud-netflix-zuul-websocket%20example
stackoverflow.com/questions/53068364/websocket-push-message-programmatically-using-java-code
http://www.scribd.com/document/301414613/Spring-Essentials-Sample-Chapter
또, AbstractWebSocketConfigurer 클래스가 안보인데 찾아보니 Spring Boot 3.2.0 부터 사용이 불가능하다고한다. 대신 WebSocketConfigurer를 사용하면 된다.
Application.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.TextWebSocketHandler;
@SpringBootApplication
@EnableWebSocketMessageBroker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/websocket").setAllowedOrigins("*");
}
}
@Component
public class MyWebSocketHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// 수신된 메시지 처리
String textMessage = message.getPayload();
System.out.println("Received message: " + textMessage);
// 클라이언트에게 메시지 전송
session.sendMessage(new TextMessage("Hello from server!"));
}
}
}
다시 돌려도 마찬가지로 아래와 같이 오류가 뜬다.
org.springframework.context.ApplicationContextException: Failed to start bean 'subProtocolWebSocketHandler'
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:291) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:281) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:471) ~[spring-context-6.1.6.jar:6.1.6]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:260) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:205) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:981) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-3.2.5.jar:3.2.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-3.2.5.jar:3.2.5]
at cohttp://m.example.demo.Application.main(Application.java:20) ~[classes/:na]
Caused by: java.lang.IllegalStateException: No handlers
at org.springframework.util.Assert.state(Assert.java:76) ~[spring-core-6.1.6.jar:6.1.6]
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.start(SubProtocolWebSocketHandler.java:289) ~[spring-websocket-6.1.6.jar:6.1.6]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:288) ~[spring-context-6.1.6.jar:6.1.6]
... 14 common frames omitted
뭔가 스프링 웹소켓 쪽 구조가 계속 변경되니 GPT를 활용하여 진행하는게 어려운거 같다.
일단 여기까지 하고 홀딩
'프론트엔드' 카테고리의 다른 글
react 기본 개발 (0) | 2024.08.03 |
---|---|
IntelliJ IDEA 초기 세팅 및 단축키 (0) | 2024.06.10 |
비주얼 스튜디오 코드 초기 세팅 및 단축키 (1) | 2024.06.08 |
react + spring boot 연계하기 (1) | 2024.05.23 |
react + typescript 개발환경 세팅하기 (0) | 2024.05.18 |
댓글