Приложение для чата в реальном времени с Vue 3 Socket.io и Nodejs следует из предыдущей статьи, которую я написал о том, как создать приложение для чата в реальном времени с Vuejs, Socket.io и Nodejs, чтобы продемонстрировать все, что вам нужно для настройки и создания. ваше приложение чата с Vuejs.

Мы собираемся получить больше информации оттуда, чтобы разработать более надежное, безопасное и продвинутое приложение для чата в реальном времени с Vue 3 Socket.io и Nodejs.

Vue 3 - это самая последняя версия Vue.js, которая использует новый API композиции. Мы собираемся узнать, как его настроить и создать наше первое приложение реального времени с Vue 3.

Кроме того, мы собираемся изучить более сложные и реальные концепции приложения чата, включая такие функции, как аутентификация и авторизация, настройка и сохранение сообщений в базе данных для дальнейшего анализа.

В этой статье мы собираемся подробно изучить, как создать приложение для чата в реальном времени с Vue 3 Socket.io и Nodejs, мы также узнаем, как добавить аутентификацию и авторизацию в наше приложение для чата.

Кроме того, мы рассмотрим процесс хранения и извлечения новых и старых сообщений чата из базы данных в нашем приложении чата в режиме реального времени.

Если это то, чего вы хотите достичь, приступим:

Перед погружением, если вы backend-разработчик или хотите углубиться в этот карьерный путь, присоединитесь к другим разработчикам, чтобы получать ежедневные статьи о backend-разработке, которые повысят вашу продуктивность.

Вот видео о том, что мы будем строить.

Создайте приложение для чата в реальном времени

Настраивать

Прежде чем мы начнем, мы должны убедиться, что у нас установлены все необходимые инструменты.

Для этого руководства требуются Node.js и NPM, и его можно легко установить с официального сайта.

Вам также нужно будет немного знать JavaScript и Vuejs, вы можете изучить VueJS, пройдя этот курс, и JavaScript с этим курсом.

Если все настроено правильно, приступим:

Сначала создайте каталог для приложения и откройте каталог с помощью вашего любимого текстового редактора.

mkdir advanced-chat-app && cd advanced-chat-app && code .

Затем мы инициализируем каталог с помощью NPM и установим необходимые пакеты, необходимые для создания нашего приложения чата в реальном времени.

Выполните следующую команду, чтобы инициализировать проект, откройте терминал в корневом каталоге проекта и запустите:

Это инициализирует проект с настройкой NPM по умолчанию и создаст файл package.json, чтобы мы могли начать установку наших пакетов.

Установки зависимостей

Затем мы начнем устанавливать наши зависимости и настраивать их, вы можете узнать больше о каждой из зависимостей по предоставленной ссылке.

Сначала мы установим Express.js и Socket.io, используя следующую команду:

npm install express socket.io --save

Наконец, мы установим другие необходимые зависимости (MySQL), используя следующую команду.

npm install mysql2 --save

Настройка базы данных

Сохранение сообщений нашего чата в реальном времени - это дополнительная функция к нашей предыдущей версии этой статьи.

Давайте посмотрим, как мы можем настроить нашу базу данных и начать хранить и получать сообщения из нашей базы данных.

Сначала создайте database.js файл:

touch database.js

и вставьте следующие коды:

const mysql = require("mysql2");
let db = null;
class DB {
 constructor() {
  db = mysql.createConnection({
   host: "localhost",
   user: "root",
   password: "DB_PASSWORD",
   database: "advanced-chat-app",
 });
 db.connect(function (err) {
   if (err) console.log(err);
 });
}
addUser(data) {
 return new Promise(async (resolve, reject) => {
  if (await this.isUserExist(data)) {
   resolve("User already exist");
  } else
  db.execute(
   "INSERT INTO users (name, user_id) VALUES (?,?)",
   [data.name, data.user_id],
   function (err, rows) {
     if (err) reject(new Error(err));
     else resolve(rows);
    }
  );
 });
}
isUserExist(data) {
  return new Promise((resolve, reject) => {
  db.execute(
  "SELECT * FROM users WHERE name = ?",
  [data.name],
  function (err, rows) {
   if (err) reject(new Error(err)); 
   else resolve(rows[0]);
  }
 );
});
}
fetchUserMessages(data) {
 const messages = [];
 return new Promise((resolve, reject) => {
  db.query(
  "SELECT * from messages where name =?",
  [data.name],
  function (err, rows) {
    if (err) reject(err);
    else resolve(rows);
  }
 );
});
}
storeUserMessage(data) {
 return new Promise((resolve, reject) => {
 db.query(
 "INSERT INTO messages (message, user_id, name) VALUES (?,?,?)",
 [data.message, data.user_id, data.name],
 function (err, rows) {
 if (err) reject(new Error(err));
  else resolve(rows); 
 }
 );
});
}
}
module.exports = DB;

