묻고 답해요
131만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨네이버(치지직)에서 대용량 채팅 TPS 처리를 위한 웹소켓 통신에 대해 알아보고 학습하기
채팅이 2번씩 전송되는 현상 질문
안녕하세요 go 서버 구축 이후 프론트 연결하여 채팅을 전송하면 같은 메시지가 두 번씩 전송되는 현상이 발생합니다.강의를 여러 번 체크하면서 봤는데 소스 코드가 다른 점은 찾지 못했습니다. 제가 작성한 socket.go 코드인데 어떤 부분이 문제가 있을까요package network import ( "chat_server_golang/types" "log" "net/http" "time" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) var upgrader = &websocket.Upgrader{ReadBufferSize: types.SocketBufferSize, WriteBufferSize: types.MessageBufferSize, CheckOrigin: func(r *http.Request) bool {return true}, } // http 요청을 websocket 통신으로 업그레이드 해준다. type message struct { Name string Message string Time int64 } type Room struct { Forward chan *message Join chan *client Leave chan *client Clients map[*client]bool } type client struct { Send chan *message Room *Room Name string Socket *websocket.Conn } func NewRoom() *Room { return &Room { Forward: make(chan *message), Join: make(chan *client), Leave: make(chan *client), Clients: make(map[*client]bool), } } func (c *client) Read() { // 클라이언트가 들어오는 멧세지를 읽는 작업 defer c.Socket.Close() for { var msg message err := c.Socket.ReadJSON(&msg) if err != nil { if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) { break } panic(err) } else { log.Println("READ : ", msg, "client", c.Name) log.Println() msg.Time = time.Now().Unix() msg.Name = c.Name c.Room.Forward <- &msg } msg.Name = c.Name c.Room.Forward <- &msg } } func (c *client) Write() { // 클라이언트가 나가는 메시지를 전송하는 작업 defer c.Socket.Close() for msg := range c.Send { log.Println("WRITE : ", msg, "client", c.Name) log.Println() err := c.Socket.WriteJSON(msg) if err != nil { panic(err) } } } func (r *Room) RunInit() { // room 에 있는 모든 채널 값을 받는 작업 // join leave 등의 메시지 큐를 처리, 무한반복문을 돌면서 처리 for { log.Println(r.Clients) log.Println(r.Forward) select { case client := <-r.Join: r.Clients[client] = true case client := <-r.Leave: r.Clients[client] = false close(client.Send) delete(r.Clients, client) case msg := <-r.Forward: for client := range r.Clients { client.Send <- msg } } } } func (r *Room) SocketServe(c *gin.Context) { socket, err := upgrader.Upgrade(c.Writer, c.Request, nil) if err != nil { panic(err) } userCookie, err := c.Request.Cookie("auth") if err != nil { panic(err) } log.Println("userCookie", userCookie) client := &client{ Socket: socket, Send: make(chan *message, types.MessageBufferSize), Room: r, Name: userCookie.Value, } r.Join <- client // 채팅방에 클라이언트가 들어왔다고 알림 defer func() { r.Leave <- client }() // 클라이언트가 나갔다고 알림, 클라이언트가 나가면서 defer 함수가 실행된다. go client.Write() client.Read() }2024/05/20 01:39:17 userCookie auth=one 2024/05/20 01:39:17 map[0x14000512600:true] 2024/05/20 01:39:17 0x14000192600 2024/05/20 01:39:21 READ : { hi 0} client one 2024/05/20 01:39:21 2024/05/20 01:39:21 map[0x14000512600:true] 2024/05/20 01:39:21 0x14000192600 2024/05/20 01:39:21 map[0x14000512600:true] 2024/05/20 01:39:21 0x14000192600 2024/05/20 01:39:21 WRITE : &{one hi 1716136761} client one 2024/05/20 01:39:21 2024/05/20 01:39:21 WRITE : &{one hi 1716136761} client one 2024/05/20 01:39:21
-
미해결Next + React Query로 SNS 서비스 만들기
로그인 모달창 새로고침 시 배경 메인 페이지 사라지는 현상
로그인 버튼을 클릭하면 우선 '/login' 주소로 이동했다가 'i/flow/login'으로 이동하기 때문에 이때 '/login'에서 배경이 메인 컴포넌트를 보여줘야 메인 페이지가 바탕이 되고로그인 모달 창을 띄운다는 점은 이해했습니다.따라서 app/(beforeLogin)/login/page.tsx 에서 Main 컴포넌트를 보여주도록 했습니다.export default function Login() { const router = useRouter(); router.replace("/i/flow/login"); return <Main />; } 문제는 '/i/flow/login' 에서 새로고침하면 모달 창은 그대로지만 배경은 메인 페이지가 아닙니다. 이때 아래와 코드와 같이 따로 Main 컴포넌트를 불러오면 새로고침 시, 배경은 메인 페이지로 잘 나옵니다.그런데 강의와 깃허브 코드를 보니 LoginModal 컴포넌트만 보여주고 있습니다.LoginModal 컴포넌트만 있어도 app/(beforeLogin)/page.tsx에서 Main 컴포넌트를 보여주고 있으므로app/(beforeLogin)/layout.tsx에서 Main 컴포넌트가 {children}에 할당된다고 생각했습니다.따라서 아래 코드에서 Main 컴포넌트가 없어도 배경은 메인 페이지가 나온다고 생각했습니다. 아래 코드와 같이 Main 컴포넌트가 있으면 새로고침 시, 메인 페이지가 배경이 되고 그 위에 로그인 모달창이띄워지지만 Main 컴포넌트가 없으면 새로고침 시, 메인 페이지가 빈 페이지가 나옵니다. 여기서 Main 컴포넌트를 넣어서 해결해도 되는건지 의문이 들었습니다. 아래 코드에서 Main 컴포넌트를 넣지 않으면 Main 페이지가 어떻게 배경으로 보여지는 건지 알고 싶습니다!import LoginModal from "@/app/(beforeLogin)/@modal/(.)i/flow/login/page"; import Main from "@/app/(beforeLogin)/_component/Main"; export default function Page() { return ( <> <LoginModal /> <Main /> </> ); }
-
해결됨[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)
3회 기출유형(작업형2)
RandomForestClassifier 에서pred=r.predict_proba(X_val)[:,1] 로 적혀있는데이전 회차까지는 (X_val)까지로만 공부했는데이번 문제에서는 [:,1]이 추가된 이유가 뭔지 궁금해요!
-
미해결김영한의 자바 입문 - 코드로 시작하는 자바 첫걸음
short, int
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.안녕하세요. 백엔드 개발을 하고 있는 주니어 개발자입니다.질문이 있습니다. short는 2byte이고 int는 4byte면 2byte 이상 4byte 이하 값에 대한 연산은 int보다 short를 사용하는 것이 메모리나 속도 측면에서 적합하지 않나요? 보통 int를 사용하는건 굳이 short를 사용할만한 메리트가 없어서 그런걸까요? 구글링 해봤을 땐 자바에서는 연산을 할 때 피연산자를 4byte로 저장하기 때문에 short는 오히려 int형으로 변환 후 연산을 한다고 하던데 정확히 이해하기가 쉽지 않아서요,,, 혹시 답변 가능하시다면 부탁드리겠습니다.. 감사합니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
전체 회원 다 뜨는거 말고 원하는 아이디만 찾을떄 어떻게해야 할까요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] <!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <body> <div class="container"> <form action="/members/find" method="post"> <div class="form-group"> <label for="name">찾기</label> <input type="text" id="name" name="name" placeholder="이름을 입력하세요"> </div> <button type="submit">찾기버튼</button> </form> </div> <!-- /container --> </body> </html>find.html입니다.<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <body> <div class="container"> <div> <table> <thead> <tr> <th>#</th> <th>이름</th> </tr> </thead> <tbody> <tr th:each="member : ${members}"> <td th:text="${member.id}"></td> <td th:text="${member.name}"></td> </tr> </tbody> </table> </div> </div> <!-- /container --> </body> </html> memberfind.html 입니다 memberController.java 입니다 @GetMapping("members/find") public String find(MemberForm form) { return "members/find"; } @PostMapping("members/find") public String find(Model model) { List<Member> members = memberService.findMembers(); model.addAttribute("members", members); return "members/memberfind"; } } List<Member> members = memberService.findMembers(); 여기 부분을 List<Member> members = memberService.findOne(); 으로 바꾸어야할텐데 ()-> 여기안에 매개변수를 뭘로 해야할까요
-
미해결Vue3 완벽 마스터: 기초부터 실전까지 - "실전편"
질문있습니다!
안녕하세요 짐코딩님! 기본부터 실전편까지 완강하고 실무에 적응중입니다! 강의와는 상관없는 내용이지만 궁금한게 있습니다!현재 실무에서 드롭다운 여러개를 클릭 하여 form에 업데이트해서 업로드 하는 기능과 페이지를 구현하고 있습니다. 제가 강의를 좀 급하게 들어서 기억을 잘 못하는건지, 아직 실력이 부족해서 watch문으로 form을 관리하고 있는데요.예를들면,watch(([data1, data2, data3..]), ([newData1, newData2,newData3...]) => {if(newData1 && newData2 && newData3) { formData.value => { ...formData, data1 = newData1, data2 = newData2, ... } }}, {immediate: true, deep: true})대략 이런 느낌입니다..! 근데 감지해야할 데이터의 수가 10개가 넘어가면서 코드 퀄리티가 떨어진다고 느끼고있는데, 도통 어떻게 개선해야할지 모르겠습니다.. 그리고 찾아보니 watch문을 많이 사용하면 좋지 않다고 하던데,,ㅠㅠ 저는 거의 모든 코드가 watch문을 사용하고 있었는데,, 최대한 computed로 대체하는게 좋을지도 궁금합니다,,강의와는 연관없는 질문이지만, 저에겐 짐코딩님이 vue 1타 강사님이시기 때문에..ㅎㅎ 어떻게 리팩토링하는게 좋을지 조언 좀 부탁드리겠습니다..😭
-
미해결[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버
리소스 파일 경로
강사님 혹시 제 코드와 강사님 코드를 비교하려고 파일을 다운받았는데요 리소스파일 이미지 경로가 틀려서 확인을 못하는데 혹시 어디서 변경할 수 있는지 알 수 있을까요? 오류는 계속 이렇게 뜹니다.
-
미해결
특정 강의에서 무한로딩이 걸려요
김영한의 실전 자바 - 기본편이 강의에서 아직 듣지못한 강의들과 강의 시간이 좀 긴 것들이 자꾸 무한로딩이 걸립니다.. 크롬 강력 새로고침, 시크릿모드를 해봐도 안되고 기기를 바꿔도 동일한 문제가 반복되서 문의 드립니다.추가로 확인해보니 다른 강의에서도 동일한 증상이 발견됐습니다..
-
해결됨외워서 끝내는 네트워크 핵심이론 - 기초
TCP 연결 종료과정 TIME_WAIT
TCP 연결 종료과정에서 (4-way handshaking), TIME_WAIT 를 최대한 줄이기 위해서 client가 active 하게 종료를 하자고 하는건 이해를 했습니다. 그러면 server 입장에서는 TIME_WAIT가 없는데 socket 회수를 언제하는지 궁금합니다. client 의 마지막 ack를 받고 바로 socket 회수를 하나요? 그러면 client도 server에게 마지막 ack를 보내면서 바로 socket 회수를 하면될텐데 TIME_WAIT의 존재의의가 궁금합니다.
-
미해결김영한의 자바 입문 - 코드로 시작하는 자바 첫걸음
switch문 12분55초
자바의 새로운 기능을 별도로 깊이있게 다뤄주신다고 하셨는데 이것도 고급편에서 다뤄주시는건가요?
-
미해결백엔드 개발자 성능 개선 초석 다지기
nGrinder validate가 안됩니다.
다른 질문을 보니 www.nate.com으로 시도해보라하여 했지만 똑같이 되지 않습니다. Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during conversion: Unsupported class file major version 61 java.lang.IllegalArgumentException: Unsupported class file major version 61 Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during conversion: Unsupported class file major version 61 java.lang.IllegalArgumentException: Unsupported class file major version 61
-
미해결Verilog를 이용한 FPGA 활용 기초
10 bits * 10bits 연산 구현 질문
안녕하세요. 강사님 강의를 보던 중 10 bits * 10bits 연산 구현에서 bit position을 주석으로 두셔서 살펴 보던 중 곱셈에서 어떻게 bit position을 잡을 수 있는지 질문 드립니다. 어떻게 bit position 잡는지 공부 후 16bits * 16bits, 32bits * 32bits 두 곱셈도 스스로 학습해 보려 합니다.
-
미해결실무자가 알려주는 CANoe - CAPL과 Panel 기본 사용법
CAPL 강의 재생
강의가 재생되지 않습니다. 확인 부탁 드립니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
사용자 입력값을 ILIKE에 집어넣었는때 보안적으로 어떤가요?
ILIKE와 같은 유틸함수에 직접적으로 사용자 입력값을 받을때 sql 인젝션이 방어되는지 궁금합니다. 검색해서 찾아보니 파라매터 바인딩하는 방법이 있는것 같은데 queryBuilder를 해야하는 것 같더라구요 sql injection 방어를 위해서 유틸함수를 쓰지 못하고 queryBuilder를 해야하는 거면 typeorm을 사용했을때 장점이 줄어드는 것 같아서 고민됩니다.
-
해결됨[퇴근후딴짓] 빅데이터 분석기사 실기 (작업형1,2,3)
predict, predict_proba 차이
3-5 classification 강의 학습중인데,predict, predict_proba 차이가 잘 이해가 되지 않습니다.어떤 경우에 따라서 두 함수를 나누어쓰는걸까요?
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
에셋 구름 아이콘이 없어요
어디서 받을 수 있나요?다운로드 버튼이 아무리 찾아도 없습니다.
-
미해결RDBMS Modeling 실습
RootModel에 대한 질문
RootModel에 있다는 뜻은 모든 테이블에 기본적으로 관리하는 attribute가 된다는 뜻으로도 이해했는데요.그 중 companyId 은 왜 관리하는지 알 수 있을까요? 그리고 registerId나 modifierId를 관리하는 이유가 누가 이 테이블의 데이터를 업데이트(등록/수정) 했는지 전부 관리한기 위함일까요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
Content-Length 질문입니다.
package hello.servlet.basic.response; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "responseHeaderServlet", urlPatterns = "/response-header") public class ResponseHeaderServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //[status-line] response.setStatus(HttpServletResponse.SC_OK); //[response-headers] // response.setHeader("Content-Type", "text/plain;charset=utf-8"); response.setHeader("Cashe-Control", "no-cache, no-store, must-revalidate"); response.setHeader("Pragma", "no-cache"); response.setHeader("my-header", "hello"); //[Header 편의 메서드] content(response); //[message body] PrintWriter writer = response.getWriter(); writer.println("ok"); } private void content(HttpServletResponse response) { response.setContentType("text/plain"); response.setCharacterEncoding("utf-8"); } }ok에 println이면 3이 출력되어야하는데 4가 출력됩니다...print로 바꿔보면 2가 출력되고, println("o") 만 적으면 3이 출력되는데 ln붙였을 때 실제 길이에서 +1 되어야 하지 않나요? 본문이 제거된거라면 아예 0이 나와야할거같은데 이유를 잘 모르겠습니다...찜찜해서 질문 남깁니다!
-
미해결[입문자를 위한 UE5] Part4. 언리얼 엔진 C++
GamePlayAttribute & Protobuf
데디서버가 아닐때 protobuf 클래스를 그대로 사용하는 것을 상당히 좋은 방법이라고 생각했었는데, GameplayAttribute를 쓰면 앞의 방식을 포기하게 되는 경우가 있었나요? 아니면 사용하기는 하나 GameplayAttribute를 위해 protobuf에서 FGameplayAttributeData쪽에 복사를 해서 사용하려나요...
-
미해결김영한의 실전 자바 - 중급 2편
제네릭 메서드
역시 갓 영한님 믿고듣는 강의.. 감사합니다 질문이 하나 있습니다. public static <T> T genericMethod(T t) { System.out.println("generic print: " + t); return t; }이 코드에서 타입 지정해주는 T를왜 다 똑같은 타입으로 써야 하는지 궁급합니다. 예를 들자면 위 코드를 보면 매개변수 타입도 T이고 반환 타입도 T인데매개변수의 타입과 반환타입을 꼭 맞춰서 써야 하는지 궁금하네요 public static <T> T genericMethod(A t) { System.out.println("generic print: " + t); return t; }이런식으로는 왜 못쓰는건가요 ?(매개변수로는 String을 받지만 결과 타입은 Integer 로 할수도 있지않나요 ? 근데 제네릭 메서드는 왜 이렇게는 불가능한가요?)