“This is the fourth day of my participation in the First Challenge 2022. For details: First Challenge 2022”

preface

To implement one-on-one real-time chat, we need to use the WebSocket protocol, which is supported by all popular browsers. Node.js provides an efficient server running environment, but due to the browser side of HTML5 support is different, in order to compatible with all browsers, provide excellent real-time user experience, and provide programmers with client and server consistent programming experience, so socket. IO was born. Socket. IO encapsulates Websocket, polling mechanism and other real-time communication methods into general interfaces, and implements corresponding codes of these real-time mechanisms on the server side.

All open source code: github.com/HJianfeng/s…

The front part

For the front end, we use Vue3 + ElementUI as the framework. We won’t go into details about how to create the project. You can refer to my first two articles.

pattern

First we need to write a simple style. Create a page SRC /views/home.vue and add HTML and styles

// src/views/home.vue
<template>
  <div class="container">
    <div class="chat-content">
      <template v-if="chatList && chatList.length">
        <div
          v-for="(chat, index) in chatList"
          class="message-box"
          :class="{'right-message': chat.user.id === userInfo.user.id}"
          :key="index"
        >
          <div class="user">
            <el-avatar v-if="chat.user.id ! == userInfo.user.id" class="avatar" :src="chat.user.avatar" ></el-avatar>
            <div class="info">
              <div class="name">{{chat.user.name}}</div>
              <div class="time">{{chat.createTime}}</div>
            </div>
            <el-avatar v-if="chat.user.id === userInfo.user.id" class="avatar" :src="chat.user.avatar" ></el-avatar>
          </div>
          <div class="message"><div class="block">{{chat.message}}</div></div>
        </div>
      </template>
      <div v-else class="empty">No news</div>
    </div>
    <div class="chat-bottom">
      <el-input v-model="chatMsg" class="chat-input" placeholder="Please enter the content" />
      <el-button class="chat-btn" type="primary" @click="sendMsg">send</el-button>
    </div>
    <div style="margin-top: 10px;">Current User:<el-select v-model="userInfo.user" value-key="id" @change="selectUser" placeholder="Select">
        <el-option
          v-for="item in userList"
          :key="item.id"
          :label="item.name"
          :value="item"
        >
        </el-option>
      </el-select>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue';

const avatar = 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png';
export default {
  name: 'HomePage'.setup() {
    const chatList = ref([]); // Message list
    const chatMsg = ref(' ');
    const userList = [{ name: Users' 1 '.id: 0, avatar }, { name: Users' 2 '.id: 1, avatar }]; // List of users, two users in total
    const userInfo = reactive({ user: userList[0]});// Current logged-in user
    const selectUser = (user) = > {
        // Switch the current login user
      userInfo.user = user;
    };
    return{ chatMsg, chatList, userList, userInfo, selectUser }; }};</script>

<style lang="scss" scoped>.</style>

Copy the code

Define a list of users, userList, and the information of the currently logged user. You can switch the current user at any time by using the drop-down option

I will not post the style part, you can directly go to the warehouse to check. When we’re done, our static effect looks like this.

socket.io-client

We need to install the socket. IO client package

npm i socket.io-client
Copy the code

Open the SRC/views/home. Vue

// src/views/home.vue
<template>
...
</template>
<script>
import { onMounted, ref, reactive } from 'vue';
import io from 'socket.io-client';

const avatar = 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png';

export default {
  name: 'HomePage'.setup() {
    const chatList = ref([]);
    const chatMsg = ref(' ');
    const userList = [{ name: Users' 1 '.id: 0, avatar }, { name: Users' 2 '.id: 1, avatar }];
    const userInfo = reactive({ user: userList[0]});let socket;
    onMounted(() = > {
      socket = io('http://localhost:3001'); // Connect to the socket. IO method of the backend to pass the server IP
      socket.on('connect'.() = > {
        console.log(socket.id, 'Listening client connection successful -connect');
      });
      socket.on('fresh-message'.(data) = > {
        // Define an event to get the list of messages pushed back by the server
        chatList.value = data;
      });
    });
    const selectUser = (user) = > {
        // Switch the current login user
      userInfo.user = user;
    };
    const sendMsg = () = > {
      // Send messages using the custom event send-message
      socket.emit('send-message', userInfo.user, chatMsg.value);
      chatMsg.value = ' ';
    };
    return{ chatMsg, chatList, userList, userInfo, sendMsg, selectUser, }; }};</script>
Copy the code

Two events are defined: send-message and fresh-message. Send-message is used to send messages to the server, and fresh-message gets the message list

The backend part

The back-end part of the code is simpler, using the KOa.js framework, with the dependencies installed first

npm install --save koa moment http socket.io
Copy the code

The root directory app. Js

// app.js
const Koa = require('koa');
const http = require('http');
const { Server } = require('socket.io');
const moment = require('moment');

const app = new Koa();

const chatList = [];
const server = http.createServer(app.callback());
const io = new Server(server, {
  serveClient: false.cors: {
    origin: The '*'.// from the screenshot you provided
    methods: ['GET'.'POST'],}}); io.on('connection'.(socket) = > {
  socket.emit('fresh-message', chatList);
  socket.on('send-message'.(user, message) = > {
    const createTime = moment().format('YYYY-MM-DD HH:mm:ss');
    chatList.push({
      user,
      message,
      createTime,
    });
    socket.emit('fresh-message', chatList);
  });
});
io.listen(3001);

Copy the code

The code is simple: define a chatList variable to hold the list of messages, listen for the send-message event, save the message and create time when it is triggered. The fresh-message is then triggered to send to the client

conclusion

We only created two users as an example, but if you want to do better, you can add a user creation page so that many users can chat together at the same time.