image.png

Written in the book of the former

I have always wanted to implement a chat application demo, try socket. IO framework, at the same time see online tutorials about the use of Node chat application demo are chatroom form, that is, group chat, very few implementation of private chat. So I wanted to do it myself. In addition, I also tried to upload and download the profile pictures of registered users by accessing vientiane Youtuo API of Tencent Cloud when uploading profile pictures, which proved to be quite useful. =, but the server where the interface is deployed will run out of money to rent at some point, so it may not be able to run the upload function. Making the address

I. Introduction to technology

Vue

Vue. Js is a front-end MVVM development framework opened source in February 2014. Its core content is to provide simple API for developers, and build a reusable component system by realizing efficient data binding.

Nodejs

Node.js is a platform based on the Chrome JavaScript runtime for building fast, easily extensible web applications. Node.js uses an event-driven, non-blocking I/O model to be lightweight and efficient, making it ideal for running data-intensive real-time applications on distributed devices.

MongoDB

MongoDB is a database based on distributed file storage. Written in C++ language. Designed to provide scalable high-performance data storage solutions for WEB applications.

Socket.IO

Socket.IO is a cross-platform open source framework that is fully implemented by JavaScript, based on Node.js and supports WebSocket protocol for real-time communication. Socket.IO not only supports WebSocket communication protocol, but also supports many Polling mechanisms and other real-time communication methods, and encapsulates into a common interface, and implements the corresponding code of these real-time mechanisms in the server. Socket.IO selects the best mode for real-time network communication based on the communication mechanism supported by the browser.

Second, the function of

  • [x]
  • [x] to register
  • [x] address book
  • [x] Chat list
  • [x] private chat
  • [x] group chat
  • [x] Friend management

    Iii. Key function realization

    Upload pictures for Tencent Cloud

    Image preview problem

    Due to browser security restrictions, the real address of the file submitted in the input file cannot be obtained, which makes it impossible to obtain the desired preview image directly from the address. So you can use an HTML5API, FileReader object.Developer.mozilla.org/zh-CN/docs/…





    image.png

    Upload it to the Cloud






    Tencent cloud interface deployment is divided into two parts, one is its own server for authentication services, the other is Tencent server to store pictures. As can be seen from the figure, the first step is to obtain the address of uploading profile picture from your own server. This step is the authentication service. For details, please refer to the codeOfficial document of Tencent Cloud. After how to upload to Tencent cloud is also the use of official interface. The document is relatively detailed, at the same time, if there is a bug, you can also initiate the engineer consultation of tx. That time my engineer called me at 11 PM to fix the bug. =, so if you have a programmer husband/wife, please cherish it

    Private & group chat

    The interfaces of private chat and group chat are reused by the same component. In the front page, you need to determine whether to render private chat or group chat messages. At the same time, the back end also needs to determine whether it is group chat or private message mode.

    The front-end logic of communication is as follows:





    image.png


    The back-end logic for the communication is as follows:





    image.png

    Begin to implement

  • Socket.IO is deployed on the front end and back end
// client.js front-end deployment socket.io
import io from 'socket.io-client'
const CHAT={
  ...
  init:function(username){
    // Connect to the WebSocket backend server
    this.socket = io.connect('http://127.0.0.1:3000', {'force new connection': true})
    this.socket.on('open'.function() {
      console.log('Connected')})this.socket.emit('addUser', username)
  }
}
export default CHATCopy the code
// server/bin/ WWW backend socket. IO
var io = require('socket.io')(server)
io.on('connection'.function(socket){... socket.emit('open')... }) socket.on("disconnect".function () {
  console.log("The client is disconnected.")
  delete 'A corresponding socket object' 
  // Delete the socket connection every time otherwise disconnect and reconnect the same socket but the client socket has changed
})Copy the code

After deployment, both the front and back ends can use emit and ON to send and listen for custom events. Socket. IO document

  1. Front end differentiating render private chat group chat
