目录

基于微信小程序实现聊天室功能

基于微信小程序实现聊天室功能

基于微信小程序实现聊天室功能

一、引言

在当今社交网络盛行的时代,聊天室功能成为许多应用不可或缺的一部分。本文将详细介绍如何使用微信小程序开发一个简单的聊天室应用,包括前端界面的搭建以及与后端 WebSocket 的连接交互等步骤,通过代码示例和相关知识讲解,帮助读者理解并掌握小程序聊天室开发的基本流程和要点。

二、前端界面设计

整体布局

在 pages/pullDetail/pullDetail.wxml 文件中,我们构建了聊天室的前端界面。

1.整体布局主要包含以下几个部分:

连接状态提示:

//	html
<view wx:if="{{loadingSocket}}">
  聊天室连接中...
</view>

这里通过 wx:if 指令判断 loadingSocket 变量的值,如果为 true,则显示 “聊天室连接中…” 的提示信息,用于告知用户当前连接状态。

2. 聊天记录展示区:
//	html
<scroll-view class="chat-container" scroll-y scroll-into-view="{{'k'+list[list.length-1].id}}">
  <view class="chat-item {{userName == item.from? 'my-msg' : ''}}" wx:for="{{list}}" wx:key="id" id="{{'k'+item.id}}">
    <view class="avatar">
      <image src="{{item.avatar}}">
      </image>
    </view>
    <view class="msg-box">
      <view class="nickname" wx:if="{{userName!== item.from}}">
        {{item.nickName}}
      </view>
      <view wx:if="{{item.type == 1}}" class="content-box">
        {{item.content}}
      </view>
      <view wx:elif="{{item.type==2}}" class="img-content" >
        <image src="{{item.content}}" mode="widthFix">
        </image>
      </view>
    </view>
  </view>
</scroll-view>

使用 scroll-view 组件实现聊天记录的滚动展示,scroll-y 属性表示允许垂直滚动。通过 wx:for 指令遍历 list 数组来展示每条聊天消息,根据消息发送者是否为当前用户,通过条件类 { {userName == item.from? ‘my-msg’ : ‘’}} 来区分不同的消息样式。对于文本消息,在 content-box 中展示 item.content,对于图片消息,则在 img-content 中展示 image 组件,其 src 属性为 item.content(这里假设图片消息的 content 为图片链接)。

3. 消息输入发送区:
//	html
<view class="send-msg-container">
    <input class="input" type="text" model:value="{{value}}" />
  <view class="action-box">
    <van-icon name="smile-o" class="icon" bind:tap="sendImg" />
    <van-button class="send-btn" square type="primary" bind:tap="sendMsg">发送</van-button>
  </view>
</view>

这里有一个文本输入框 input,通过 model:value 双向绑定 value 变量,用于获取用户输入的消息内容。还有一个图标 van-icon 用于触发发送图片的功能(这里只是绑定了 sendImg 函数,具体功能未完整实现),以及一个发送按钮 van-button,点击时触发 sendMsg 函数来发送消息。

三、后端连接与交互

(一)WebSocket 连接建立

在 pages/pullDetail/pullDetail.js 文件中,在 onLoad 生命周期函数里进行 WebSocket 连接的创建:

// 1、创建一个 WebSocket 连接
wx.connectSocket({
  url: `ws://192.168.5.120:13000?username=${app.globalData.userInfo.loginName}&password=&courseId=${this.data.courseId }&nickName=${app.globalData.userInfo.userName}&avatar=${app.globalData.userInfo.avatar}`,
})

这里使用 wx.connectSocket 方法创建一个 WebSocket 连接,连接地址包含了一些参数,如用户名 username、课程 ID courseId、昵称 nickName 和头像 avatar 等信息,这些参数将被传递到后端服务器,以便服务器识别和处理不同用户的连接和消息。

(二)连接打开事件监听

接着监听 WebSocket 连接打开事件:

// 2、监听 WebSocket 连接打开事件。
wx.onSocketOpen(() => {
  console.log('连接建立成功');
  this.setData({
    loadingSocket: false
  })
  // 3、获取聊天记录
  wx.sendSocketMessage({
    data: JSON.stringify({
      cmd: 19, // 命令  
      type: 1, // 类型 固定值 
      groupId: this.data.courseId, //  分组的id 
      userId: app.globalData.userInfo.loginName // 用户id(这里可以用loginName)
    }),
  })
  // 4、添加心跳检测
  this.data.timer = setInterval(()=>{
    wx.sendSocketMessage({
      data: JSON.stringify({
        "cmd": 13, // 固定参数 
        "hbbyte": "-127" // 固定参数
      }),
    })
  },5000)
})

