채팅 서비스에서는 접속한 사용자를 닉네임을 통해 구분할 수 있어야겠죠. 이번에는 웹소켓을 사용하여 닉네임을 설정하는 방법에 대해 알아보겠습니다.
먼저, home.pug에서 닉네임을 입력받을 필드를 추가해주겠습니다.
// home.pug
doctype html
html(lang="en")
head
meta(charset="UTF-8")
meta(http-equiv="X-UA-Compatible", content="IE=edge")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
link(rel="stylesheet", href="https://unpkg.com/mvp.css")
title Zoom
body
header
h1 Chat Service
main
form#nickname
input(type="text", placeholder="Please set your nickname", required)
button Save
ul
form#message
input(type="text", placeholder="Please write a message", required)
button Send
script(src="/public/js/app.js")

다음으로 프론트에서 전송하는 메시지와 닉네임 메시지를 구분해주겠습니다. 닉네임 설정 핸들러 handleNicknameSubmit을 만들어주고, socket["nickname"] 방식으로 기존의 소켓 데이터에 닉네임을 담아 전송해줄 수 있습니다.
이 때, 해당 객체를 JSON 형태로 바꿔서 전송해줘야 하는데요. JSONMessage 라는 함수를 만들어 메시지를 JSON 형식으로 치환해 보내줍니다. 이 때 메시지 유형 type과 페이로드 payload를 설정해줍니다.
메시지는 "newMessage"를 통해 전송하고, 닉네임은 "nickName"으로 전송할 것입니다.
// app.js
const messageList = document.querySelector("ul");
const nicknameForm = document.querySelector("#nickname");
const messageForm = document.querySelector("#message");
const socket = new WebSocket(`ws://${window.location.host}`);
// 메시지를 JSON 데이터로 바꿔주기
function JSONMessage(type, payload) {
const message = { type, payload };
return JSON.stringify(message);
}
socket.addEventListener("open", () => {
console.log("Connected to Server.");
});
socket.addEventListener("message", (message) => {
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
socket.addEventListener("close", () => {
console.log("Disconnted from the server.");
});
// 메시지 전송 핸들러
function handleSubmit(event) {
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(JSONMessage("newMessage", input.value));
input.value = "";
}
//닉네임 설정 핸들러
function handleNicknameSubmit(event) {
event.preventDefault();
const nickname = nicknameForm.querySelector("input");
socket["nickname"] = nickname.value; // 닉네임 값을 socket에 넣어 줌
socket.send(JSONMessage("nickName", socket["nickname"]));
nickname.value = "";
}
messageForm.addEventListener("submit", handleSubmit);
nicknameForm.addEventListener("submit", handleNicknameSubmit);
다음으로 서버에서 프론트에서 전송한 닉네임과 메시지를 처리해줄 차례입니다. 먼저, 프론트에서 들어오는 메시지를 socket.on("message")를 통해 받고, 해당 메시지를 다시 파싱합니다.
다음으로 메시지 유형이 newMessage 채팅인지 nickName인지 구분하여 닉네임을 설정하고, 설정한 닉네임과 함께 메시지를 다시 전달해줍니다.
// server.js
import http from "http";
import WebSocket from "ws";
import express from "express";
const app = express();
app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));
const server = http.createServer(app); // http 요청을 처리
const webSocketServer = new WebSocket.Server({ server });
const sockets = [];
webSocketServer.on("connection", (socket) => {
sockets.push(socket);
socket["nickName"] = "Anonymous"; // 연결 시 닉네임 미설정이라면 기본값 부여
socket.on("open", () => console.log("Connected to the Browser"));
socket.on("message", (message) => {
message = JSON.parse(message);
// 메시지 유형을 구분해주기
switch (message.type) {
case "newMessage":
sockets.forEach((eachSocket) =>
eachSocket.send(`${socket.nickName}: ${message.payload.toString()}`)
);
break;
case "nickName": // 닉네임 설정하기
socket["nickName"] = message.payload;
console.log(message.payload);
break;
}
});
socket.on("close", () => console.log("Disconnectd from the Browser"));
});
server.listen(8000);
닉네임을 저장하고 메시지를 보냈을 때 다음과 같이 닉네임과 메시지가 함께 표시되면 성공입니다!

'개발 > Projects' 카테고리의 다른 글
| [WebSocket/Socket IO] 채팅 서비스 구현 4. Socket IO 설치 및 연결하기 (0) | 2022.12.06 |
|---|---|
| [WebSocket/Socket IO] 채팅 서비스 구현 2. 메시지 수신하기 (0) | 2022.12.05 |
| [WebSocket/Socket IO] 채팅 서비스 구현 1. 프로젝트 설정 (0) | 2022.12.02 |
