Socket.io Part 2

JB·2022년 5월 24일
0

teamproject

목록 보기
2/2

📂 File Structure


🚀 Source Code

main.js

const chatForm = document.getElementById("chat-form");
const chatMessages = document.querySelector(".chat-messages");
const rommName = document.getElementById("room-name");
const userList = document.getElementById("users");

const { username, room } = Qs.parse(location.search, {
  ignoreQueryPrefix: true,
});

const socket = io();

// Join Chatroom
socket.emit("joinRoom", { username, room });

// Get room and users
socket.on("roomUsers", ({ room, users }) => {
  outputRoomName(room);
  outputUsers(users);
});

// Message from server
socket.on("message", (message) => {
  // emit 으로 보낸 메시지를 on으로 받는거임
  console.log(message); // Welcome to LangB Chat Room
  outputMessage(message);
});

// Message submit
chatForm.addEventListener("submit", (e) => {
  // e stands for event
  e.preventDefault(); // literally prevent default behavior

  // Get message text
  const msg = e.target.elements.msg.value; // userinput text

  //   console.log(msg); // get the message from the text input

  // Emit message to server
  socket.emit("chatMessage", msg);

  // Scroll Down
  chatMessages.scrollTop = chatMessages.scrollHeight;

  // Clear input
  e.target.elements.msg.value = "";
  e.target.elements.msg.focus(); // after sending, the cursor is on input div
});

// Output message to DOM
function outputMessage(message) {
  const div = document.createElement("div");
  div.classList.add("message");
  div.innerHTML = `<p class="meta">${message.username} <span>${message.time}</span></p>
  <p class="text">
    ${message.text} 
  </p>`;
  // here, the {message} is in object type
  document.querySelector(".chat-messages").appendChild(div); // whenever a new message is created, a new message div is created
}

// Add room name to DOM
function outputRoomName(room) {
  rommName.innerText = room;
}

// Add users to DOM
function outputUsers(users) {
  userList.innerHTML = `
    ${users.map((user) => `<li>${user.username}</li>`).join("")}
  `;
}

server.js

const path = require("path");
const http = require("http");
const express = require("express");
const socketio = require("socket.io");
const formatMessage = require("./utils/messages");
const {
  userJoin,
  getCurrentUser,
  userLeave,
  getRoomUsers,
} = require("./utils/users");

const app = express();
const server = http.createServer(app);
const io = socketio(server);

// Set static folder
app.use(express.static(path.join(__dirname, "public")));

const Admin = "Admin";

/// Run when client sonnects
io.on("connection", (socket) => {
  // console.log("New WS Connection..."); // whenever client connects, this pops up

  socket.on("joinRoom", ({ username, room }) => {
    const user = userJoin(socket.id, username, room);
    socket.join(user.room);

    // Welcome current user
    socket.emit("message", formatMessage(Admin, "Welcome to Chat Room!")); // only shown to the single client that is curently connecting
    // io.emit() // to the all client in general

    // Broadcast when a user connects
    // broadcast.emit is different from socket.emit=> emit to everybody except the user
    // no need to notify the user that they are connecting while connecting
    socket.broadcast
      .to(user.room)
      .emit(
        "message",
        formatMessage(Admin, `${user.username} has joined the chat`)
      ); // to all the client exepct the user

    // Send users and room info
    io.to(user.room).emit("roomUsers", {
      room: user.room,
      users: getRoomUsers(user.room),
    });
  });

  // we sent the message to the server, so we should now catch the message
  // Listen for chatMessage
  socket.on("chatMessage", (msg) => {
    // console.log(msg); // now emit this back to the client
    const user = getCurrentUser(socket.id);

    io.to(user.room).emit("message", formatMessage(user.username, msg));
  });

  // Runs when client disconnects
  socket.on("disconnect", () => {
    const user = userLeave(socket.id);

    console.log("🌸", user); // result => { id: 'mJpCOYQyQ9UAtQOrAAAF', username: 'John', room: 'JavaScript' }

    if (user) {
      io.to(user.room).emit(
        "message",
        formatMessage(Admin, `${user.username} has left the chat`)
      );

      // After leaving the chat, update the user list in main.js
      // Send users and room info
      io.to(user.room).emit("roomUsers", {
        room: user.room,
        users: getRoomUsers(user.room),
      });
    }
  });
});

const PORT = 3000 || process.env.PORT;

server.listen(PORT, () => console.log(`🚀 SERVER RUNNING ON ${PORT}`));

users.js

const users = [];

// Join user to chat
function userJoin(id, username, room) {
  const user = { id, username, room };

  users.push(user);

  return user;
}

// Get the curernt user
function getCurrentUser(id) {
  return users.find((user) => user.id === id);
}

// User leaves chat
function userLeave(id) {
  const index = users.findIndex((user) => user.id === id);

  if (index !== -1) {
    return users.splice(index, 1)[0];
  }
}

// Get room users
function getRoomUsers(room) {
  return users.filter((user) => user.room === room);
}

module.exports = {
  userJoin,
  getCurrentUser,
  userLeave,
  getRoomUsers,
};

messages.js

const moment = require("moment");

function formatMessage(username, text) {
  return {
    username,
    text,
    time: moment().format("h:mm a"), // moment.js library used. hour : minute AM / PM
  };
}

module.exports = formatMessage;

📓 Libraries

qs cdn Library


https://www.youtube.com/watch?v=jD7FnbI76Hg

profile
두비두밥밥

0개의 댓글