Настройка сервера

Теперь у нас есть конфигурация нашей базы данных, мы настроим наш сервер Node.js с помощью express и импортируем наш модуль базы данных для использования в событиях.

Давайте посмотрим, как этого добиться:

Сначала создайте файл server.js в каталоге:

touch server.js

и вставьте следующие коды.

const app = require("express")();
const http = require("http").Server(app);
const io = require("socket.io")(http);
const path = require("path");
const DataBase = require("./database.js");
const db = new DataBase();
app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html");
});
io.on("connection", function (socket) {
  console.log(io.sockets.connected);
  console.log("A user with ID: " + socket.id + " connected");
socket.on("disconnect", function () {
    console.log("A user with ID: " + socket.id + " disconnected");
  });
// More Socket listening here.
  // if (io.sockets.connected) console.log(io.sockets.connected);
  // socket.emit("connections", Object.keys(io.sockets.connected).length);
socket.on("chat-message", async (message) => {
    const data = {
      message: message.message,
      user_id: socket.id,
      name: message.user,
    };
    console.log(data);
    const messageData = await db.storeUserMessage(data);
    socket.broadcast.emit("chat-message", message);
  });
socket.on("typing", (data) => {
    socket.broadcast.emit("typing", data);
  });
socket.on("stopTyping", () => {
    socket.broadcast.emit("stopTyping");
  });
socket.on("joined", async (name) => {
    let messageData = null;
    const data = {
      name,
      user_id: socket.id,
    };
    const user = await db.addUser(data);
    if (user === "User already exist") {
      messageData = await db.fetchUserMessages(data);
    }
    // console.log(messageData);
    socket.broadcast.emit("joined", messageData);
  });
socket.on("leave", (data) => {
    socket.broadcast.emit("leave", data);
  });
});
http.listen(3000, () => {
  console.log("Listening on port *: 3000");
});

Пока что мы создали наш сервер, используя HTTP-сервер express ', а также инициализировали наш Socket.io, используя созданный нами экземпляр сервера.

Мы также настроили конечную точку нашей домашней страницы / для отображения дизайна внешнего интерфейса чата, чтобы мы могли взаимодействовать с ним.

Затем мы создали наше соединение Socket.io и начали прослушивать входящие запросы / события, например. событие disconnect.

Мы также выполняли различные вызовы наших баз данных, когда это необходимо для отображения или сохранения сообщений в базе данных.

Наконец, мы создали сервер и прослушиваем входящие запросы через порт 3000 на localhost.

В моей предыдущей статье я наглядно объяснил, как работает socket.io, и значение каждого метода и событий, которые мы будем использовать в этом руководстве, вы должны прочитать его сейчас, если вы еще этого не сделали.

Теперь, когда у нас есть серверная часть, давайте поработаем над частью внешнего интерфейса Vue 3:

Сделайте перерыв и подпишитесь, чтобы получать ежедневную информацию, которая повысит вашу продуктивность как Backend Developer Nodejs.

Настройка Vue 3 Frontend

Затем мы настроим интерфейсную часть нашего приложения для чата в реальном времени, используя Vue 3 и Bootstrap.

Начать работу с Vue3 очень просто, добавив CDN в наш HTML-файл только для разработки:

touch index.html

Откройте файл index.html и добавьте следующие коды:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ChatApp_Socket</title>
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"
      integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
</head>
<body>
  <div id="app">

  </div>
</body>
</html>

Приведенный выше код просто включает Bootstrap и Socket.io Client в интерфейс.

Вы также можете скачать здесь клиентскую библиотеку Socket.IO.

Затем мы добавим следующие HTML-коды в <div id="app">, который мы создали выше:

