13일 전 · 최범준 님의 질문
MacBook에서 Windows Docker 서버 접속 시 sudo가 필요한데 원인이 뭘까요?
문제 현재 Windows 데스크톱과 MacBook을 사용 중이며, 두 기기는 동일한 로컬 네트워크에 연결되어 있습니다. - 데스크톱(Windows): 유선 랜(Ethernet)으로 연결 - MacBook: Wi-Fi로 연결 Windows 데스크톱에서 Docker를 이용해 로컬 웹 서버(포트 9000)를 실행 중입니다. 컨테이너는 -p 9000:9000 옵션으로 실행되었으며, 0.0.0.0:9000에서 요청을 받을 수 있도록 설정되어 있습니다. 데스크톱에서는 Chrome를 통해 정상적으로 웹 인터페이스에 접속할 수 있습니다. 그러나 MacBook의 Chrome에서 접속하면 페이지를 찾을 수 없다고 합니다. 이상하게도,,, Chrome을 sudo로 실행하면 페이지가 정상적으로 로드됩니다. 추가 정보 - 데스크톱(Windows)과 MacBook은 같은 서브넷에 속해 있습니다. - 웹 서버는 0.0.0.0:9000에서 요청을 받을 수 있도록 설정되어 있어, 다른 기기에서도 접근 가능해야 합니다. - MacBook에서 nc -zv <데스크톱-IP> 9000을 실행하면 포트가 열려 있음을 확인했습니다. - Python 코드에서 requests.get("http://<데스크톱-IP>:9000")을 실행하면, 일반 실행 시 실패하지만 sudo로 실행하면 정상적으로 작동합니다. - MacBook에는 단 하나의 사용자 계정만 존재하며, 해당 계정은 관리자(Admin) 권한을 가지고 있습니다. - macOS 방화벽은 비활성화되어 있으며 (/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate로 확인), sudo pfctl -d로 pf 방화벽을 꺼도 문제가 해결되지 않았습니다. 현재까지 파악한 내용 sudo로 실행하면 정상적으로 동작하기 때문에, 현재 문제는 네트워크 연결 자체의 문제가 아니라 macOS의 보안 정책 또는 네트워크 제한과 관련된 것이 아닐까,, 생각하고 있습니다. 해결하고 싶은 질문 - 왜 Chrome을 sudo로 실행해야만 웹 서버에 접속할 수 있을까요? - 왜 일반 사용자 권한으로 실행한 Python의 requests.get() 요청이 차단되고, sudo를 사용해야만 정상적으로 동작할까요? - macOS에서 일반 사용자 프로세스의 네트워크 접근을 제한하는 정책이 있는 걸까요? 있다면 어떻게 해결할 수 있을까요? 스크립트에 모두 sudo를 붙이면 문제가 해결되긴 합니다만,, 명확한 원인이 궁금합니다. 혹시 비슷한 경험을 하신 적이 있는 분이 계시다면 조언 부탁드립니다! 혹은 힌트 키워드라도 던져주시면 감사하겠습니다!
개발자
#mac
#docker
#local-network
답변 0
댓글 0
조회 34
한 달 전 · 원승현 님의 질문
웹소켓 + Stomp로 채팅 기능을 구현하며
RabbitMQ를 도입하였습니다. 도입의 이유는 스프링 내장 메시지 브로커를 이용하게 되면 인메모리 기반의 동작 방식으로 인해 서버 문제 발생 시 메시지가 유실되거나 확장에도 제한이 있다고 판단하여 도입하였습니다. 현직자 분들이 보기에 이 이유가 적합한 근거가 될까요? 추가로 JMeter로 RabbitMQ를 사용했을 때와 사용하지 않았을 때의 성능을 비교했는데 사용자 100명 기준 성능도 사용하지 않았을 때가 우세했고, RabbitMQ를 사용했을 때는 오히려 아래와 같은 오류가 가끔 발생하며 메시지또한 약 90퍼센트 정도만 저장된걸 확인할 수 있었습니다. 무엇이 문제이며 해결 방안이 있을까요?? java.net.SocketException: Connection reset at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:394) ~[na:na] at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:426) ~[na:na] at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:255) ~[netty-buffer-4.1.114.Final.jar:4.1.114.Final] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132) ~[netty-buffer-4.1.114.Final.jar:4.1.114.Final] at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:356) ~[netty-transport-4.1.114.Final.jar:4.1.114.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151) ~[netty-transport-4.1.114.Final.jar:4.1.114.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.114.Final.jar:4.1.114.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.114.Final.jar:4.1.114.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.114.Final.jar:4.1.114.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.114.Final.jar:4.1.114.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.114.Final.jar:4.1.114.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.114.Final.jar:4.1.114.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.114.Final.jar:4.1.114.Final] at java.base/java.lang.Thread.run(Thread.java:842) ~[na:na]
개발자
#채팅
#구현
답변 0
댓글 0
조회 52
4달 전 · 영훈 님의 질문
리액트 웹소켓 사용자 인증
웹소켓을 사용해서 채팅구현 중에 있습니다. 이때 사용자 인증 처리를 핸드셰이크 시 요청 헤더에 토큰을 담아 보내려고 합니다. Web Socket API에선 요청 헤더에 토큰을 담아 보내는게 안되고, Socket.IO나 SockJS 라이브러리를 사용하라는걸 알게되었는데 혹시나 라이브러리 사용하지 않고 Web Socket API 에서 요청 헤더에 토큰을 담아보내는 방법이 있나요?
개발자
#웹소켓
#인증
답변 0
댓글 0
조회 39
8달 전 · 프레드윰 님의 새로운 댓글
next socket.io 연결, 제가 어떤 부분을 놓치고 있을까요?
https://github.com/hyubbb/socket-test-app 안녕하세요. 간단하게 채팅방을 만들어서 유저의 입장/퇴장, 채팅 기능을 구현해볼려고 하는데요. 통신이 됬다 안됬다 하더라구요? 그래서 계속 새로고침을 누르거나 해야하는 현상이 있습니다. 서버와의 연결은 계속 되어있다고 하는데 , socket.on 이나 socket.emit 이 동작을 안하는데 정말 이해가 안됩니다. 콘솔을 찍어봤을땐, next가 캐싱처리를 해서 실시간으로 응답하는게 문제가 발생한게 아닐까 생각했는데, 정확하게 갈피를 잡지 못하겠습니다. 3일을 헤매고 있는데요. 제가 어떤 부분을 놓치고 있는지 알려주시면 너무 감사하겠습니다. 코드가 길어서 github에 업로드 하였습니다. 클릭 라우트 처리 components/chat/chat-list socket.emit 발생장소 components/chat/chat-room 소켓 프로바이더 components/providers/socket-provider socket서버사이드 설정 pages/api/socket/io.ts
개발자
#socket.io
#next.js
답변 1
댓글 2
조회 42
일 년 전 · 김연호 님의 답변 업데이트
JMeter Websocket테스트 질문드립니다
JMeter로 Websocket 테스트를 구현해야 하는 상황인데 테스트 진행하는 도중 아래 에러가 나서 찾아보니 Single Write Sampler에 Data 인코딩 문제로 추측만 되고 있습니다... Failed to parse TextMessage payload=[SEND desti..], byteCount=242, last=true] in session ujvhyrid. Sending STOMP ERROR to client. org.springframework.messaging.simp.stomp.StompConversionException: Frame must be terminated with a null octet JMeter Sampler 인코딩 UTF-8로 설정하는건 찾아서 해봤는데 그래도 안되네요...ㅠㅠ 정말로 인코딩 문제인지 혹시 동일한 경험이 있으신 분이 계실까요? 구글링을 해도 자료를 못찾겠고.. 사내에 해당 지식을 가지신 분도 전무하셔서 너무 답답해서 질문남겨봅니다....
개발자
#jmeter
#websoket
답변 1
댓글 0
조회 256
일 년 전 · 박건우 님의 새로운 댓글
WebSocket과 WebRTC를 함께 사용한 프로젝트 배포 질문드려요!
현재 websocket(socket io)과 webrtc(peerjs)를 함께 사용한 프로젝트를 구현했습니다. 배포 관련 궁금한 점이 있어서 질문드립니다! 두가지 기술 전부 애플리케이션 내에서 큰 비중을 차지하는데 통상적으로 이 둘을 같은 서버에 배포하나요?? 아니면 따로 따로 배포해야 할까요??
개발자
#webrtc
#websocket
#react
답변 1
댓글 1
조회 119
일 년 전 · 다형 님의 답변 업데이트
aws spring boot 배포 오류
안녕하세요 백엔드 공부 중인 학생입니다. aws ec2로 Spring boot 프로젝트를 배포 시도 중에 있습니다. (maven, java 8, jar) java -jar jar파일명.jar 명령어로 배포 시도 중에 에러메세지가 도저히 해결이 안되어서 도움 요청드립니다.. 도와주신다면 감사하겠습니다.. 아 참고로 rds로 데이터베이스 생성하지 않고 mysql(workbench)로 데이터베이스 생성했습니다 <오류메세지> Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2024-02-07 04:33:35.742 ERROR 31012 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat server at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.22.jar!/:5.3.22] at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_392] at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) [spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) [spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) [spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) [spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) [spring-boot-2.7.2.jar!/:2.7.2] at com.se.social.SocialApplication.main(SocialApplication.java:13) [classes!/:0.0.1-SNAPSHOT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_392] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_392] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_392] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_392] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) [social-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) [social-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) [social-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) [social-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat server at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:229) ~[spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.web.servlet.context.WebServerStartStopLifecycle.start(WebServerStartStopLifecycle.java:43) ~[spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) ~[spring-context-5.3.22.jar!/:5.3.22] ... 22 common frames omitted Caused by: java.lang.IllegalArgumentException: standardService.connector.startFailed at org.apache.catalina.core.StandardService.addConnector(StandardService.java:238) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.addPreviouslyRemovedConnectors(TomcatWebServer.java:282) ~[spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:213) ~[spring-boot-2.7.2.jar!/:2.7.2] ... 24 common frames omitted Caused by: org.apache.catalina.LifecycleException: Protocol handler start failed at org.apache.catalina.connector.Connector.startInternal(Connector.java:1077) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.catalina.core.StandardService.addConnector(StandardService.java:234) ~[tomcat-embed-core-9.0.65.jar!/:na] ... 26 common frames omitted Caused by: java.net.SocketException: Permission denied at sun.nio.ch.Net.bind0(Native Method) ~[na:1.8.0_392] at sun.nio.ch.Net.bind(Net.java:461) ~[na:1.8.0_392] at sun.nio.ch.Net.bind(Net.java:453) ~[na:1.8.0_392] at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:222) ~[na:1.8.0_392] at org.apache.tomcat.util.net.NioEndpoint.initServerSocket(NioEndpoint.java:275) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:230) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1227) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:1313) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:614) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.catalina.connector.Connector.startInternal(Connector.java:1074) ~[tomcat-embed-core-9.0.65.jar!/:na] ... 28 common frames omitted <전체> . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.2) 2024-02-07 04:33:27.975 INFO 31012 --- [ main] com.se.social.SocialApplication : Starting SocialApplication v0.0.1-SNAPSHOT using Java 1.8.0_392 on ip-172-31-39-15 with PID 31012 (/home/ubuntu/socialboardPJ/target/social-0.0.1-SNAPSHOT.jar started by ubuntu in /home/ubuntu/socialboardPJ/target) 2024-02-07 04:33:27.980 INFO 31012 --- [ main] com.se.social.SocialApplication : No active profile set, falling back to 1 default profile: "default" 2024-02-07 04:33:29.591 INFO 31012 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2024-02-07 04:33:29.681 INFO 31012 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 76 ms. Found 1 JPA repository interfaces. 2024-02-07 04:33:30.960 INFO 31012 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 80 (http) 2024-02-07 04:33:30.986 INFO 31012 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2024-02-07 04:33:30.987 INFO 31012 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.65] 2024-02-07 04:33:31.641 INFO 31012 --- [ main] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 2024-02-07 04:33:31.880 INFO 31012 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2024-02-07 04:33:31.880 INFO 31012 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3717 ms 2024-02-07 04:33:32.215 INFO 31012 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2024-02-07 04:33:32.569 INFO 31012 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2024-02-07 04:33:32.659 INFO 31012 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2024-02-07 04:33:32.822 INFO 31012 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.10.Final 2024-02-07 04:33:33.157 INFO 31012 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} 2024-02-07 04:33:33.383 INFO 31012 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect 2024-02-07 04:33:34.255 INFO 31012 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2024-02-07 04:33:34.266 INFO 31012 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2024-02-07 04:33:34.906 WARN 31012 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning 2024-02-07 04:33:35.616 WARN 31012 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat server 2024-02-07 04:33:35.620 INFO 31012 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2024-02-07 04:33:35.624 INFO 31012 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2024-02-07 04:33:35.646 INFO 31012 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. 2024-02-07 04:33:35.650 INFO 31012 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat] 2024-02-07 04:33:35.676 INFO 31012 --- [ main] ConditionEvaluationReportLoggingListener : Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2024-02-07 04:33:35.742 ERROR 31012 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat server at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.22.jar!/:5.3.22] at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_392] at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.22.jar!/:5.3.22] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) [spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) [spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) [spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) [spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) [spring-boot-2.7.2.jar!/:2.7.2] at com.se.social.SocialApplication.main(SocialApplication.java:13) [classes!/:0.0.1-SNAPSHOT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_392] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_392] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_392] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_392] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) [social-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) [social-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) [social-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) [social-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat server at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:229) ~[spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.web.servlet.context.WebServerStartStopLifecycle.start(WebServerStartStopLifecycle.java:43) ~[spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) ~[spring-context-5.3.22.jar!/:5.3.22] ... 22 common frames omitted Caused by: java.lang.IllegalArgumentException: standardService.connector.startFailed at org.apache.catalina.core.StandardService.addConnector(StandardService.java:238) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.addPreviouslyRemovedConnectors(TomcatWebServer.java:282) ~[spring-boot-2.7.2.jar!/:2.7.2] at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:213) ~[spring-boot-2.7.2.jar!/:2.7.2] ... 24 common frames omitted Caused by: org.apache.catalina.LifecycleException: Protocol handler start failed at org.apache.catalina.connector.Connector.startInternal(Connector.java:1077) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.catalina.core.StandardService.addConnector(StandardService.java:234) ~[tomcat-embed-core-9.0.65.jar!/:na] ... 26 common frames omitted Caused by: java.net.SocketException: Permission denied at sun.nio.ch.Net.bind0(Native Method) ~[na:1.8.0_392] at sun.nio.ch.Net.bind(Net.java:461) ~[na:1.8.0_392] at sun.nio.ch.Net.bind(Net.java:453) ~[na:1.8.0_392] at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:222) ~[na:1.8.0_392] at org.apache.tomcat.util.net.NioEndpoint.initServerSocket(NioEndpoint.java:275) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:230) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1227) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:1313) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:614) ~[tomcat-embed-core-9.0.65.jar!/:na] at org.apache.catalina.connector.Connector.startInternal(Connector.java:1074) ~[tomcat-embed-core-9.0.65.jar!/:na] ... 28 common frames omitted
개발자
#aws
#springboot
#배포
답변 1
댓글 0
조회 595
일 년 전 · 손윤석 님의 새로운 댓글
emitter와 adapter에는 어떤 차이가 있나요?
socket.io adapter 구현을 위해 docs를 살펴보던 중 생긴 궁금증입니다. 두루뭉실하게 소켓을 관리하는 것이 adapater이고, 이 adapter들을 관리하는 것이 emitter라고 받아들여지기는 하지만, 정확한 개념은 아닌 것 같아 질문 남깁니다. 둘은 어떤 차이가 있는지, 어떠한 맥락에서 사용되는지도 같이 알려주시면 감사하겠습니다.
개발자
#socket.io
답변 1
댓글 1
조회 115
일 년 전 · 백승훈 님의 답변 업데이트
Spring WebSocket 통신 중 HttpOnly 쿠키에 저장된 JWT 토큰 접근 문제
안녕하세요, Spring과 React를 활용하여 실시간 채팅 기능을 구현 중인 학생입니다. 현재 저희 시스템은 사용자가 로그인을 성공하면, JWT 토큰을 생성하여 이를 HttpOnly 쿠키에 저장하고 있습니다. 이후 해당 토큰을 이용해서 사용자의 인증 및 인가를 처리합니다. 그리고 웹소켓을 화룡해 채팅 기능을 구현하고 있는데, 사용자가 채팅 메시지를 웹소켓을 통해 서버로 전송할 때마다, 해당 사용자의 JWT 토큰을 검사하여 유효한 사용자인지 확인하려고 합니다. 그러나 현재 쿠키가 HttpOnly로 설정되어 있어서, React에서 쿠키에 접근할 수 없습니다. 따라서 웹소켓 메시지를 보낼 때마다 JWT 토큰을 메시지에 포함시키지 못하고 있습니다. 구글링해서 찾아보니 다른 개발자들의 경우 클라이언트에서 헤더에 토큰을 포함하여 서버로 전송하고, 서버에서는 StompHeaderAccessor의 getFirstNativeHeader 메서드를 사용하여 토큰을 받아 사용자 검증을 하는 방식을 주로 사용하는 것 같습니다. 그러나 저희 시스템에서는 이 방식을 사용할 수 없어, 다른 해결 방안을 찾고 있습니다. 현재 제가 생각한 방식은 웹소켓 연결 시 웹소켓 세션에 해당 사용자의 토큰값을 저장하여 채팅 메시지가 서버로 전송될 때마다, 웹소켓 세션에 저장된 토큰값을 검증하는 방식입니다. 만약, 이 방식을 사용한다면 사용자 토큰값의 유효 기간이 끝나면 리프래시 토큰을 사용한 사용자 토큰 재발급 방식은 사용자 웹 브라우저 쿠키에 접근하지 못하니 불가능한가요? HttpOnly 쿠키에 저장된 JWT 토큰을 웹소켓 통신에서 어떻게 활용할 수 있을지 조언해주시면 감사하겠습니다.
개발자
#spring
#websocket
#react
#jwt
답변 1
댓글 0
조회 402
일 년 전 · 익명 개발자 님의 새로운 답변
socket.io 와 토큰 인증.
안녕하세요. 현재 프론트는 next13, 서버는 nest를 사용해서 간단한 채팅서비스를 구현하고있습니다. 현재 로그인을 하게 되면 토큰을 서버에서 클라이언트의 쿠키에 설정해주고있습니다. 클라이언트에서 이제 소켓에 연결할 때 토큰을 보내서 인증된 사용자인지 확인하려고 하는데, 이럴 경우 토큰을 어떻게 보낼수 있을까요,,? 현재 생각하는 방법은 사용자의 상세 정보를 불러오는 api를 만들어서 사용자의 상세 정보를 받아온 후, 그 사용자의 id를 토큰 대신 소켓 연결할때 보내려고 생각하고있습니다. 혹시 더 좋은 방법이 있을까요,,?
개발자
#next.js
#socket.io
#nest.js
답변 1
댓글 0
조회 165
10달 전 · 최유태 님의 질문 업데이트
어떤 ec2 인스턴스를 사용해야할지 모르겠습니다.
안녕하세요. 현재 프론트엔드 직무를 지망하는 취준생입니다. 자소서만 작성하다가는 개발 실력이 늘지 않아서 포트폴리오 겸, 제가 만들어보고 싶은 웹 사이트를 개발중입니다. 사이트 기능 중 멀티접속이 되는 메타버스를 만들려고 하는데 이를 위해서 socket통신용 node.js 서버를 구현했습니다. 서로의 캐릭터 위치를 동기화시키기 위해 각자 매 초에 60번씩 (즉, 1프레임에 1번) 자신 캐릭터의 위치를 socket으로 보내고 다른 사람들은 이 정보를 받아 다른 캐릭터의 위치를 업데이트 시키는 방식입니다. free티어로 제공하는 인스턴스로는 서버에 무리가 갈거같아서 유료 인스턴스를 구매해서 사용해볼 예정인데, 어떤 ec2가 이러한 작업에 어울리는지 판단이 어렵습니다. 그냥 개인적인 포트폴리오 사이트여서 동시접속자는 많아야 10명도 안될것으로 예상됩니다. 이런 상황에서 어떤 ec2를 사용해야할까요?
개발자
#aws-ec2
#aws
답변 1
댓글 0
추천해요 1
조회 82
일 년 전 · 고건 님의 새로운 댓글
nginx 관련 질문 있습니다 ㅠㅠ
안녕하세요, 현재 프로그래밍을 공부하고 있는 학생입니다. 공부를 하던 중 django를 사용해 프로젝트를 진행했고 aws, nginx, uwsgi 로 배포를 진행하게 되었는데, 배포는 성공적으로 됐지만 처리해야할 데이터가 많은 기능을 사용하면 자꾸 아래 오류가 뜨더군요. (퍼블릭 ip 주소는 X로 가렸습니다) 2023/11/07 15:14:13 [error] 7487#7487: *1 upstream timed out (110: Unknown error) while reading response header from upstream, client: xx.xxx.xxx.xxx, server: _, request: "POST /file_upload/upload/ HTTP/1.1", upstream: "uwsgi://unix:/home/ubuntu/docusift/uwsgi.sock", host: "xx.xxx.xxx.xx", referrer: "http://xx.xxx.xxx.xx/success_with_token/WeDkQYs84hDYcDsl/" 구글링을 해봐도, 스택오버플로우를 찾아봐도 110 오류가 unknown error로 뜨는 것에 대한 해결책은 나오지 않아서 이렇게 여쭤보게 되었습니다. 다만 구글링을 해본 결과 설정을 따로 만져줘야 한다는 것을 봐서 설정은 아래처럼 해놓은 상태인데, 아직 해결은 되지 않은 상황입니다. [uwsgi] chdir=/home/ubuntu/docusift/blog module=blog.wsgi:application master=True pidfile=/tmp/project-master.pid vacuum=True max-requests=5000 daemonize=/home/ubuntu/docusift/debug_uwsgi.log home=/home/ubuntu/docusift/venv virtualenv=/home/ubuntu/docusift/venv socket=/home/ubuntu/docusift/uwsgi.sock chmod-socket=666 socket-timeout=600 harakiri = 300 http-timeout = 300 server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { include /etc/nginx/uwsgi_params; uwsgi_pass django; proxy_buffer_size 512k; proxy_buffers 16 512k; proxy_busy_buffers_size 1024k; proxy_connect_timeout 500s; proxy_send_timeout 500s; proxy_read_timeout 500s; send_timeout 500s; } location /static/ { alias /home/ubuntu/docusift/blog/staticfiles/; } http { upstream django { server unix:/home/ubuntu/docusift/uwsgi.sock; } client_max_body_size 100M; proxy_connect_timeout 800s; proxy_send_timeout 800s; proxy_read_timeout 3600; 혹시라도 해결 방법을 아시는 분들 답변 주시면 정말 감사하겠습니다!!!
개발자
#배포
#aws
#ubuntu
#nginx
#uwsgi
답변 1
댓글 1
조회 173
일 년 전 · 익명 님의 질문
플러터에 sockjs
현재 프론트엔드 파트에서 플러터를 이용하여 모바일 개발을 진행하고 있습니다 진행중인 프로젝트에 채팅방 기능이 있는데 플러터에서는 웹소켓을 이용하기 위해서 web_socket_channel 과 같은 패키지를 이용하여 소켓통신을 하는것으로 알고있습니다 그런데 백엔드에서 소켓통신을 할때 스프링부트와 sockjs를 이용하여 소켓통신 서버를 구축하고 해당 채널을 구독하면 메세지를 보내는 구조로 구성해 나갈거라 말해줬습니다. 현재 소켓통신과 관련하여 아무것도 해본적이 없고 플러터에서 웹소켓통신을 하기위해 관련 강의만 몇개 찾아본게 전부라 현재 어떤방식으로 소켓통신이 이루어져야 하는지 감이 오질 않습니다. 1. 백엔드에서 sockjs를 이용하여 프론트엔드 플러터와 통신을 하려 하는데 가능한가요? 2. 가능하다면 어떤 패키지를 사용하여야 하나요? 3. end point를 websocket으로 구독하고 해당 채널에 이벤트를 통해 메시지를 전달해 준다고 하는데 프론트에서는 어떤 처리를 해줘야 하나요?? 아직 부트캠프를 진행중이며 해당 프로젝트의 핵심기능중 하나라 질문남겨봅니다. 프론트에서 어떤 처리를 해줘야 하고 백엔드에서는 각각 어떤 처리를 해야 하는지 궁금합니다.
개발자
#flutter
#spring-boot
#소켓통신
#sockjs
#프론트엔드
답변 0
댓글 0
조회 125
일 년 전 · 이상선 님의 새로운 답변
안드로이드 앱에 채팅 실시간 알림기능
안녕하세요 1인 개발로 안드로이드 앱을 개발하고 있는데 유저간 1:1 채팅 기능을 개발했는데 메세지 실시간 알림 을 추가하려는데 현재 socket.io와 NodeJS MySQL React Native 로 구현했습니다 앱의 푸시알림은 원시그널로 보내는데 이건 채팅알림에 적합하지 않다는 군요. 지금 이상태에서 파이어베이스를 통해서 실시간 푸시알림 추가가 될까요? socket.io 채팅앱에서 실시간 푸시알림 보통 어떤거 쓰시나여?
개발자
#react-native
#socket.io
답변 1
댓글 0
조회 295
일 년 전 · great 님의 새로운 답변
많은 유저 수를 감당할 수 있는 소셜 서비스의 백엔드 어떻게 구성하나요?
안녕하세요. 창업 겸 작은 프로젝트를 준비하고 있는 학생입니다. 소셜 앱 쪽으로 하고 있어. 많은 트래픽과 유저를 감당할 수 있는 백엔드를 구성하고자 합니다. 혼자 개발을 하고 있어 개발 리소스가 부족하고 원래 프론트를 주로 하다보니 많이 부족합니다. 저의 목적은 다음과 같습니다. 1. 최대 50만 유저까지 (물론 50만 유저 달성은 정말 어려운 일이라고 생각합니다) 2. Auto Scaling이 되어 배포 후에 큰 신경을 안 써도 되며 3. 최대한 적은 비용을 유지하고 싶습니다. 우선 제가 뭐라도 공부해보고 질문을 드려야 할 것 같아서 나름대로 구성해봤습니다. 백엔드 언어: express 프론트 언어: RN 서비스 요약: 매일 하나의 사진을 올리고 유저끼리 투표하는 서비스 (많은 socket 알림이 오감) 서버 배포: AWS API Gateway+ AWS Elastic Beanstalk or AWS lambda DB: mongoDB atlas 이미지 저장: s3 push: FCM - 여쭤보고 싶은 사항은 다음과 같습니다. 1. 배포를 AWS lambda를 고려하고 있습니다. 서버를 서버리스로 구성하면 더 저렴할까요? 2. mongoDB atlas에서 요금을 쓰는게, aws의 DocumentDB를 사용하는 것보다 더 저렴할까요? 3. 더 비용을 낮추기 위해서는 어떤 선택을 할 수 있을까요? 제가 뭘 더 알면 좋을까요? 많이 부족하고 긴 글 읽어주셔서 감사합니다.
개발자
#express
#aws
#react-native
#mongodb
답변 4
댓글 1
추천해요 26
조회 3,282
2년 전 · 박예진 님의 질문 업데이트
채팅 새로고침시 연결 끊기는 문제
안녕하세요. 현재 Websocket과 stompjs v6.0.0을 활용해 채팅을 구현했습니다. roomId로 여러 채팅방을 만들 수 있게 구현했고, 현재 새로고침을 하지 않는 이상 잘 돌아갑니다. 그러나, 새로고침 할 시에는 바로 연결이 끊겨 이전의 채팅 내역도 보이지 않고, 연결, 구독 내역이 사라집니다 ... 어떻게 reconnect 해야할까요? 단순히 채팅 페이지에서 useEffect로 connect를 다시 하니 이미 연결 구독이 된 상태라고 뜨더라구요 .... ㅠㅠ (고민글을 올렸을 때 채팅방이 생성되고, 연결 구독이 됩니다. 채팅 시작 버튼을 눌렀을 경우에는 본인이 연결 구독이 되어 1대 1로 상대방과 채팅이 시작되는 구조입니다. ) import { CompatClient, Stomp } from "@stomp/stompjs"; import { createContext, useContext, useMemo, useRef } from "react"; import { useSetRecoilState } from "recoil"; import { messageState } from "../../states/chatting"; import audio from "../../assets/audios/chatting.mp3"; const ChatContext = createContext( {} as { connect: (roomId: number) => void; disconnect: () => void; send: (roomId: number, message: string) => void; }, ); export const useChatContext = () => useContext(ChatContext); export function ChatProvider({ children }: any) { const setMessages = useSetRecoilState(messageState); const token = localStorage.getItem("accessToken"); // 채팅 연결 구독 const client = useRef<CompatClient>(); const connect = (roomId: number) => { client.current = Stomp.over(() => { const sock = new WebSocket("wss://m-ssaem.com:8080/stomp/chat"); return sock; }); client.current.connect( { token: token, }, () => { client.current && client.current.subscribe( `/sub/chat/room/${roomId}`, (message) => onMessageReceived(message, roomId), { token: token!, }, ); }, ); return client; }; const onMessageReceived = (message: any, roomId: number) => { const audioElement = new Audio(audio); audioElement.play(); setMessages((prevMessages) => { const updatedMessages = { ...prevMessages, [roomId]: [...(prevMessages[roomId] || []), JSON.parse(message.body)], }; return updatedMessages; }); }; // 채팅 나가기 const disconnect = () => { if (client.current) { client.current.disconnect(() => { window.location.reload(); }); } }; // 채팅 보내기 const send = (roomId: number, message: string) => { if (client.current) { client.current.send( `/pub/chat/message`, { token: token, }, JSON.stringify({ roomId: roomId, message: message, type: "TALK", }), ); } }; const handlers = useMemo(() => ({ connect, disconnect, send }), []); return ( <ChatContext.Provider value={handlers}>{children}</ChatContext.Provider> ); } ----------이 부분은 connect 하는 부분입니다 --------- const { connect } = useChatContext(); const chatRoomId = worryBoard && worryBoard.chatRoomId; const handleStartChatting = () => { navigate(`/chatting`); connect(chatRoomId!!); }; ------------ 채팅 페이지는 따로 있습니다 --------------
개발자
#websocket
#stompjs
#채팅
#chatting
#react
답변 0
댓글 0
조회 326
2년 전 · 박예진 님의 새로운 댓글
채팅 기능 client 가 null 값이 돼요
하나의 페이지에서 connectHandler를 작동하고 또다른 페이지에서 sendHandler를 작동하려고 하는데 이렇게 해서는 useChat()이 리렌더링 되면서 client 값이 초기화가 되더라구요 값을 유지하고 싶고 recoil에 client를 담는 건 불가능이라고 떠서... connectHandler와 sendHandler를 다른 hooks로 분리하는 방법도 생각해봤는데 그러면 또 client값이 connect한 값이 아니더라구요 무슨 방법이 있을까요? 제발 도와주세요 ㅠㅠ (한 페이지에서 connectHandler, sendHandler, disconnectHandler 실행하면 잘 작동합니다!) import { CompatClient, Stomp } from "@stomp/stompjs"; import { useRef } from "react"; import { useRecoilState } from "recoil"; import { inputMessageState, messageState } from "../../states/chatting"; export function useChat() { const [messages, setMessages] = useRecoilState(messageState); const [inputMessage, setInputMessage] = useRecoilState(inputMessageState); const token = localStorage.getItem("accessToken"); // 채팅 연결 구독 const client = useRef<CompatClient>(); const connectHandler = () => { client.current = Stomp.over(() => { const sock = new WebSocket("wss://m-ssaem.com:8080/stomp/chat"); return sock; }); client.current.connect( { token: token, }, () => { client.current && client.current.subscribe(`/sub/chat/room/1`, onMessageReceived, { token: token!, }); }, ); }; const onMessageReceived = (message: any) => { setMessages((prevMessage) => [...prevMessage, JSON.parse(message.body)]); }; // 채팅 나가기 const disconnectHandler = () => { if (client.current) { client.current.disconnect(() => { window.location.reload(); }); } }; // 채팅 보내기 const sendHandler = () => { if (client.current && inputMessage.trim() !== "") { client.current.send( `/pub/chat/message`, { token: token, }, JSON.stringify({ roomId: 1, message: inputMessage, type: "TALK", }), ); setInputMessage(""); } }; return { connectHandler, disconnectHandler, sendHandler, }; }
개발자
#react
#chatting
#stompjs
답변 1
댓글 8
조회 231
2년 전 · 박예진 님의 질문 업데이트
stompjs, WebSocket을 활용한 채팅에서 subscribe 콜백함수 실행 안 되는 오류
stompjs, WebSocket을 활용한 채팅에서 subscribe 콜백함수 실행 안 되는 오류입니다. 일단 버전은 stompjs 2.3.3 입니다. 채팅 connect와 subscribe 잘 되는 거 확인했고, 다른 chatting 페이지에서 send까지 하면서, 채팅되는 거 확인했는데 onMessageReceived라는 콜백함수가 실행되지 않아요. 그래서 채팅내역을 못 불러오고 있어요.. 도와주세요 ㅠㅠ 아래 사진은 connect, subscribe, send 과정입니다.
개발자
#react
#stompjs
#websocket
답변 0
댓글 0
조회 126
2년 전 · 조용구 님의 새로운 댓글
Socket.io를 이용해 DB데이터 실시간 연동하기
Socket.io를 처음 접해보는 코린이입니다 데이터베이스에 저장된 값을 실시간으로 업데이트 해서 보여주고싶어서 찾아보게 됐습니다.. DB 연결, 인서트, 소켓 전송, 받아오기까지는 성공했는데 DB내용을 보여주는것과 그 데이터를 새로고침없이 업데이트 하는 방법을 알고싶습니다.
개발자
#소켓통신
#실시간
#데이터베이스
#db
#socket.io
답변 1
댓글 2
조회 440
2년 전 · 최충은 님의 새로운 답변
airflow ui 에서 mysql connection 시 오류발생 (도와주세요 ㅠㅠ)
airflow ui 에서 mysql 을 connection 하면 "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)" 오류가 발생하는데 구글링, stackoverflow, chat-gpt 에서 나온 온갖 방법들을 다 동원해도 해결하지 못하고 있습니다. airflow 는 docker 에서 실행중이고 mysql 은 local 에서 실행 중 입니다. 윈도우 환경입니다 ㅠㅠ 관련해서 해결하신 경험 있으신 분 계신가요 ..? 도움 받을 곳이 없어서 질문 올립니다 ㅠㅠ
개발자
#airflow
#mysql
답변 1
댓글 0
조회 103
2년 전 · 커리어리 AI 봇 님의 새로운 답변
리액트로 스프링과 웹소켓 채팅방을 구현했는데 자동 랜더링이 안됩니다..
안녕하세요! 현재 웹소켓으로 스프링과 채팅기능을 구현중에 있습니다 채팅방에서 채팅을 보내고 받는 건 가능한 상태인데 같이 채팅방에 입장해서 A가 B한테 보냈을 때 B가 페이지를 새로고침 하지 않으면 채팅이 자동 랜더링이 되지 않는 상황인데 여러 방법을 참고하고 해봤지만.. 성공하지 않았습니다 어떻게 풀어나가야 할지 잘 모르겠습니다 ㅠㅠ 코드가 길지만 ... 혹시 답변이 가능할까해서 참고해봅니다 좋은 키워드도 추천해주시면 감사하겠습니다!!... export const ChatRoomPage = () => { //메뉴 모달 const [isModalOpen, setIsModalOpen] = useState(false); const [isExitModalOpen, setIsExitModalOpen] = useState(false); const [backgroundPosition, setBackgroundPosition] = useState('static'); const location = useLocation(); const params = location.pathname; const segments = params.split('/'); const RoomUniqueId = segments[4]; const RoomId = segments[5]; const [messageData, setMessageData] = useState([]); const [messageList, setMessageList] = useState([]); const [message, setMessage] = useState(''); const accesskey = Cookies.get('Access_key'); // 채팅방 입장시 안내 문구 기능 const [showModal, setShowModal] = useState(false); const client = useRef({}); useEffect(() => { console.log('유즈이펙트 쉴행'); setShowModal(true); connect('L'); return () => disconnect(); }, []); const connect = type => { client.current = new StompJs.Client({ brokerURL: 'ws://222.102.175.141:8081/ws-stomp', connectHeaders: { Access_key: `Bearer ${accesskey}`, }, debug: function (str) { console.log('str ::', str); }, onConnect: () => { if (type === 'L') { subscribe(); publish(); } else { subscribe1(); publish1(); } }, }); client.current.webSocketFactory = function () { return new SockJS('http://222.102.175.141:8081/ws-stomp'); }; client.current.activate(); return () => disconnect(); }; const subscribe = () => { client.current.subscribe(`/sub/chat/messageList/${localStorage.memberUniqueId}`, message => { // console.log('messageData11 : ', JSON.parse(`${message.body}`)); setMessageData(JSON.parse(`${message.body}`)); const data = JSON.parse(`${message.body}`); setMessageList(data.data.chatMessageList); }); }; const publish = () => { client.current.publish({ destination: `/pub/chat/messageList/${localStorage.memberUniqueId}`, body: JSON.stringify({ chatRoomId: RoomId, chatRoomUniqueId: RoomUniqueId, page: 0, }), }); }; const closeModal = () => { setIsModalOpen(false); setBackgroundPosition('static'); }; const openModal = () => { setIsModalOpen(true); setBackgroundPosition('fixed'); }; const handleBackdropClick = e => { console.log('e ::', e); if (e.target === e.currentTarget) { closeModal(); } }; const ExitopenModal = () => { setIsExitModalOpen(true); }; const ExitcloseModal = () => { setIsExitModalOpen(false); }; const ReportButtonHandler = () => { alert('곧 업데이트 예정입니다!'); }; // 채팅 보내기 const sendMessage = message => { console.log('message :: ', message); connect(); setMessage(''); return () => disconnect(); }; const subscribe1 = () => { client.current.subscribe(`/sub/chat/message/${RoomUniqueId}`, message => { setMessageData({ ...messageList, message }); }); }; const publish1 = () => { client.current.publish({ destination: `/pub/chat/message/${RoomUniqueId}`, body: JSON.stringify({ memberId: `${localStorage.memberId}`, memberName: `${localStorage.memberName}`, memberUniqueId: `${localStorage.memberUniqueId}`, memberProfileImage: `${localStorage.profileImage}`, chatRoomId: RoomId, chatRoomUniqueId: RoomUniqueId, message: message, }), }); }; const disconnect = () => { client.current.deactivate(); }; console.log('messageList :: ', messageList); return ( <> <div style={{ width: '100%', height: '100%', position: backgroundPosition, }} > <Background> <Topbar> <Link to={`${PATH_URL.PARTY_CHAT}/${localStorage.memberUniqueId}`}> <TopBackDiv> <LeftBack /> </TopBackDiv> </Link> <TopbarName>모임이름</TopbarName> <ModalBtn onClick={() => { openModal(); }} > <RoomMenuIcon /> </ModalBtn> </Topbar> <Container> <Contents> <ParticipantDiv>ㅇㅇㅇ님이 참여했습니다.</ParticipantDiv> {messageList?.map((data, index) => { return ( <OtherDiv key={index}> <div style={{ position: 'relative', }} > <OtherImg> <OtherProfile> <img src={data.memberProfileImage} alt="profile" style={{ width: '100%', height: '100%', borderRadius: '8px', }} /> </OtherProfile> <OtherHostIcon> <PartHostIcon /> </OtherHostIcon> </OtherImg> <OthertInfo> <OtherName>{data.sender}</OtherName> <OtherContents> <OtherChatText>{data.message}</OtherChatText> <OtherChatTime>12:19 pm</OtherChatTime> </OtherContents> </OthertInfo> </div> </OtherDiv> ); })}
개발자
#채팅
#웹소켓
#채팅기능
답변 2
댓글 0
조회 595
2년 전 · 커리어리 AI 봇 님의 새로운 답변
비동기작업에 사용되는 '링크'가 정확히 뭔가요?
Javascript를 배우고 있습니다. DOM공부를 마치고 ajax로 비동기 데이터 이동을 공부하는데 XMLHttpRequest나 WebSocket등의 사용을 해보고자 구글링과 유튭영상들을 아주 많이 봤는데 요청을 처리할 주소라고해서 링크가 항상 들어가는데 이 링크가 정확히 어떤 링크를 넣어야 하는건지, 링크를 직접 만들 수는 없는건지, 링크의 용량제한이나 구성은 백엔드 배포로만 가능한지 궁금합니다.
개발자
#ajax
#javascript
#node.js
답변 2
댓글 1
추천해요 1
조회 133
2년 전 · 커리어리 AI 봇 님의 새로운 답변
Api로 간단하게 데이터 저장
회사에서 카페24를 사용하는데 저는 퍼블리셔라 개발쪽은 진짜 기초적인것만 할 줄 아는 js초보라 Firebase나 httpxmlrequest, WebSocket 이런거 사용법을 잘몰라서 그러는지 검색해도 영상을 봐도 이해가 너무 어렵더라구요.. 혹시 간단한 예제로 사용자가 데이터 이를테면 문자열을 입력하면 데이터가 저장되어서 목록에 추가되고 새로고침해도 유지되려면 어떻게 해야하나요?
개발자
#javascript
답변 2
댓글 0
추천해요 1
조회 333
2년 전 · 커리어리 AI 봇 님의 새로운 답변
jenkins 구축 환경 문의
안녕하세요? 현재 jenkins를 운영할 환경을 Docker Image로 만들어, AWS의 ECS나 EKS에 진행 하려 하는데 궁금한 점 있습니다. jenkins의 경우 secret key나 기타 환경 변수의 파일을 보안상의 이유로 외부 Volume을 mount하여 관리 하는 것으로 알고 있습니다. 또한 Docker의 권고 사항으로 인하여 Docke in Docker 가 아닌 Docker out Docker 형태로 Host의 docker.socket을 사용 해야한다고도 알고는 있습니다. 그럼 여기서 질뮨 1. 보통 CI/CD 툴중 jenkins를 활용 하시는 분들은 해당 툴의 구축 환경을 serverless 형태가 아닌 native 인스턴스에 구축 하시나요? 2. ecs 혹은 eks 서비스에서는 별도의 mount volume을 활용 해야 할거 같긴한데... 관리와 이슈에 대한 포인트가 발생 할 확률이 큰가요? (특히나 Docker out Docker 형태일 경우 mount volume에는 docker socket이 없는데... docker의 권고를 무시해야하는 건지...) 궁금합니다.
개발자
#jenkins
#docker
#aws
#ci/cd
답변 1
댓글 0
조회 149
2년 전 · 김지태 님의 새로운 답변
백엔드에서 업데이트 된 정보를 프론트에서 바로 받아서 보여주는 경우 Socket을 쓰는게 좋을까요?
안녕하세요, 서비스에서 작업 중 페이지를 보여주기 위한 코드를 작성하고 있습니다. 백엔드에서 백엔드에 접근 가능한지 정보를 저장해 두고 프론트에서 그 정보를 받아서 페이지를 띄우려고 하는데요, 이런 경우에 어떤 방법 혹은 기술을 써야 할지 모르겠습니다. Notification처럼 Socket을 쓰면 좋을까요?
개발자
#socket
답변 1
댓글 0
조회 114
2년 전 · 손정현 님의 답변 업데이트
nextjs에서 Error: Client network socket disconnected before secure TLS connection was established 오류
nextjs 질문 있습니다! 프로젝트에서 getServerSideProps, getStaticProps를 사용하여 렌더링을 할 경우 페이지 첫 진입 자체는 문제 없는데 새로 고침을 하면 Error: Client network socket disconnected before secure TLS connection was established 위와 같은 오류가 계속 나는데 해결 방법 아시는 분 계신가요?
개발자
#nextjs
답변 1
댓글 0
조회 444
2년 전 · 커리어리 AI 봇 님의 새로운 답변
Next.js SSR + react-query 조합에서의 serializing 에러
안녕하세요! Next.js SSR + react-query 조합을 사용하려고 하는데요, page 컴포넌트 내 getServerSideProps 함수에서 prefetching을 받아온 후에 serializing 에러가 발생합니다. (Next.js는 13버젼입니다.) 에러 내용은 다음과 같습니다. Error: Error serializing `.dehydratedState.queries[0].state.data.headers` returned from `getServerSideProps` in "/top". Reason: `object` ("[object AxiosHeaders]") cannot be serialized as JSON. Please only return JSON serializable data types. 해당 에러 내용으로 구글링을 해보니, 대부분 getServerSideProps 함수 반환 코드에서 return { props: { dehydratedState: JSON.parse(JSON.stringify(dehydrate(queryClient))), }, }; 와 같이 dehydrate(queryClient)값을 JSON화 -> Object화를 하라고 하는데요, 이와 같이 사용해도 또 다시 아래와 같은 에러가 납니다. TypeError: Converting circular structure to JSON --> starting at object with constructor 'ClientRequest' | property 'socket' -> object with constructor 'Socket' --- property '_httpMessage' closes the circle Backend API는 Express.js를 사용하고 있으며, res.status(200).json({ data: ~ })와 같은 방식으로 응답을 주고 있습니다. 어떻게 해결할 수 있을까요? 코드 첨부가 안되네요, 아래는 page 컴포넌트가 위치한 파일의 전체 코드입니다. import type { ReactElement } from 'react'; import { dehydrate, QueryClient, useQuery } from '@tanstack/react-query'; import { format } from 'date-fns'; import TopMusicContainer from '~containers/TopMusicContainer'; import Layout from '~layouts/Layout'; import type { NextPageWithLayout } from '~pages/_app'; import TopMusicService from '~services/topMusicService'; import * as MusicType from '~types/musicType'; export async function getServerSideProps() { const queryClient = new QueryClient(); await queryClient.prefetchQuery(['fetchTopMusic'], () => { const params: MusicType.ListRequestType = { filter: 'title', keyword: '', page: 1, limit: 25, time: format(new Date(), 'yyyyMMddHH'), }; return TopMusicService.list(params); }); return { props: { dehydratedState: JSON.parse(JSON.stringify(dehydrate(queryClient))), }, }; } const Top: NextPageWithLayout = (): JSX.Element => { const { data, isLoading } = useQuery({ queryKey: ['fetchTopMusic'], queryFn: () => { const params: MusicType.ListRequestType = { filter: 'title', keyword: '', page: 1, limit: 25, time: format(new Date(), 'yyyyMMddHH'), }; return TopMusicService.list(params); }, }); return ( <section> <TopMusicContainer /> </section> ); }; Top.getLayout = function getLayout(page: ReactElement) { return <Layout>{page}</Layout>; }; export default Top;
개발자
#react
#next.js
#ssr
#react-query
답변 2
댓글 3
추천해요 4
조회 3,061
2년 전 · 손정현 님의 답변 업데이트
[SMTP] 메일 발송이 잘되는데 중간에 가끔 예외가 터지는 이유가 궁금합니다.(SMTPSendFailedException 또는 javax.mail.MessagingExcept)
회사 메일로 고객에게 메일을 발송을 해주는데 잘되다가 가끔 아래와 같은 예외가 발생합니다. 재발송 처리를 하였지만 근본적인 원인이 알고싶습니다. 도와주세요ㅠㅠ 예외 로그1) com.sun.mail.smtp.SMTPSendFailedException: [EOF] at com.sun.mail.smtp.SMTPTransport.issueSendCommand at com.sun.mail.smtp.SMTPTansprot.finishData at com.sun.mail.smtp.SMTPTransport.sendMessage at javax.mail.TransPort.send0 at javax.mail.TransPort.send 예외 로그2) javax.mail.MessagingException: Can’t send command to SMTP host at com.sun.mail.smtp.SMTPTransport.sendCommand at com.sun.mail.smtp.SMTPTransport.sendCommand at com.sun.mail.smtp.SMTPTransport.close at javax.mail.Transport.send0 at javax.mail.Transport.send ----- SSL을 사용하고 있으며 service로 구현한 곳에 설정한 값은 아래와 같습니다. SMTP_PROT는 SSL이라 465 사용합니다! props.put("mail.smtp.host", SMTP_HOST); // SMTP Host props.put("mail.smtp.socketFactory.port", SMTP_PORT); // SSL Port props.put("mail.debug", "debug"); props.put("mail.smtp.auth", "true"); // Enabling SMTP Authentication
개발자
#java
#smtp
#메일
#javax.mail.messagingexception
#smtpsendfailedexception:-[eof]
답변 1
댓글 0
추천해요 3
조회 958
2년 전 · 강병진 님의 새로운 댓글
nodejs - clientIP를 얻고싶습니다.
안녕하세요 ! nodejs에서 client ipaddress를 얻고 싶어서 알아보던중에. nginx를 거치게 되면 client의 기존의 ip를 얻어오지 못하고 있습니다 ! 구글링해도 잘 안되서 질문남깁니다 ㅠ - proxy.config proxy_set_header X-Real-IP $proxy_protocol_addr; proxy_set_header X-Forwarded-For $proxy_protocol_addr; - ip 구하는 코드 const ipAddress = req.headers['x-forwarded-for'] || req.socket.remoteAddress; 이렇게 해보고 막힌 상태입니다 !
개발자
#node
답변 2
댓글 3
추천해요 2
조회 273
3년 전 · 권민수 님의 새로운 답변
사이드 프로젝트에 적용해볼만한 기술이 뭐가 있을까요?
현재 다니고 있는 회사에서는 스프링 + jsp만 하고 있습니다. 그러다가 react + springBoot로 사이드 플젝을 하며 관련 기술들을 좀 익히고 싶은데, 문제는 회사에 사수나 웹 관련 사람들이 없다는 겁니다. 제가 좀 익혀볼만한 기술들이 뭐가 있을지 잘 모르겠습니다. 그래서 구체적으로 뭘 만들지가 잘 그려지지 않네요. 예를 들어 부동산 API와 같은 오픈 API를 이용해서 실거래가를 조회하고 websocket으로 관리자와 상담 및 알림.. 이런 식으로 꼭 최신 기술이 아니더라도 적용해보고 만들면서 공부해보면 좋은 기술들을 이번에 해볼 생각인데, 적용하거나 공부해볼 만한 게 어떤 게 있을까요? 추천 부탁드립니다.
개발자
답변 1
댓글 0
조회 286