小程序实时聊天socket

项目背景:小程序直播平台上显示实时聊天
技术站:小程序API

     首先对于不了解webSocket的来个简单的介绍,因为http协议只能由客户端发送请求,服务端收到请求之后返回相应结果,而且是一个客户端对应一个服务端,所以对于现在好多的实时聊天是不合适的,想一下,如果你发送了一条消息,服务端收到消息后又给你返回你发送成功了,而且你只能跟一个人聊天不能接受好多人的消息,所以出现了wss协议,使用webSocket技术可以使这个功能实现,详情请参照 这里

切入正题:

需求:首先进入页面要显示10条最新的聊天记录,如果记录比较多就显示加载更多,然后加载出更多的消息内容,然后输入内容发送出内容到页面上

看代码:
HTML:

// 获取到最新的消息循环显示
<view wx:for="{{chatList.data}}" wx:key="index">
  <text class='user'>{{item.nickname}}:</text>
  <text class='user-content'>{{item.content}}</text>
</view>
// 用户自己发送的内容
<view wx:for="{{UserChatList}}" wx:key="index" wx:if="{{isUser}}">
  <text class='user' wx:if="{{item.nickname}}">{{item.nickname}}:</text>
  <text class='user-content'>{{item.content}}</text>
</view>
// socket是否链接的提示(有无都可以)
<text wx:if="{{isOpen}}" style='font-size:30rpx;padding-left:30rpx'>{{statusMsg}}</text>
// 用户发送信息的输入框
<view class='user-input' style="font-size:0">
  <textarea bindinput='bindContent' class='input' value="{{input_value_content}}" show-confirm-bar="{{showConfirm}}" bindconfirm="handleSendMessage" fixed='{{fixed}}' cursor="10" cursor-spacing="10" style='z-index:998'></textarea>
  <text bindtap="handleSendMessage" class='send'>发送</text>
</view>

css代码不贴了,简单的写样式


js

Page({

  /**
   * 页面的初始数据
   * 
   * 
   */
  data: {
    resource_id: '',
    book_id: '',
    content: '',
    chatList: '',
    is_content_chat: true,
    isShowMore: false,
    isOpen: false,
    statusMsg: '已断开',
    input_value_content:'',
    UserChatList: [],
    isUser: false
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that = this;
    this.setData({
      resource_id: options.resource_id,
      book_id: options.book_id,
      is_content_chat: true,
      isShowMore: false,
      input_value_content: '',
      UserChatList: [],
      fixed: true,
      isUser: false,
      isOpen: false
    })

    this.data.resource_id = options.resource_id;
    
    this.wssInit()
  },
  // 获取直播聊天列表
  handleGetChatList () {
    getChatList({
      token: wx.getStorageSync('token'),
      resource_id: this.data.resource_id,
      book_id: this.data.book_id
    }).then(res => {
      if (res.data.length > 9) {
        this.setData({
          isShowMore: true,
          chatList: res,
          isOpen: false,
        })
      } else {
        this.setData({
          chatList: res,
          isShowMore: false,
          isOpen: false,
        })
      }
    }).catch(err => {
      Event.initShowToast(err, this);
    })
  },
  // // 获取输入框value
  bindContent(e) {
    this.setData({
      content: e.detail.value,
      send: true
    })
    if (e.detail.value == '') {
      this.setData({
        content: e.detail.value,
        send: false
      })
    }
  },
  // // 下拉获取更多聊天记录
  getMoreChatList() {
    if (this.data.chatList.min_id == 0) {
      wx.showToast({
        title: '没有更多记录了哦',
        icon: 'none',
        duration: 1000
      })
      return;
    }
    this.setData({
      loading: true
    })
    getChatList({
      token: wx.getStorageSync('token'),
      resource_id: this.data.resource_id,
      book_id: this.data.book_id,
      page_index: 0,
      page_size: 10,
      start_id: this.data.chatList.min_id
    }).then(res => {
      // 把之前得到的聊天数据和重新加载的拼接在一起
      res.data.reverse().forEach(item => {
        this.data.chatList.data.unshift(item)
      })
      this.data.chatList.min_id = res.min_id;
      var that = this;
      setTimeout(function () {
        that.setData({
          chatList: that.data.chatList,
          loading: false
        })
      }, 500)
    }).catch(err => {
      Event.initShowToast(err, this);
    })
  },
  wssInit () {
	var that = this;
    this.connectWss();
    // 链接失败显示
    wx.onSocketError(function (res) {
      console.log('WebSocket连接打开失败,请检查!', res);
      that.setData({
        isOpen: false,
        statusMsg: '已断开'
      });
    });
    // 监听连接成功
    wx.onSocketOpen(function (res) {
      console.log('WebSocket连接已打开!')
      that.setData({
        isOpen: true,
        statusMsg: '已连接'
      });
      that.handleGetChatList()
      wx.onSocketMessage(function (res) {
        console.log('收到服务器内容:', res);
        var res_data = JSON.parse(res.data);
        if (res_data.errcode > 0) {
          wx.showToast({
            title: '内容涉及敏感信息!',
            icon: 'none',
            duration: 2000
          })
        }
        if (!res_data.msg && !res_data.rooms) {
          that.data.UserChatList.push(res_data)
          that.setData({
            isUser: true,
            UserChatList: that.data.UserChatList
          })
          setTimeout(function () {
            wx.createSelectorQuery().select('#chatContent').boundingClientRect(function (rect) {
              that.setData({
                scrollTop: rect.height + 100000
              })
            }).exec()
          }, 500)
        } else {
          wx.showToast({
            title: res_data.msg,
            icon: 'none',
            duration: 3000
          })
        }    
      });
      wx.sendSocketMessage({
        data: JSON.stringify({
          token: wx.getStorageSync('token'),
          resource_id: that.data.resource_id,
          book_id: that.data.book_id,
        }),
        success: res => {
          console.log(res+'发送成功')
        },
        fail: err=> {
          console.log(err+'失败')
        }
      });
    })
  },
  // 向服务器发送消息
  handleSendMessage: function () {
    var that = this;
    console.log('尝试向服务器发送消息:');
    connect()
    if (that.data.content.trim() == '') {
      wx.showToast({
        title: '内容不能为空!',
        icon: 'none',
        duration: 2000
      })
      return;
    }
    wx.sendSocketMessage({
      data: JSON.stringify({content:that.data.content}),
      success: res => {
        that.setData({
          input_value_content: '',
          content: ''
        })      
      }
    });
  },
  connectWss: function () {
    this.setData({
      statusMsg: '连接中。。。'
    });
    connect();
  },
})
function connect() {
  wx.connectSocket({
    url: 'wss://api.tl100.com/wss',
    success: function (res) {
      console.log('连接成功');
    }
  });
}

好了,代码就这些,到此已经可以实现实时聊天的效果了

有网友评论说我的全是错,我确实是个前端小白,代码很多不如意的,刚改了一下,确实还有很多不完善(但是可以用哦,已经上线了),我希望有看不下去的大神能教教本小宝怎么写的更完美的话我也是感激不尽的哈,哈哈哈~
  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值