Implementation of a Simple Chat Room with vue + socket.io

Keywords: Javascript Vue socket npm

vue + vuex + elementUi + socket.io implements a simple online chat room to improve their depth of application of vue Series in the project. Because it's easy to learn a library or framework, but it's not so easy to use a library or framework in conjunction with a project. Although not many functions, but there are gains. The idea of design and implementation is rather clumsy. I beg you to make a great correction.

Achievable needs

  • View the list of online users
  • Ability to send and receive messages

Frameworks and libraries used

  • socket.io as the basis of real-time communication
  • vuex/vue: client Ui layer usage
  • Element-ui: Client Ui component

Class File Diagram

Server:

Client:

Server-side implementation

Implement the related functions of chat server, including the creation of communication channels, user joining, message receiving and forwarding, etc.

I. Establishment of Communication Services

build/server-config.js: Entry to Chat Server

let socketIo = require('socket.io');
let express = require('express'); 
let cxt = require('../src/services-server');

let httpPort = 9001;
let channelId = 1
let app = express();

app.get('/',function(req,res){
    res.send('Successful start-up:' + httpPort);
});
 
let server = require('http').createServer(app);
let io = socketIo(server);
io.on('connection',function(socket){ 
    console.log('Client Connection');
    cxt.createChannel(channelId++,socket)
});
server.listen(httpPort); //use server Connect
console.log('io listen success !! ' + httpPort);
  • Create a server object through express, and then create io objects using socketIo
  • Then listen for connection events through io's on method
  • When there is a client connection, the connection event is triggered, and the county immediately invokes the createChannel method of "Server Context" (hereinafter referred to as cxt) to create a pipeline. At this time, there is no user information on the pipeline.

Create context (server context)

Implement a chat room context that contains arrays of users, rooms, messages, pipes, etc., so the code is in the service-server directory.

  • index.js: Chat room server context creates entry, creates context, and initializes the room to context.
  • context.js: Chat room server context class, user, room, message, pipeline and so on to do centralized management.
  • room directory: implementation of a collection of rooms and rooms
  • channel: Pipeline class for communication between server and client
    Combined with the connection event in "Communication Service Establishment", then go to the cxt.createChannel method
createChannel (id, socket) {
    let channel = new Channel(id, socket, this)
    channel.init()
    channel.index = this.channels.length
    this.channels.push(channel)
}

At this point, a pipeline instance is created, then the pipeline instance is initialized, and the pipeline is added to the pipeline array. The following is the code to initialize the pipeline instance:

init () {
    let self = this
    let roomInfo = this.cxt.room.collections[0]
    this.roomInfo = roomInfo
    this.socket.join('roomId' + roomInfo.id)
    this.socket.emit(this.cxt.eventKeys.emit.sendRooms, roomInfo) /* send Go out to a default room */
    this.socket.on(this.cxt.eventKeys.client.registerUser, function (id, name) {
      console.log(id + '-' + name + '--' + self.id)
      self.cxt.createUserById(id, name, self.id)
    }) /** New user registration */
    this.socket.on(this.cxt.eventKeys.client.newMsg, function (msg) { /** send message */
      self.notifyMsg(msg)
      console.log(msg)
      self.cxt.addMsg(msg)
    })
    this.socket.on(this.cxt.eventKeys.client.closeConn, function () {
      console.log(self.id + '--Close connection')
      self.cxt.remove(self)
    })
    this.sendUsers()
}

When initializing the pipeline instance, the following events are done:

  • Add a communication socket to the room to facilitate good news broadcasting in the future
  • Send room information to the currently connected socket and set it to the first room
  • Listen for three events: user registration, new messages, and connection closure. Here all need to be processed logically, you can refer to the source code.

Client-side Implementation

The main functions are to connect services, register users, send and receive messages. Firstly, the main.js is used as the entrance, and the vue-related accessories, such as vuex, ElemUi, client communication pipeline, etc., need to be assembled first. Then, the Vue instance and the connection message server are created. The code is as follows:

import '../node_modules/bootstrap/dist/css/bootstrap.css'
import Vue from 'vue'
import ElemUi from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
import App from './App'
import * as stores from './store'
import { Keys } from './uitls'
import { getCxt } from './services-client'

let initRoomInfo = Keys.SETROOMINFO
Vue.use(ElemUi)
/* eslint-disable no-new */
new Vue({
  store: stores.default,
  el: '#app',
  template: '<App/>',
  components: { App },
  created: function () {
    let self = this
    getCxt().createIo(this, function (roomInfo) {
      stores.busCxt.init() /** Initialize the interaction layer between view and service layer (business layer) */
      self.$store.dispatch(initRoomInfo, roomInfo)
      getCxt().refUsers(function (users) {
        stores.busCxt.userCxt.refUsers(users)
      })
    })
  }
})

1. Communication with the server

Instances in the service-client directory communicate with message servers, including creating users, receiving and sending messages, etc. A client can only have one message pipeline. The following code is the creation of message management:

import * as io from 'socket.io-client'
import Context from './context'

let eventKeys = require('../services-uitls/event.keys')
let url = 'http://localhost:9001/'
let cxt = null

export function getCxt () {
  if (cxt == null) {
    cxt = new Context(url, eventKeys, io)
  }
  return cxt
}

The createIo instance method of Context is called in the create ticket of the vue instance in main.js to create a connection with the message server and accept the room information sent back from the room in it. Then the business layer is initialized.

2. Combination of vuex

Implemented in the store directory, including vuex class related implementations, as well as business layer implementations. Business layer will refer to "client communication pipeline", and vuex implementation class may refer to business layer related implementation class, in order to achieve ui to "message server" communication. The store/index.js code is as follows:

import Vuex from 'vuex'
import Vue from 'vue'

import RoomViewCxt from './room/roomViewCxt'
import UserViexCxt from './userViewCxt'
import MsgViewCxt from './msg/msgViewCxt'
import BusCxt from './indexForBus'

let _busCxt = new BusCxt()

let _rvCxt = new RoomViewCxt()
let _uvCxt = new UserViexCxt(_busCxt.userCxt)
let _mvCxt = new MsgViewCxt()

let opt = {
  state: null,
  getters: null,
  mutations: null,
  actions: null
}
_rvCxt.use(opt)
_uvCxt.use(opt)
_mvCxt.use(opt)

Vue.use(Vuex)

let store = new Vuex.Store(opt)
export default store
export const busCxt = _busCxt /** Business Processing Context */
export function getBusCxt () {
  return _busCxt
}

Three, components

Component only implements user registration, main interface container, message sending and message acceptance. Components only refer to related classes in the store directory, not directly to pipeline classes.

  • Login.vue: User Registration Component
  • HChat.vue: Main Interface Container Component
  • Message/MsgWriter.vue: Send Message Component
  • Message/MsgList.vue: Accept and display message list components

How to run an example

  • Download source code
  • cnpm run install installs all dependencies
  • npm run sokcetIo starts the message server
  • npm run dev starts client
  • Sample screenshots

Posted by hank9481 on Thu, 11 Apr 2019 11:39:32 -0700