채팅 서비스에서는 접속한 사용자를 닉네임을 통해 구분할 수 있어야겠죠. 이번에는 웹소켓을 사용하여 닉네임을 설정하는 방법에 대해 알아보겠습니다.
먼저, 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 |