Next.js - 채팅 어플리케이션 구현 1편

김종민·2023년 4월 4일
0

Next.js로 사이드프로젝트 진행 중, socket.io를 활용한 채팅방 기능을 구현하고 있습니다.

Server

express를 활용한 서버는 아래와 같이 구성합니다.

import express, { Express } from "express";
import { createServer } from "http";
import { Server, Socket } from "socket.io";

const app: Express = express();
const httpServer = createServer(app);

const PORT: number = 8080;

const io = new Server(httpServer, {
  path: "/socket/chat",
  cors: {
    origin: "*",
    credentials: true,
  },
});

io.on("connection", (socket: Socket) => {
  console.log(`유저입장 :${new Date()} 유저아이디:${socket.id}`);

  socket.on("sendMessage", ({ userName, message }: { userName: string; message: string }) => {
    io.emit("message", { userName, message });
  });

  socket.on("disconnect", () => {
    console.log(`유저나감 : ${new Date()}  유저아이디:${socket.id}`);
  });
});

httpServer.listen(PORT, () => {
  console.log(`[server]: Server is running at http://localhost:${PORT}`);
});
  1. io변수의 path는 클라이언트측과 socekt을 연동시켜주는 주소라고 생각하면 됩니다.
  2. io.on 및 io.emit을 통해, 클라이언트측과의 이벤트를 구성해줍니다.
  3. io.on은 이벤트수신 , io.emit은 이벤트전송이라 생각하면 됩니다.

Client

클라이언트는 Next.js로 구성했습니다.
(CSS 미적용)

import { useEffect, useState } from "react";
import { io, Socket } from "socket.io-client";

interface ChatMessage {
  userName: string;
  message: string;
}

let socket: Socket;

export default function Home() {
  const [userName, setUserName] = useState<string>("");
  const [message, setMessage] = useState<string>("");
  const [chatMessage, setChatMessage] = useState<ChatMessage[]>([]);

  useEffect((): any => {
    socket = io("http://localhost:8080", { path: "/socket/chat" });

    socket.on("connect", () => {
      console.log("소켓연결 성공!!!", socket.id);
    });

    socket.on("message", (receiveMessage: ChatMessage) => {
      console.log("메세지 수신");
      setChatMessage((prev) => [...prev, receiveMessage]);
    });

    if (socket) return () => socket.disconnect();
  }, []);

  const onMessageSubmit = () => {
    socket.emit("sendMessage", { userName, message });
    setMessage("")
  };

  const enterKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key === "Enter" && !event.shiftKey) {
      event.preventDefault();
      onMessageSubmit();
    }
  };

  return (
    <div>
      <div>
        {chatMessage.map((item, index) => {
          return <div key={index}>{`${item.userName} : ${item.message}`}</div>;
        })}
      </div>
      <form>
        <input type="text" placeholder="닉네임을 입력해주세요" onChange={(e) => setUserName(e.currentTarget.value)} />
        <input type="text" placeholder="메세지를 입력해주세요" onChange={(e) => setMessage(e.currentTarget.value)} onKeyDown={enterKeyDown} />
        <button type="button" onClick={onMessageSubmit}>
          메세지 전송
        </button>
      </form>
    </div>
  );
}
  1. useEffect를 통해 렌더링 후 서버측과 socket을 연결시켜줍니다.
  2. 위의 코드에서 onMessageSubmit함수를 호출하면 작성한 메세지를 서버로 전송합니다.
  3. 이후 서버측이 전송한 메세지를 다시 chatMessage에 추가하여 채팅을 보여줍니다.

간단하게 기능확인을 위해 적용한 코드이므로
CSS적용 및 컴포넌트분리등을 추가한 내용으로 2편을 작성하겠습니다.

전체소스코드는 아래의 저장소에서 확인 가능합니다.
깃허브 저장소 이동

profile
개발을 합시다 :)

0개의 댓글