Responder + WebSocket으로 간단한 채팅 앱
TL;DR
WebSocket을 거의 사용한 적이 없었기 때문에 사용해 보았다.
사용자 인증이 없는 간이적인 채팅 앱이라면 바로 만들 수 있을 것 같았기 때문에 2018년에 방금 출시된 파이썬 웹 프레임워크 Responder을 사용해 구현해 보았다. (원래 Responder의 정보가 너무 적은데 WebSocket을 사용하고 있는 기사 등이 전무했기 때문에 소스 코드를 읽거나 Responder의 베이스가 되고 있는 Starlette도 조사하거나 해 꽤 힘들었다…)
Responder 은 Python 세계에서 유명한 Kenneth Reitz 씨작( requests 이나 pipenv 만든 사람)
완제품 : htps : // 기주 b. 이 m / ksk001100 / re s pon r-b b c t
프로젝트 구성
$ tree
.
├── Pipfile
├── Pipfile.lock
├── app.py
└── static
└── index.html
프로젝트 만들기
이번에도 pipenv
에서 프로젝트를 작성하겠습니다.
$ mkdir responder-websocket-chat
$ cd responder-websocket-chat
$ pipenv --python 3.6.5
$ pipenv install responder --pre
서버 구현
app.py
에 서버 프로그램을 작성합니다.
app.pyimport responder
api = responder.API()
clients = {} # 1
@api.route('/ws', websocket=True)
async def websocket(ws):
await ws.accept()
key = ws.headers.get('sec-websocket-key') # 2
clients[key] = ws # 3
try:
while True:
msg = await ws.receive_text()
for client in clients.values(): # 4
await client.send_text(msg)
except:
await ws.close()
del clients[key] # 5
api.add_route('/', static=True)
api.run()
$ tree
.
├── Pipfile
├── Pipfile.lock
├── app.py
└── static
└── index.html
프로젝트 만들기
이번에도 pipenv
에서 프로젝트를 작성하겠습니다.
$ mkdir responder-websocket-chat
$ cd responder-websocket-chat
$ pipenv --python 3.6.5
$ pipenv install responder --pre
서버 구현
app.py
에 서버 프로그램을 작성합니다.
app.pyimport responder
api = responder.API()
clients = {} # 1
@api.route('/ws', websocket=True)
async def websocket(ws):
await ws.accept()
key = ws.headers.get('sec-websocket-key') # 2
clients[key] = ws # 3
try:
while True:
msg = await ws.receive_text()
for client in clients.values(): # 4
await client.send_text(msg)
except:
await ws.close()
del clients[key] # 5
api.add_route('/', static=True)
api.run()
$ mkdir responder-websocket-chat
$ cd responder-websocket-chat
$ pipenv --python 3.6.5
$ pipenv install responder --pre
app.py
에 서버 프로그램을 작성합니다.app.py
import responder
api = responder.API()
clients = {} # 1
@api.route('/ws', websocket=True)
async def websocket(ws):
await ws.accept()
key = ws.headers.get('sec-websocket-key') # 2
clients[key] = ws # 3
try:
while True:
msg = await ws.receive_text()
for client in clients.values(): # 4
await client.send_text(msg)
except:
await ws.close()
del clients[key] # 5
api.add_route('/', static=True)
api.run()
1의 변수
clients
는 접속중의 클라이언트를 포함하는 사전. 메시지를 받으면 모든 클라이언트에게 메시지를 브로드 캐스트하기 위해 저장됩니다. 4 단계에서 모든 연결 클라이언트에 메시지를 브로드 캐스트
5의 예외 처리 부분은 연결이 끊어지거나 다시로드 될 때 사전에 연결되지 않은 클라이언트가 저장되어 메모리를 압축하기 때문에 클라이언트를 삭제합니다.
전면 구현
JS의 처리 부분만 씁니다. 귀찮아서 실제로는 static/index.html
에 script 태그를 직접 묻고 있습니다.
const ws = new WebSocket('ws://localhost:5042/ws');
// メッセージを入力するinput要素
const textbox = document.getElementById('textbox');
// チャットのメッセージを表示するのul要素
const chat = document.getElementById('chat');
// 1
ws.onmessage = function (e) {
// メッセージのli要素作成
const li = document.createElement('li');
li.textContent = e.data;
chat.appendChild(li);
};
// 2
window.onload = function () {
textbox.addEventListener('keypress', function (e) {
// エンターキーが押された場合メッセージを送信
if (e.keyCode == 13) {
ws.send(textbox.value);
textbox.value = "";
}
});
}
const ws = new WebSocket('ws://localhost:5042/ws');
// メッセージを入力するinput要素
const textbox = document.getElementById('textbox');
// チャットのメッセージを表示するのul要素
const chat = document.getElementById('chat');
// 1
ws.onmessage = function (e) {
// メッセージのli要素作成
const li = document.createElement('li');
li.textContent = e.data;
chat.appendChild(li);
};
// 2
window.onload = function () {
textbox.addEventListener('keypress', function (e) {
// エンターキーが押された場合メッセージを送信
if (e.keyCode == 13) {
ws.send(textbox.value);
textbox.value = "";
}
});
}
1은 서버에서 브로드 캐스트 될 때 처리
2는 메시지를 입력하고 Enter 키를 눌렀을 때 처리합니다
실제 동작
Reference
이 문제에 관하여(Responder + WebSocket으로 간단한 채팅 앱), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ksk001100/items/6da58ef0152bb14869ff
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Responder + WebSocket으로 간단한 채팅 앱), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ksk001100/items/6da58ef0152bb14869ff텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)