<div class="container">
        <div class="col-lg-6 offset-lg-3">
          <div v-if="ready">
            <p v-for="(user, i) in info" :key="i">
              {{ user.username }} {{ user.type }}
            </p>
          </div>
    
          <div v-if="!ready">
            <h4>Enter your username</h4>
            <form @submit.prevent="addUser">
              <div class="form-group row">
                <input
                  type="text"
                  class="form-control col-9"
                  v-model="username"
                  placeholder="Enter username here"
                />
                <input
                  type="submit"
                  value="Join"
                  class="btn btn-sm btn-info ml-1"
                />
              </div>
            </form>
          </div>
          <h2 v-else>{{ username }}</h2>
          <div class="card bg-info" v-if="ready">
            <div class="card-header text-white">
              <h4>
                My Chat App
                <span class="float-right">{{ connections }} connections</span>
              </h4>
            </div>
            <ul class="list-group list-group-flush text-right">
              <small v-if="typing" class="text-white">{{ typing }} is typing</small>
              <li class="list-group-item" v-for="(message, i) in messages" :key="i">
                <span :class="{ 'float-left': message.type === 1 }">
                  {{ message.message }}
                  <small>:{{ message.user }}</small>
                </span>
              </li>
            </ul>
    
            <div class="card-body">
              <form @submit.prevent="send">
                <div class="form-group">
                  <input
                    type="text"
                    class="form-control"
                    v-model="newMessage"
                    placeholder="Enter message here"
                  />
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>

Socket.io События

Затем мы создадим различные события, чтобы сформировать основу для связи с сервером. Код будет размещен под комментарием в приведенном выше скрипте.

<script src="/socket.io/socket.io.js"></script>
<script src="https://unpkg.com/vue@next"></script>
<script>
    const socket = io();
   const Chat =  {
      name: "Chat",
    
      data() {
        return {
          newMessage: null,
          messages: [],
          typing: false,
          username: null,
          ready: false,
          info: [],
          connections: 0,
        };
      },
      created() {
        window.onbeforeunload = () => {
          socket.emit("leave", this.username);
        };
    
        socket.on("chat-message", (data) => {
          this.messages.push({
            message: data.message,
            type: 1,
            user: data.user,
          });
        });
    
        socket.on("typing", (data) => {
          this.typing = data;
        });
    
        socket.on("stopTyping", () => {
          this.typing = false;
        });
    
        socket.on("joined", (data) => {
          this.info.push({
            username: data,
            type: "joined",
          });
    
          setTimeout(() => {
            this.info = [];
          }, 5000);
        });
// data.forEach(element => {
        //     this.messages.push({
        //       message: element.message,
        //       type: 1,
        //       user: element.name,
        //     });
        //     this.info.push({
        //       username: element.name,
        //       type: "joined",
        //     });
        //   });
    
        socket.on("leave", (data) => {
          this.info.push({
            username: data,
            type: "left",
          });
    
          setTimeout(() => {
            this.info = [];
          }, 5000);
        });
    
        socket.on("connections", (data) => {
          this.connections = data;
        });
      },
    
      methods: {
        send() {
          this.messages.push({
            message: this.newMessage,
            type: 0,
            user: "Me",
          });
    
          socket.emit("chat-message", {
            message: this.newMessage,
            user: this.username,
          });
          this.newMessage = null;
        },
    
        addUser() {
          this.ready = true;
          socket.emit("joined", this.username);
        },
      },
    
      watch: {
        newMessage(value) {
          value ? socket.emit("typing", this.username) : socket.emit("stopTyping");
        },
      },
    };
Vue.createApp(Chat).mount('#app');
  </script>

В приведенном выше сценарии используется метод on Socket.io для прослушивания различных событий с сервера, а также для ожидания ответов от сервера.

Кроме того, метод emit в Socket.io используется для отправки или отправки событий на сервер, как метод POST в Restful API.

В том же духе мы слушали различные события, такие как набор текста, joined, stopTyping и т. Д. И ответ соответственно на разные события.

В приведенном выше сценарии много всего происходит, что было объяснено в моей предыдущей статье, вы обязательно должны проверить это, прежде чем читать эту.

Но здесь мы дадим вам небольшой контекст того, что происходит:

В методах Vue мы создали два метода send() и addUser(), которые в основном отправляют сообщения пользователю, используя метод emit Socket.io, а addUser генерирует объединенное событие, чтобы добавить этого конкретного пользователя в чат.

Вывод

Мы многому научились, создав приложение для чата в реальном времени с помощью статей Vuejs, socket.io и Nodejs.

Кроме того, мы узнали, как добавить аутентификацию и добавить управление базой данных для управления всеми вашими новыми изменениями.

Надеюсь, вы узнали что-то новое о Vue, Node, Express и Socket.IO. Полный код находится на GitHub, скачай сейчас.

Спасибо, что прочитали мою статью.

Здесь, в моем блоге или медиа, я регулярно пишу о backend-разработке, цифровом маркетинге и системе управления контентом. Чтобы читать мои будущие сообщения, просто присоединяйтесь к моей публикации или нажмите Подписаться. Также не стесняйтесь связываться со мной через Twitter, Facebook, Instagram.

Если вам понравился этот пост, обязательно сообщите нам и поделитесь им с друзьями.

Первоначально опубликовано на https://masteringbackend.com 25 января 2021 г.