// src/component/talk.vue
<div v-for="msgObj in CHAT.msgArr" track-by="$index">
    <div  class="talk-space self-talk" 
        v-if="CHAT.msgArr[$index].fromUser == username && CHAT.msgArr[$index].toUser == $route.query.username" 
        track-by="$index">
    <div class="talk-content">
      <div class="talk-word talk-word-self">{{ msgObj.msg }}</div><i class="swip"></i>
    </div>
    </div>
    <div v-else></div>
    <div  class="talk-space user-talk" 
        v-if="CHAT.msgArr[$index].toUser == username && CHAT.msgArr[$index].fromUser == $route.query.username" 
        track-by="$index">
    <div class="talk-content">
      <div v-if="CHAT. MsgArr [$index]. FromUser ==" class="talk-all">{{ msgObj.trueFrom }}</div>
      <div class="talk-word talk-word-user">
        {{ msgObj.msg }}
        <i class="swip-user"></i>
      </div>
    </div>
</div>Copy the code

You can see that a public message queue is maintained in chat.msgarr, which contains both group and private messages. And each array object contains the fromUSer and toUser methods to distinguish the sender from the receiver. The user name carried in the route is used to determine whether the message should be rendered on the left or right side of the interface. At the same time, although the chat object of the user is “group chat”, the message sent by the left “group chat” should still be rendered with the real user name, namely msgobj.trueFrom field.

3. Back-end communication logic

// server/bin/www
io.on('connection', function(socket){
  var toUser = {}
  var fromUser = {}
  var msg = ' '
  socket.emit('open')
  socket.on('addUser', function(username) {
    if(! onlineUsers.hasOwnProperty(username)) { onlineUsers[username] = socket onlineCount = onlineCount +1
    }
    user = username
    console.log(onlineUsers[username].id) // After the connection is established, the user clicks different address books to establish the same socket object
    console.log('Number of people online:',onlineCount)
      socket.on('sendMsg', function(obj) {
        toUser = obj.toUser
        fromUser = obj.fromUser
        msg = obj.msg
        time = obj.time
        if (toUser == 'chatting') { // Group chat mode
            obj.fromUser = 'chatting'
            obj.toUser = user
            obj.trueFrom = fromUser // Carry the real sender
          for (user in onlineUsers) { // Iterate over all objects to distinguish yourself from other users
            if( user ! = fromUser ) {/ / receiver
              onlineUsers[user].emit('to' + user, obj)
            } else { / / the sender
              obj.toUser = 'chatting'
              obj.fromUser = user
              onlineUsers[fromUser].emit('to' + fromUser, obj)
            }
          }
        } 
        else if(toUser in onlineUsers) { Private chat mode
          onlineUsers[toUser].emit('to' + toUser, obj)
          onlineUsers[fromUser].emit('to' + fromUser, obj)
        } else {
          console.log(toUser + 'Not online')
          onlineUsers[fromUser].emit('to' + fromUser, obj)
        }
      })
    socket.on("disconnect", function () {
      console.log("The client is disconnected.")
      // Remove the socket connection every time you encounter a pit, otherwise disconnect and reconnect the same socket, but the client socket has changed
      delete onlineUsers[fromUser] 
    })
  })
})Copy the code

The effect is shown below:









The last

This is the most basic implementation of a chat demo and the first time I wrote a small share myself. The UI aspect borrows some of the styling from the Web version of WX. At the same time, there are still some “unpredictable” bugs in the code, such as chat message display sometimes has problems, but there is no good way to troubleshoot, mainly because IT is the first time to use VUE to do the front-end framework, I still can’t get used to the separation of HTML and JS, and THE debugging is not good enough, after all, react has been used for a long time. Well, that’s not a reason, so welcome to share your thoughts and bug issues, although I may… Finally, post a Github address: github.com/Aaaaaaaty/v…