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.js
const expressWs=require('express-ws')(app);
const chat=require('./src/chat');

//*** 略 ***//

app.ws('/chat', chat);

구현은 src/chat.js 와 별 파일로 해 두는 데이터의 교환은 JSON 형식을 사용한다. client에는 name 속성이 없으므로 여기에 연결 사용자 이름을 붙입니다.

src/chat.js
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;

클라이언트측 구현



js/chat.js
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('不正なデータ形式です'); }
    });
});

새로운 접속이 있으면 open 이벤트로 서버에 보내고 있습니다. close는 서버 측에서 자동으로 감지하므로 작성할 필요가 없습니다.
서버가 보낸 데이터는 massage.data에 있습니다. 데이터에 의해 출력측에 여러가지 내보내고 있습니다.

완제품





디자인은 꽤 적당합니다만..., 이런 느낌으로 채팅을 할 수 있습니다.

후기



어려운 것 같았지만 express-ws조차 사용하면 간단하게 WebSocket을 사용할 수있었습니다.서버와 클라이언트 측의 데이터의 불일치로 JavaScript가 죽거나는 꽤 있었습니다만....
express-ws라면 라우터의 설정도 간단하게 할 수 있었으므로 편리했습니다.
close 이벤트도 자동적으로 감지해 주었으므로 세션 관리 등에도 사용할 수 있을 것 같은 생각이 들었습니다.



Heroku에서 Express 및 express-ws를 사용하여 채팅 앱을 이동하는 샘플 

좋은 웹페이지 즐겨찾기