当连接成功打开后,首先将 loadingSocket 设置为 false,隐藏连接中提示。然后通过 wx.sendSocketMessage 向服务器发送一个获取聊天记录的请求,请求数据是一个 JSON 字符串,包含了命令 cmd、类型 type、分组 ID groupId 和用户 ID userId 等信息。同时,设置了一个心跳检测定时器 setInterval,每隔 5 秒向服务器发送一个心跳消息,用于保持连接的活跃性,心跳消息的数据也是一个 JSON 字符串,包含固定的命令 cmd 和参数 hbbyte。

(三)接收服务器消息事件监听

监听 WebSocket 接收到服务器消息的事件:

// 5、监听 WebSocket 接收到服务器的消息事件。
wx.onSocketMessage((result) => {
  let data = JSON.parse(result.data)
  if(data.command ==  11){
   this.data.list.push(data.data)
   this.setData({
     list: this.data.list
   })
  }else if(data.command === 20 && data.code === 10018){
    console.log('历史消息');
    if( data.data){
      this.setData({
        list: data.data.groups[this.data.courseId]
      })
    }
  }
})

当接收到服务器消息时,首先将消息数据 result.data 解析为 JSON 对象 data。如果 data.command 为 11,则将消息数据 data.data 推送到本地的 list 数组中,并更新界面显示。如果 data.command 为 20 且 code 为 10018,则表示接收到的是历史消息,将历史消息数据中的对应课程 ID 的聊天记录设置为本地 list 数组,并更新界面。

(四)发送消息函数

定义发送消息函数 sendSocketMessage 和 sendMsg:

sendSocketMessage(content, type){
  let data =  {      
    from: app.globalData.userInfo.loginName,  // 发送人,当前用户的用户名 
    createTime: new Date().getTime(), // 发送时间   
    cmd: 11,  // 命令固定内容   
    group_id: this.data.courseId,  // 分组id。  想要发送到哪个组里     
    chatType: 1,  //  聊天类型 固定内容  
    msgType: 0, // 消息类型 固定内容   
    content, // 消息内容,自己设计结构,比如你想发送图片(图片上传的接口)  
    nickName: app.globalData.userInfo.userName, // 用户昵称   
    avatar: app.globalData.userInfo.avatar, // 用户头像  
    type // 消息类型。 你可以自己设计,发送过去是什么,返回的就是什么(1: 普通文本 2: 图片 3:点赞 4, 送花)
    }
  wx.sendSocketMessage({
    data: JSON.stringify(data),
  })
}
// 发送消息
sendMsg(){
  this.sendSocketMessage(this.data.value,1)
  // 清空输入框
  this.setData({
    value:''
  })
}

sendSocketMessage 函数用于构建发送消息的数据对象,包括发送人、时间、命令、分组 ID、聊天类型、消息类型、消息内容、昵称、头像和自定义的消息类型等信息,然后将其转换为 JSON 字符串并通过 wx.sendSocketMessage 发送到服务器。sendMsg 函数则是在用户点击发送按钮时被调用,它获取输入框中的消息内容 this.data.value,调用 sendSocketMessage 函数发送普通文本消息(消息类型为 1),并清空输入框。

四、页面生命周期管理

在小程序的生命周期函数中,除了上述提到的 onLoad 函数用于页面加载时的初始化操作外,还有其他几个重要的生命周期函数:

onReady:在页面初次渲染完成后调用,可以在这里进行一些与页面渲染完成后相关的操作,但在本示例中未使用。

onShow:当页面显示时调用,可用于在页面每次显示时进行数据更新或其他操作,本示例未使用。

onHide:当页面隐藏时调用,可用于暂停一些不必要的操作,如停止定时器等,本示例未涉及相关操作。

onUnload:在页面卸载时调用,用于清理资源,如断开 WebSocket 连接和清空心跳检测定时器:

onUnload() {
  // 断开聊天室
  wx.closeSocket({
    code: 1000
  })
  // 清空定时器
  clearInterval(this.data.timer)
}

这里通过 wx.closeSocket 方法关闭 WebSocket 连接,并使用 clearInterval 清除心跳检测定时器,释放资源,避免内存泄漏等问题。

五、总结

通过以上步骤,我们实现了一个简单的微信小程序聊天室功能。从前端界面的设计搭建,包括聊天记录展示、消息输入发送等组件的布局和样式设置,到后端 WebSocket 的连接建立、连接打开事件、接收消息事件的监听处理,以及发送消息函数的实现,再到页面生命周期的合理管理,各个环节相互配合,共同构建了一个完整的聊天室应用。读者可以根据此示例进一步扩展和完善功能,如添加更多的聊天表情、实现图片上传发送、优化界面交互体验等,以满足不同的业务需求。同时,在实际开发中,还需要考虑服务器的性能优化、消息的安全性和可靠性等多方面的因素,以打造一个高质量的聊天室应用。