Using Noejs Websocket to Establish one to one Instant Messaging Service

Keywords: JSON Redis MongoDB

Requirement: One-to-one instant messaging service using nodejs-websocket

Environment: nodejs

Design idea: Save message channel and return message through message channel.

Data Storage: Redis, MongoDB, Show Code without Example

First, I want to know what websocket is.

WebSocket is based on TCP protocol, and has good compatibility with HTTP protocol. The biggest characteristic is that the server can actively push messages to the client, and the client can actively send messages to the server.

Secondly, what is nodejs-websocket?

Look here https://www.npmjs.com/package/nodejs-websocket

Now that you have seen this, it means that you have mastered the basics, so will not go into any more details about node project initialization and installation of nodejs-websocket.

const ws = require('nodejs-websocket')
const PORT = 8000
// passageway
let AllConn = [{ userId: 'test001' }]
// Message record
let messageList = []

// Create a service
var server = ws.createServer(function (conn) {
  console.log('New connection')
  console.log(AllConn.length)
  // Return function when client has message
  conn.on('text', function (str) {
    const msg = JSON.parse(str)
    // Establishing channels
    if (msg.type === 'get-pass') {
      // Judgment of existence
      let exist = AllConn.some(item => {
        return item.userId === msg.userId // true or false
      })
      if (exist) {
        // There is a replacement key
        AllConn.forEach((item) => {
          if (item.userId === msg.userId) {
            item.wskey = conn.key
          }
        })
      } else {
        AllConn.push({
          'userId': msg.userId,
          'wskey': conn.key
        })
        conn.sendText(JSON.stringify({ code: '1', msg: 'Channel Creation Successful' }))
      }
    }


    // Find the channel by receiving the message identifier
    if (msg.type === 'get-enter') {
      // Packets that organizations need to send
      let conversations = {
        formId: msg.userId,
        toId: msg.toId,
        msgUserId: msg.msgUserId, // Message id = userId
        content: msg.content,
        createTime: msg.createTime,
        timeStr: getMyTime(msg.createTime),
        read: false
      }
      // Received message return
      conn.sendText(JSON.stringify(conversations))
      AllConn.forEach(item => {
        // Channel existence
        if (item.userId === msg.toId) {
          // Get the channel key and send the data packet
          broadcast(conversations, item.wskey)
        }
      })
    }
  })

  conn.on('close', (code, res) => {
    // Client disconnects
    console.log(conn.key + 'Has been disconnected.')
    AllConn.forEach((item, index, arr) => {
      if (item.wskey === conn.key) {
        // Delete channel records
        arr.splice(index, 1)
      }
    })
  })
  conn.on('error', function (err) {
    console.log('error:' + JSON.stringify(err))
  })
}).listen(PORT)

/**
 * @description:Broadcasting function
 * @param {Object} str Message packet
 * @param {Object} wskey Channel key
 * @return:
 */
function broadcast (str, wskey) {
  // Traverse all channels
  server.connections.forEach(conn => {
    const key = conn.key
    // Find the specified channel
    if (key === wskey) {
      conn.sendText(JSON.stringify(str))
    }
  })
}


/**
 * @description: Time stamp time
 * @param {type}
 * @return:
 */
function getMyTime (timestamp) {
  let date = new Date(timestamp)
  let hours = date.getHours()
  let minutes = date.getMinutes()
  return `${hours >= 10 ? hours : '0' + hours}:${minutes >= 10 ? minutes : '0' + minutes}`
}

If any big man finds imperfections, errors and better ways, criticize and correct them.

Posted by robwilson on Mon, 07 Oct 2019 20:56:47 -0700