小程序 即时通讯 聊天 websocket

小程序即时通讯

即时通讯也就是利用了websocket。
需要注意的是,在小程序中,websocket最多只能存在5个。
好了,不多说了,上代码。


node代码

// npm i ws
const WebSocket = require('ws');

const server = new WebSocket.Server({
  port: 9999 // 开启websocket的端口
})

const user = {} // 注册一个对象,用来绑定用户,以便做到及时响应

server.on('connection', (client, req) => {
  client.on('open', data => {
  })

  client.on('close', res => {
  	// 在客户端关闭的时候,node端需要将该客户端的记录给清除掉
    for(let key in user) {
      if (user[key] == client) {
        delete user[key]
      }
    }
  })

  client.on('message', async message => {
    console.log('小程序传过来的数据是:', message);
    message = JSON.parse(message)
    
    // 绑定用户
    let keys = Object.keys(user)
    if (keys.length == 0) {
      user[message.user] = client
    } else {
      let flag = true
      for(let key in user) {
        if (key == message.user) {
          flag = false
        }
      }
      if (flag) {
        user[message.user] = client
      }
    }
    // 两个客户端做到即时响应,重要的就是绑定这个客户端,以做下面的响应区分

    // 发送消息
    if (!message.toUser) {
      // 首次开启,注册
      client.send(JSON.stringify({
        user: 'node',
        msg: '你好,小程序,我是node端'
      }))
    } else {
      // 拿到刚刚绑定好的客户端,发送消息给另一个客户端
      user[message.toUser].send(JSON.stringify({
        user: message.user,
        msg: message.msg
      }))
    }
  });
})

小程序代码,用的mpvue框架

<template>
  <div class="container">
    <div class="item" v-for="item in data" :key="item">
      <div class="other" v-if="item.user != user">
        <span class="icon"></span>
        <span class='message'>{{item.msg}}</span>
      </div>
      <div class="self" v-if="item.user == user">
        <span class='message'>{{item.msg}}</span>
        <span class="icon"></span>
      </div>
    </div>
    <div class="control">
      <input class='input' type="text" v-model='msg'>
      <span class='btn' @click="send">发送</span>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: '小程序1', // user是node端用来区分用户的标识
      msg: '',
      socketTask: null,
      data: []
    };
  },
  components: {
  },
  methods: {
    send() {
      this.socketTask.send({
        data: JSON.stringify({
          user: this.user,
          toUser: '小程序2', // 与 this.user不同
          msg: this.msg
        })
      })
      this.data.push({
        user: this.user,
        msg: this.msg
      })
      this.msg = ''
    }
  },
  onLoad() {
    this.socketTask = wx.connectSocket({
      url: 'ws://localhost:9999'
    })

    this.socketTask.onOpen(res => {
      console.log('res:', res)
      this.socketTask.send({
        data: JSON.stringify({
          user: this.user
        })
      })
    })

    this.socketTask.onMessage(res => {
      console.log('msg:', res)
      let data = JSON.parse(res.data)
      if(Object.prototype.toString.call(data) == "[object Array]") {
        this.data = data
      } else {
        this.data.push(data)
      }
    })
  }
};
</script>

<style scoped lang="less">
.container {
  font-size: 14px;
  .item {
    .other,
    .self {
      display: flex;
      padding: 5px 15px;
      .icon {
        width: 40px;
        height: 40px;
        border-radius: 50%;
      }
      .message {
        height: 40px;
        line-height: 40px;
        background-color: #eee;
        border-radius: 10px;
        margin: 0 20px;
        padding: 0 10px;
      }
    }
    .other {
      .icon {
        background-color: skyblue;
      }
    }
    .self {
      justify-content: flex-end;
      .icon {
        background-color: pink;
      }
    }
  }
  .control {
    width: 100%;
    height: 50px;
    background-color: #eee;
    position: fixed;
    left: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    padding: 5px 10px;
    box-sizing: border-box;
    .input {
      flex: 1;
      background-color: #fff;
      border-radius: 8px;
      padding-left: 5px;
      margin-right: 10px;
    }
    .btn {
      width: 50px;
      height: 30px;
      line-height: 30px;
      text-align: center;
      color: #fff;
      background-color: #129611;
      border-radius: 10px;
    }
  }
}
</style>

创建两个小程序端就行了,需要注意的是,user得设为不同才行,toUser也需更改。

web端也同理,区分用户的重点就是绑定client。


版权声明:本文为lert707原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。