기본 콘텐츠로 건너뛰기

Express + Socket.IO, 간단한 채팅 만들기

Express + Socket.IO, 간단한 채팅 만들기

안녕하세요 〰️

오늘은 NodeJS + Express + Socket.io 를 사용해서 정말 - 간단한 단체 채팅방을 만들어보겠습니다.

일단 제가 보이는 부분을 많이 신경쓰다 보니,,,

요즘 유행한다는 'neumorphism'을 사용하여 채팅창을 제작해보았습니다.

일단 결과창부터 볼까요?

오늘 만들어볼 채팅창입니다 〰️

일단 소켓이 뭔지 조금 알아볼까요? 아는 분들은 그냥 넘어가시면 됩니다 !

모든 소스는 깃허브에 올려두었으니 참고되셨으면 합니다^~^

Socket 통신 ?

HTTP통신은 클라이언트가 요청을 보내는 경우에만 서버가 응답하는 단방향 통신입니다.

Socket 통신은 Http 통신과 달리 서버와 클라이언트가 연결을 유지하며 실시간 양방향 통신으로 데이터를 주고 받는 방식입니다.

http 통신은 클라이언트가 요청을 보내면 서버가 응답을 하고 연결을 끊어버립니다.

반면, Socket 통신은 연결은 서버와 클라이언트의 지속적인 연결을 이어나갑니다.

보통 특정 시간동안 통신을 하지 않으면 서버와 클라이언트의 연결을 끊습니다. 또, 연결을 지속적으로 하기 때문에 서버에서 요청을 먼저할 수 있다는 특징이 있습니다.

그럼 이러한 Socket 통신은 언제 사용이 될까요?

HTTP 통신은 거의 대부분의 통신에 해당합니다.

예를 들어, 어떤 블로그에 접속하기 위해 링크를 클릭하면 클라이언트는 주소를 옮겨달라는 요청을 하고, 서버는 그 요청을 받아 그에 해당하는 url로 응답을 줍니다. 이 때에는 단순히 데이터를 요청하고 응답하기만을 하는 단순한 요청을 하게 되죠.

Socket 통신은 HTTP 통신에 지속적인 연결성을 더합니다.

예를 들어 메신저를 통한 연락을 할 때, 채팅방에 들어서는 순간부터 "실시간"으로 메세지를 전달해야합니다.

Socket 통신은 이러한 실시간 통신을 할 때 필요하게 됩니다.

CHATTING 만들기

자, 그럼 실제로 구현해볼까요?

IDE는 VSCode를 사용하였습니다.

1. 먼저, Express 프로젝트를 생성해봅시다.

$ express { project_name } // express 프로젝트 생성

명령어를 이용해서 프로젝트 하나를 만들어주세요!

( node, npm, express는 각자 설치해주세요! )

2. socket.io 모듈을 설치해줍니다.

먼저, 터미널에서 프로젝트의 최상위 폴더로 이동해주세요!

$ cd { project_name } // 터미널 명령어를 위해 프로젝트로 파일로 이동

혹은 프로젝트를 우클릭해서 open in Terminal을 하셔도 됩니다.

$ npm install socket.io // 프로젝트에 소켓 설치 $ npm install

을 순서대로 해줍니다.

package.json을 확인해보면 소켓이 잘 설치되어 있는 걸 확인할 수 있습니다.

3. app.js에 socket을 붙여줍니다.

// socket 생성 app.io = require('socket.io')(); // or const Server = require('socket.io'); const io = new Server();

socket.io를 가져와 app.io로 가져옵니다.

소켓을 생성하면서 옵션을 추가할 수도 있는데, socket document에서 더 자세히 확인해보세요❗️

하나씩 더 확인해볼게요!

app.io.on('connection',(socket) => { ... })

위의 코드는 connection 이라는 이벤트가 들어왔을 때, 그 다음 요소로 오는 콜백 함수를 호출합니다.

socket이라는 파라미터는 connection이 성공했을 때 connection에 대한 정보를 담고 있는 변수입니다.

이 socket을 사용해서 서버에서는 event listener를 만들면 됩니다!

socket.on('chat-msg-1', (msg) => { app.io.emit('chat-msg-2', msg); });

socket.on(eventName, callback)

eventName (String)

callback (Function)

Returns Socket

on( ... ) 메소드로 'chat-msg'라는 이벤트명을 설정해주고, 콜백함수를 지정합니다.

콜백함수 내의 emit( ... ) 메소드를 통해 같은 포트를 사용하고 있는 곳으로 msg라는 메세지를 출력합니다.

이벤트는 emit('event')으로 전달하면 on('event')으로 받습니다.

socket.on('disconnect', () => { console.log('socket disconnect !'); });

