| 1번째 줄: |
1번째 줄: |
| | == 개요 == | | == 개요 == |
| − | 웹소켓의 역사적 맥락은 다름 글을 참고하자. [https://medium.com/@chullino/http%EC%97%90%EC%84%9C%EB%B6%80%ED%84%B0-websocket%EA%B9%8C%EC%A7%80-94df91988788 HTTP에서부터 WEBSOCKET까지] | + | 웹소켓의 역사적 맥락은 다음 글을 참고하자. [https://medium.com/@chullino/http%EC%97%90%EC%84%9C%EB%B6%80%ED%84%B0-websocket%EA%B9%8C%EC%A7%80-94df91988788 HTTP에서부터 WEBSOCKET까지] |
| | + | |
| | + | = 작동방식 = |
| | + | |
| | + | === 처음 접속 === |
| | + | {| class="wikitable" |
| | + | !과정 |
| | + | !설명 |
| | + | !비고 |
| | + | |- |
| | + | |웹소켓 생성 |
| | + | |자바스크립트에서 웹소켓을 생성한다. |
| | + | |<code>const ws = new WebSocket(SOCKET_HOST + `/ws/users/`);</code> |
| | + | |- |
| | + | |신호 전달 |
| | + | |<code>/ws</code>로 시작하는 요청은 asgi > routing을 거쳐 컨슈머의 connect()에 전달된다. |
| | + | | |
| | + | |- |
| | + | |컨슈머 |
| | + | connect() |
| | + | |인증과정을 거쳐 해당 유저를 적절한 그룹, 레이어에 속하게 한다. |
| | + | | |
| | + | |} |
| | + | |
| | + | === 메시지 전달 === |
| | + | {| class="wikitable" |
| | + | !과정 |
| | + | !설명 |
| | + | !비고 |
| | + | |- |
| | + | |컨슈머 |
| | + | receive() |
| | + | |자바스크립트에서 웹소켓을 통해 전동한 메시지를 받는다. |
| | + | |<syntaxhighlight lang="python"> |
| | + | async def receive(self, text_data): |
| | + | text_data_json = json.loads(text_data) # 받은 객체를 변환해야 한다. |
| | + | message = text_data_json['message'] |
| | + | </syntaxhighlight> |
| | + | |- |
| | + | |장고에서 프론트로 전송 |
| | + | | |
| | + | |<syntaxhighlight lang="python"> |
| | + | # 현재 소켓으로 접속한 유저에게 전송 |
| | + | await self.send(text_data=json.dumps({ |
| | + | 'message': message, |
| | + | })) |
| | + | |
| | + | # 현재 소켓으로 접속한 유저와 그가 속한 층에 전송 |
| | + | await self.channel_layer.group_send( |
| | + | self.room_group_name, |
| | + | { |
| | + | 'type': 'chat_message', |
| | + | 'message': message, |
| | + | } |
| | + | ) |
| | + | </syntaxhighlight> |
| | + | |} |
| | + | |
| | + | === 웹소켓 종료 === |
| | + | {| class="wikitable" |
| | + | !과정 |
| | + | !설명 |
| | + | !비고 |
| | + | |- |
| | + | |컨슈머 |
| | + | disconnect() |
| | + | |웹소켓 종료 신호를 받으면 응답받는 메소드. |
| | + | |
| | + | |
| | + | 자바스크립트에서 웹소켓 종료신호를 받았을 때 어떻게 할지 편집이 가능하다.<syntaxhighlight lang="javascript+django"> |
| | + | ws.onclose = function (e) { |
| | + | console.log(e) |
| | + | notification.open({ |
| | + | message: "채팅이 종료되었습니다.", |
| | + | description: "새로운 채팅을 시작하세요", |
| | + | icon: <CloseCircleOutlined style={{ color: "red" }} />, |
| | + | }); |
| | + | }; |
| | + | </syntaxhighlight> |
| | + | |django에서 프론트쪽으로 종료신호를 보내고 싶다면 <code>self.close()</code> 메소드 |
| | + | |
| | + | |
| | + | 속한 그룹 모두를 종료시키고 싶다면 아래처럼.<syntaxhighlight lang="python"> |
| | + | await self.channel_layer.group_send( |
| | + | GROUP_NAME, |
| | + | { |
| | + | 'type': 'websocket.close', |
| | + | } |
| | + | ) |
| | + | </syntaxhighlight> |
| | + | |} |
| | [[분류:장고 기능구현(중급)]] | | [[분류:장고 기능구현(중급)]] |