Doit! - 채팅서버 만들기

노드에서 채팅 기능을 만들려면 **웹 소켓(Web Socket)**을 사용해야한다. 웹 소켓은 웹 서버로 소켓을 연결한 후 데이터를 주고받을 수 있도록 만든 HTML5표준이다. 이러한 웹 소켓은 HTTP 프로토콜로 소켓 연결을 하기 때문에 웹 브라우저가 이 기능을 지원하지 않으면 사용할 수 없다. socket.io모듈을 사용하면 웹 소켓을 지원하지 않는 웹 브라우저에서도 웹 소켓을 사용할 수 있다.

10-1 socket.io 사용하기

$ npm install socket.io --save

socket.io를 사용하려면 cors모듈도 설치되어 있어야한다. CORS(Corss-Origin Resource Sharing)를 사용하면 Ajax를 사용해 데이터를 가져올 때 현재 보고 있는 브라우저의 웹 문서를 제공한 웹 서버 이외에 다른 웹 서버에서는 접속할 수 없는 제약이 풀린다.

$ npm install cors --save

프로젝트 구성

파일 or 폴더
설명

app.js

기본 코드가 들어 있는 메인 파일

/config/config.js

설정 정보가 들어 있는 파일 스키마 모듈이나 라우팅 모듈을 만들어 추가했다면 이 파일에 설정 정보를 추가

/database

데이터베이스의 스키마 모듈 파일들을 만들어 넣는 폴더

/routes

라우팅 함수들을 모듈 파일로 만들어 넣는 폴더

/views

뷰 템플릿 파일들을 만들어 넣는 폴더

//app.js
...

// socket.io 모듈 불러들이기
var socketio = require('socket.io');

// cors 사용 - 클라이언트에서 ajax로 요청하면 CORS 지원
var cors = require('cors');

...

//cors를 미들웨어로 사용하도록 등록
app.use(cors());

...

// socket.io 서버를 시작
var io = socketio.listen(server);
console.log("socket.io 요청을 받아들일 준비가 되었습니다.");

http모듈로 실행한 익스프레스 서버는 server변수에 저장되어 있으므로 그 아랫부분에서 socket.io모듈 객체의 listen()메소드를 호출한다.

socket.io모듈로 웹 소켓 요청 처리 메소드

메소드 이름
설명

attach(httpServer,options)

웹 서버 인스턴스가 socket.io를 처리한다.

listen(httpServer,options)

웹 서버 인스턴스가 socket.io를 처리한다.

socket.io 서버를 웹 서버 위에서 동작하도록 설정하면 웹 소켓과 관련된 요청은 모두 socket.io에서 처리한다. socket.io객체는 io변수에 할당되었는데 이 객체에 들어 있는 sockets객체는 클라이언트가 접속하거나 데이터를 전송했을 때 이벤트를 발생시킨다.

on() 메소드로 connection 이벤트를 처리하는 콜백함수를 등록하면 콜백 함수 쪽으로 소켓 객체가 전달된다.

socket.io는 메시지를 주고받을 때 이벤트 처리 방식을 사용한다.

송수신 이벤트 처리 메소드

메소드
설명

on(event,callback)

이벤트 수신 형태로 메시지를 수신했을 때 처리할 콜백 함수를 등록한다. 콜백 함수의 파라미터로 수신한 객체가 전달된다.

emit(event,object)

이벤트 송신 형태로 메시지를 송신한다.

이벤트의 이름은 마음대로 정할 수 있다. 즉, 사용자 정의 이벤트와 같다. Echo기능은 서버에 보낸 데이터를 그대로 다시 돌려받는 기능이다.

  • sender : 보내는 사람의 아이디

  • recepient : 받는 사람의 아이디

  • command : 데이터의 종류

  • type : 전송될 데이터의 형태

  • data : 데이터

메세지 전송방법

메소드
설명

io.sockets.emit(event,object)

나를 포함한 모든 클라이언트에 전송

socket.broadcast.emit(event,object)

나를 제외한 모든 클라이언트에 전송

10-2 일대일 채팅하기

일대일 채팅은 상대방을 지정하여 메시지를 보내야 하므로 서버에 연결된 각 클라이언트마다 고유한 정보가 있어야한다. 클라이언트가 로그인할 때 사용하는 로그인 아이디를 사용해 클라이언트를 구별할 수 있도록 하는 것이 좋다.

대상 소켓을 찾기위해서는 io.sockets.connected[login_ids[messagae.recepient]]를 사용해야한다.

배열의 요소는 delete키워드나 배열의 splice()메소드등을 이용해 여러가지 방법을 사용할 수 있다.

10-3 그룹 채팅하기

그룹 채팅은 방을 만들고 그 방에 초대된 사람끼리 동시에 메시지를 주고받는다.

방만들기

socket.io모듈은 몇 명의 사용자를 하나으 ㅣ방에 모아 두고 방에 들어온 특정 클라이언트에만 메시지를 전송할 수 있는 기능을 제공한다.

클라이언트에서는 만든 방의 리스트만 전달받는다.

방에 입장 / 퇴장 메소드

메소드
설명

join(roomName)

방에 입장한다. 방이 없으면 방을 새로 만든다.

leave(roomName)

방에서 나온다.

socket.io 모듈에서 방정보를 관리하고 있다. 방 객체에 속성을 추가하는 것도 가능하다. 방 정보는 io.sockets.adapter.rooms에 들어있다. getRoomList()는 처음부터 만들어져 있던 방이다.

그룹 채팅에서 메시지 보내기

일대일 채팅에서는 io.sockets.connected객체에 들어 있는 소켓 객체들 중에서 대상이 되는 소켓 객체를 소켓 ID로 찾은 후 emit()메소드를 호출하여 메시지를 전송했다. 이와 다르게 그룹 채팅에서는 io.sockets.in()메소드를 사용해 대상이 되는 방에 들어 있는 소켓 객체들을 찾은 후 메시지를 전송한다.

10-4 채팅 웹 문서 예쁘게 꾸미기

채팅 메시지 표시를 위해 만든 CSS는 https://css-tricks.com/replicating-google-hangouts-chat/참조

Last updated

Was this helpful?