위의 코드는 socket 연결이 끊겼을 때 (disconnect 라는 이벤트가 들어왔을 때) 실행됩니다.

놀랍게도 소켓 통신을 거의 완성시켰습니다❗️

4. 이번엔 /bin/www 파일로 이동해 소켓과 서버를 연결시켜주겠습니다 〰️

위와 같이 코드를 입력하여 서버를 붙여줍니다!

socket을 사용하기 위한 모든 세팅이 끝났습니다 👏🏻👏🏻👏🏻

5. 실제로 눈에 보여야 확인할 수 있기 때문에 출력을 위한 뷰를 짜봅시다.

html head style(type='text/css'). * { background-color: #f5f5f5; } li { list-style-type : none; padding: 10px; font-weight: 300; } p { color: #296dc2; font-weight: 300; font-size: 30px; padding-top: 10px; text-align: center; } input { height: 50%; width: 60%; border-radius: 8px; margin: 0px 10px 20px 10px; box-shadow: inset 4px 4px 5px #eeeeee, inset -4px -4px 5px #ffffff !important; border: 2px #646a73; font-size: 14px; } button { margin: 0px 10px 20px 10px; border-radius: 15px; box-shadow: 8px 8px 15px #e9e9e9, -8px -8px 15px #ffffff; height: 50%; width: 20%; border: 0px; font-weight: 300; font-size: 16px; } .container { box-shadow: 8px 8px 15px #e9e9e9, -8px -8px 15px #ffffff; height: 80%; margin: 5% 30% 5% 30%; border-radius: 20px; align: center; position: relative; padding: 5px 0px; } .inputContainer { bottom: 0px; border-radius: 20px; position: absolute; height: 15%; width: 100%; text-align: center; } body div.container p 💌 SOCKET CHAT 💌 ul#messages div.inputContainer form input(id="msgInput" placeholder=" typing something !" type="text") button SEND script(src="/socket.io/socket.io.js") script(src="http://code.jquery.com/jquery-1.11.1.js") script. $(() => { const name = prompt('이름을 입력해주세요'); const socket = io(); $('form').submit(() => { let msg = {name: name, messege:$('#msgInput').val()} socket.emit('chat-msg-1', msg); $('#msgInput').val(''); return false; }); socket.on('chat-msg-2', (msg) => { $('#messages').append($('').text(msg.name + ' : ' + msg.messege)); }); });

view/index.jade 로 이동하여 기존의 코드를 모두 지우고 위의 코드를 복/붙해 넣어보세요!

코드를 잠깐 설명해보자면, 일단 위에는 jade템플릿에 맞춘 코드입니다.

script 내에는 jquery를 사용해서 코드가 실행되게끔 만듭니다.

const socket = io();

이 부분이 socket을 연결 해줍니다❗️

그 이후, index.jade 내의 form에서 button을 통해 submit을 하게 되면

// index.jade -> submit의 콜백함수 내부 socket.emit('chat-msg-1', msg);

위 코드를 통해서 app.js에 있는

// app.js socket.on('chat-msg-1', (msg) => { app.io.emit('chat-msg-2', msg); });

라는 코드가 실행됩니다.

그리고 그 내부의 app.io.emit('chat-msg')가 index.jade 내부에 있는

// index.jade socket.on('chat-msg-2', (msg) => { $('#messages').append($('').text(msg.name + ' : ' + msg.messege)); });

을 실행하게 되어서 채팅창의 글자가 써지게끔 만들어주는 거죠.

6. 프로젝트 실행하기

자, 이제 프로젝트를 실행해서 확인해보겠습니다.

( 2번 순서에서 npm install을 하지 않으면 오류가 발생하니 꼭 해주세요 )

$ npm start

이 번엔 localhost:3000 으로 접근해서 잘 동작되는지 눈으로 확인해보겠습니다.

다음의 창에 이름(아이디)를 입력해주세요.

작동이 잘되네요❗️

다들 잘 확인하셨나요❓

굉장히 간단하게 채팅방을 제작해보았어요 ㅎㅎㅎㅎ

소스코드를 자유롭게 변경하면서 사용해보세요 〰️

from http://gngsn.tistory.com/13 by ccl(A) rewrite - 2020-03-11 05:20:05

댓글

이 블로그의 인기 게시물

[Mac OS X] 데스크탑 응용프로그램 개발시작

[Mac OS X] 데스크탑 응용프로그램 개발시작 현재 회사에서 다음 프로젝트로 Mac OS X를 개발해야 하는 일정이 생겨 난생 처음 데스크탑 응용프로그램을 개발하기 공부를 시작했고 여러가지 플랫폼이 있다는것을 발견했다. 어떤 플랫폼을 사용해야할 지 먼저 고민해보자. 무엇으로 개발할것인가? Xcode & Swfit or Objective-C Mac OS X 는 objective-c를 기반으로 만들어졌다. apple에서 제공하는 Xcode와 objective-c 혹은 Swift로 응용 프로그램을 만들 수 있다. Electron Electron 프레임워크를 사용하면 javascript, HTML, CSS를 사용하여 크로스 플랫폼 데스크탑 응용 프로그램을 만들 수 있다. react-native-desktop Qt 프레임 워크를 기반으로하는 크로스 플랫폼이다. react-native 와 javascript로 응용 프로그램을 만들 수 있다. Qt는 컴퓨터 프로그래밍에서 GUI 프로그램 개발에 널리 쓰이는 크로스 플랫폼 프레임워크. 각 플랫폼의 장단점은 무엇인가? Xcode & Swfit or Objective-C - 장점 모든 OSX API에 직접 접근할 수 있다. Xcode를 통해 App Store에 쉽게 배포할 수 있다. - 단점 Windows 전용 응용 프로그램을 다시 개발해야한다. Swift언어를 모른다면 새로 공부해야 한다. Electron - 장점 웹스택을 가지고 빠르게 만들 수 있다. 다양한 플랫폼을 지원한다. - 단점 Native언어로 개발할때 보다 성능이 떨어질 이슈가있다. OS X API를 사용하는데 복잡하다. *API에 대한 JavaScript 래퍼가 없으면 자체 래퍼를 작성하지 않는 한 프로젝트에서 사용할 수 없습니다. React-native-desktop - 장점 현재 개발스택과 완전히 동일하므로 더 빠르게 개발 할 수 있다. 다양한 플랫폼을 지원한다. - 단점 N...

AWS CI/CD 파이프라인에 Slack 알람 적용(Lambda, CloudWatch Events 연동)

AWS CI/CD 파이프라인에 Slack 알람 적용(Lambda, CloudWatch Events 연동) 이번 글에서는 구축된 CI/CD 파이프라인과 Slack 알람을 연동하는 방법에 대해서 알아볼 것이다. CI/CD 파이프라인 시작/종료(성공/실패) 시 Amazon CloudWatch Events에서 해당 이벤트를 감지한 후 AWS Lambda로 트리거 신호를 보내면 AWS Lambda에서 Slack채널로 알람을 보내는 프로세스다. 글의 순서는 다음과 같다. Amazon CloudWatch Events, AWS Lambda란? 실습 전 준비사항 Slack Webhook 생성 AWS Lambda 함수 생성 AWS CloudWatch Events 생성 테스트 위와 같은 방식으로 구축을 하면 최종 프로세스는 다음 그림과 같다 (우리가 이 글에서 진행하는 내용은 빨간색으로 표시된 부분) 1. Amazon CloudWatch Events, AWS Lambda란? 1-1. Amazon CloudWatch Events란? Amazon CloudWatch Event(혹은 AWS CloudWatch Events)는 AWS 상태 변경 등을 감시할 수 있는 기능이다. 만약 사용자가 만든 규칙에 맞는 이벤트가 발생하게 되면 해당 이벤트가 사정에 정의된 규칙과 일치할 경우 하나 이상의 대상 작업을 호출한다. 이벤트 유형에 따라 알람을 보내거나, 이벤트 정보를 캡쳐하거나, 교정작업을 수행하거나, 이벤트를 시작하거나, 기타 작업을 수행할 수 있다. 이벤트가 발생할 경우 대상 작업은 AWS Lambda함수, AWS Kinesis 스트림, AWS SQS, Amazon SNS 등이 있다. 사용되는 사례로는 1) 이벤트가 발생하면 Lambda함수를 사용하여 Slack채널로 알림을 전달하거나, 2) AWS 상태 이벤트가 발생하면 Lambda 및 CloudWatch Events를 사용하여 Amazon SNS로 사용자 지정 텍스트 또는 SMS 알림을 보내는 등...

[2020-angstromCTF] web - A peculiar query write-up

[2020-angstromCTF] web - A peculiar query write-up English write-up UI seems like below. If you click the 'the source' link, you can get back-end source code. const express = require("express"); const rateLimit = require("express-rate-limit"); const app = express(); const { Pool, Client } = require("pg"); const port = process.env.PORT || 9090; const path = require("path"); const client = new Client({ user: process.env.DBUSER, host: process.env.DBHOST, database: process.env.DBNAME, password: process.env.DBPASS, port: process.env.DBPORT }); async function query(q) { const ret = await client.query(`SELECT name FROM Criminals WHERE name ILIKE '${q}%';`); return ret; } app.set("view engine", "ejs"); app.use(express.static("public")); app.get("/src", (req, res) => { res.sendFile(path.join(__dirname, "index.js")); }); app.get("/", async (req, res) => { if (req.query...