Heroku에서 Express와 WebSocket을 사용하여 간단한 채팅 만들기
이번 내용
전회, Heroku에서 Express 앱 만들기 --- 기본 설정 , 지난번, Express와 Postgresql을 사용하여 Heroku로 로그인 페이지 만들기 , 계속.
이번에는 Express를 WebSocket 서버로 채팅을 만든다. Express에서 WebSocket 관련은 다양한 해설이 있지만 express-ws
를 사용하는 것이 편리했다 1
클라이언트 측에는 기본 WebSocket만을 사용했다.
서버측 구현
$ yarn add express-ws
에서 exoress-ws를 설치합니다. express-ws는 앱을 설정하기만 하면 app.ws(path, callback)
의 형태로 사용할 수 있게 된다
전회까지의 기본 부분, 이외의 추가분은
index.jsconst expressWs=require('express-ws')(app);
const chat=require('./src/chat');
//*** 略 ***//
app.ws('/chat', chat);
구현은 src/chat.js
와 별 파일로 해 두는 데이터의 교환은 JSON 형식을 사용한다. client에는 name 속성이 없으므로 여기에 연결 사용자 이름을 붙입니다.
src/chat.jslet clients=[];
const chat=(ws, req)=>{
clients.push(ws);
ws.on('message', message=>{
const json=JSON.parse(message);
clients.forEach(a=>{ if( a===ws && a.name==null ) a.name=json.user });
if( json.method!=null ) json.clients=clients.map(a=> a.name);
clients.forEach(a=>{ a.send(JSON.stringify(json)); });
});
ws.on('close', ()=>{
const name=clients.find(a=> a===ws).name;
clients=clients.filter(a=> a!==ws);
clients.forEach(a=>{ a.send(JSON.stringify({ user: name, method: 'close', clients: clients.map(a=>name) })); });
});
}
module.exports=chat;
클라이언트측 구현
js/chat.jswindow.addEventListener('DOMContentLoaded', ()=>{
const name=prompt('名前を入れてください');
document.getElementById('name').value=name;
const ws=new WebSocket(location.origin.replace('https', 'wss')+'/chat');
ws.addEventListener('open', ()=>{ ws.send(JSON.stringify({ user: name, method: 'connect' })); });
const input=document.getElementById('input');
document.getElementById('send').addEventListener('click', ()=>{
const text=input.value;
if( text.length>0 ){
const json={ user: name, message: text };
ws.send(JSON.stringify(json));
}
input.value='';
});
const output=document.getElementById('output');
ws.addEventListener('message', message=>{
const json=JSON.parse(message.data);
const line=document.createElement('div');
if( json.clients!=null ){
document.getElementById('n-client').innerHTML='只今、'+json.clients.length+'人が接続しています';
if( json.method==='connect' ){ line.innerHTML=json.user+'が接続しました'; }
else if( json.method==='close' ){ line.innerHTML=json.user+'が接続を切りました'; }
else console.log(不正なメソッドです, json.method);
output.appendChild(line);
}
else if( json.message!=null ){
line.innerHTML=json.user+' > '+json.message;
output.appendChild(line);
}
else{ console.log('不正なデータ形式です'); }
});
});
새로운 접속이 있으면 open
이벤트로 서버에 보내고 있습니다. close
는 서버 측에서 자동으로 감지하므로 작성할 필요가 없습니다.
서버가 보낸 데이터는 massage.data
에 있습니다. 데이터에 의해 출력측에 여러가지 내보내고 있습니다.
완제품
디자인은 꽤 적당합니다만..., 이런 느낌으로 채팅을 할 수 있습니다.
후기
어려운 것 같았지만 express-ws조차 사용하면 간단하게 WebSocket을 사용할 수있었습니다.서버와 클라이언트 측의 데이터의 불일치로 JavaScript가 죽거나는 꽤 있었습니다만....
express-ws라면 라우터의 설정도 간단하게 할 수 있었으므로 편리했습니다.
close 이벤트도 자동적으로 감지해 주었으므로 세션 관리 등에도 사용할 수 있을 것 같은 생각이 들었습니다.
Heroku에서 Express 및 express-ws를 사용하여 채팅 앱을 이동하는 샘플 ↩
Reference
이 문제에 관하여(Heroku에서 Express와 WebSocket을 사용하여 간단한 채팅 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/TechnicolorArai/items/592672a68a0c3a75a798
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const expressWs=require('express-ws')(app);
const chat=require('./src/chat');
//*** 略 ***//
app.ws('/chat', chat);
let clients=[];
const chat=(ws, req)=>{
clients.push(ws);
ws.on('message', message=>{
const json=JSON.parse(message);
clients.forEach(a=>{ if( a===ws && a.name==null ) a.name=json.user });
if( json.method!=null ) json.clients=clients.map(a=> a.name);
clients.forEach(a=>{ a.send(JSON.stringify(json)); });
});
ws.on('close', ()=>{
const name=clients.find(a=> a===ws).name;
clients=clients.filter(a=> a!==ws);
clients.forEach(a=>{ a.send(JSON.stringify({ user: name, method: 'close', clients: clients.map(a=>name) })); });
});
}
module.exports=chat;
window.addEventListener('DOMContentLoaded', ()=>{
const name=prompt('名前を入れてください');
document.getElementById('name').value=name;
const ws=new WebSocket(location.origin.replace('https', 'wss')+'/chat');
ws.addEventListener('open', ()=>{ ws.send(JSON.stringify({ user: name, method: 'connect' })); });
const input=document.getElementById('input');
document.getElementById('send').addEventListener('click', ()=>{
const text=input.value;
if( text.length>0 ){
const json={ user: name, message: text };
ws.send(JSON.stringify(json));
}
input.value='';
});
const output=document.getElementById('output');
ws.addEventListener('message', message=>{
const json=JSON.parse(message.data);
const line=document.createElement('div');
if( json.clients!=null ){
document.getElementById('n-client').innerHTML='只今、'+json.clients.length+'人が接続しています';
if( json.method==='connect' ){ line.innerHTML=json.user+'が接続しました'; }
else if( json.method==='close' ){ line.innerHTML=json.user+'が接続を切りました'; }
else console.log(不正なメソッドです, json.method);
output.appendChild(line);
}
else if( json.message!=null ){
line.innerHTML=json.user+' > '+json.message;
output.appendChild(line);
}
else{ console.log('不正なデータ形式です'); }
});
});
Reference
이 문제에 관하여(Heroku에서 Express와 WebSocket을 사용하여 간단한 채팅 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/TechnicolorArai/items/592672a68a0c3a75a798텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)