广告
返回顶部
首页 > 资讯 > 移动开发 >【uni-app】小程序实现微信在线聊天(私聊/群聊)
  • 724
分享到

【uni-app】小程序实现微信在线聊天(私聊/群聊)

uni-app前端小程序 2023-09-03 07:09:08 724人浏览 八月长安
摘要

之前学习使用uni-app简单实现一个在线聊天的功能,今天记录一下项目核心功能的实现过程。页面UI以及功能逻辑全部来源于微信,即时聊天业务的实现使用Socket.io,前端使用uni-app开发,后端服务器基于node实现,数据库选择mon

之前学习使用uni-app简单实现一个在线聊天的功能,今天记录一下项目核心功能的实现过程。页面UI以及功能逻辑全部来源于微信,即时聊天业务的实现使用Socket.io前端使用uni-app开发后端服务器基于node实现,数据库选择mongoDB

首先在系统中注册两个用户,将对方添加为好友后,开始正常聊天,先简单看一下聊天功能的效果图,分为私聊和群聊两大部分

一对一聊天效果:

在好友列表中添加群成员创建群后即可群聊,群聊效果:

目录

聊天信息列表的渲染

聊天信息发送的相关问题

实现一对一聊天

关于websocket

建立连接

存储连接的用户

发送聊天信息 

首页新消息提示

实现群聊

加入房间

发送群消息


聊天信息列表的渲染

聊天信息列表区域是一个滚动区,这里使用scroll-view组件,其中对于聊天信息展示,主要分为自己的消息和好友的消息,自己的消息位于右侧,好友的消息位于左侧,所以静态页面阶段要实现是左侧消息和右侧消息的页面布局,以及这些消息类型为文字,图片,语音,位置信息时的布局。

后端接口返回的聊天信息是按照时间顺序排列的,渲染聊天信息时使用v-for遍历接口返回的消息列表的内容即可,需要注意的是,还需要使用条件渲染v-if根据每一条消息的发送者id和当前用户的id判断消息的发送方和接受方,渲染在左右指定的区域,当前用户的id从本地存储localStorage中获取;还有就是使用条件渲染判断消息的类型,是文字,图片,语音或定位,合理展示。

    {{handleTime(item.time)}}        ................................................

聊天信息发送的相关问题

点击发送按钮,正式将信息发送给服务器之前,还有几个问题需要解决,这里面有许多坑,在实现的时候走了不少弯路。

1.scroll-view如何始终定位在最底部?

如下图,当发送了一条聊天信息时,聊天信息列表就会增加这条消息,之所以能够看到这条消息,那是因为scroll-view的滚动条在消息添加时将位置定位到了最底部,这是需要进行一些处理的,默认效果是这样的

是不是很变扭?这样的用户体验很差,滚动条不会自动定位到底部,这里需要给scroll-view组件添加一个scroll-into-view属性,按照官方文档的说法它的值应为某子元素id。设置哪个方向可滚动,则在哪个方向滚动到该元素,也就是说可以动态的修改这个属性的值,从而让scroll-view组件的滚动到想要滚动的页面元素位置。

这里就给每一个scroll-view的子元素(聊天记录item)添加id属性,属性值为 msg + 每条聊天记录的id

                ......    

在发送消息的方法中修改scroll-into-view的值scrollToView,让其为最新一条聊天记录即msg.length - 1的id值,必须使用在$nextTick回调中,这是为了在新的聊天记录渲染完毕后再去定位。

this.$nextTick(function(){this.scrollToView = 'msg' + this.msg[this.msg.length - 1].id;});

 这样才能实现最终的效果

 

2.如何动态修改scroll-view的高度

如下图,点击 + 按钮发送位置信息时会弹出底部菜单栏,但此时scroll-view内的聊天内容会被覆盖,用户想要看最后一条记录还需操作滚动条,这也是不好的用户体验。

需要做到的是弹出底部菜单栏的同时减小聊天内容区域scroll-view组件的高度,让用户能够完整的看到最后的聊天记录。

需要获取底部菜单栏弹出的高度,随后让scroll-view组件减少这部分高度即可。在uni-app中无法操作dom,获取元素的尺寸使用createSelectorQuery获取页面节点,再用 boundingClientRect查询节点的尺寸。官方文档:uni.createSelectorQuery() | uni-app官网

使用如下代码获取页面节点的尺寸,可能无法及时获取到(得到的可能是undefined),这里需要用定时器包裹,才能拿到菜单栏的高度

{{item.text}}......// 获取指定选择器元素的高度getHeight(classNa){setTimeout(() => {const query = uni.createSelectorQuery().in(this);query.select(classNa).boundingClientRect(data => {this.$emit('heightChange',data.height);}).exec();},10);},// 切换菜单栏显示隐藏changeMode(){if(this.showMore){this.showMore = !this.showMore;this.getHeight('.more-view');}},

拿到底部菜单栏的高度后,使用calc计算并修改行内样式,并修改scroll-view的元素内的子元素定位,这里修改scrollToView的值,一定要置空后再修改,否则会修改无效。

...... // 弹出菜单栏修改scroll-view高度handleHeightChange(height){this.scrollViewHeight= `calc(100vh - 208rpx - ${height}px - ${this.statusBarHeight}px)`;this.scrollToView = '';this.$nextTick(function(){this.scrollToView = 'msg' + this.msg[this.msg.length - 1].id;})}

实现一对一聊天

关于websocket

项目中使用的socket.io底层使用到的是WEBsocket协议,可以实现服务器主动推送消息给客户端,一般应用于实时通信,在线支付等场景,虽然socket.io对其进行了封装,但对其原理的了解还是有必要的。

在websock出现之前,一般使用ajax轮询(设置定时器在相同时间间隔内反复发送请求到服务器拿到服务器最新的数据),长轮询(在指定时间内不让当前请求断开),流化技术等手段进行即时通信,这三者都基于Http协议实现,但都非常占用服务器的资源, 显著增加了延时。

websocket协议解决这些缺点,它是一种全双工、双向、单套接字的连接,建立在tcp协议之上,当websocket连接建立后,服务器和客户端可以双向通信,具有以下特点:

1)建立在TCP协议之上,服务端的实现比较容易;

2)于HTTP协议有着良好的兼容性,默认的端口也是80和443,并且握手阶段采用HTTP协议;

3)数据格式轻量,性能开销小,通信高效;

4)可以发送文本,也可以发送二进制数据;

5)没有同源限制


http请求响应图解:

客户端发送请求,服务器响应,至此一次请求响应结束,再次获取服务端最新数据,需要再次重复上述过程;

websocket图解:

黄色部分是握手阶段,客户端给服务端发送请求,该请求基于http协议,服务器返回101状态码,代表成功建立连接,随后客户端和服务器可以开始全双工数据交互,且服务器可以主动推送消息给浏览器,下面是websocket的请求报文:

使用websocket请求行的路径是以ws开头,代表使用的是websocket协议

请求头Connection:Upgrade代表当前服务器这是一个升级的链接

请求头Upgrade:websocket代表需要将当前的链接升级为websocket链接

请求头Sec-WebSocket-Key: JnoOq+qL9WP3um80g1Sz3A==是客户端使用base64编码的24位随机字符序列,用户服务器标识当链接的客户端,同时要求服务器响应一个同样加密的Sec-WebSocket-Accept头作为应答;


websocket响应报文如下:

服务器响应101状态码代表websocket链接建立成功

响应头Sec-WebSocket-Accept: Eu6A8ipjouG1LVFt6xFMSrPFk1E=是对客户端请求头Sec-WebSocket-Key的应答,用于给客户端标识当前的服务器


客户端websocket实现

websocket是HTML5的新特性之一,首先你的浏览器必须支持websocket

创建WebSocket实例

const ws = new WebSocket('ws:localhost:8000');

参数url:ws://ip地址:端口号/资源名

WebSocket对象包含以下事件

open:连接建立时触发

message:客户端接收服务端数据时触发

error:通信发生错误时触发

close:连接关闭时触发

WebSocket对象常用方法

send():使用连接给服务端发送数据

客户端websocket代码模板:

;((doc,WebSocket) => {    const msg = doc.querySelector('#msg');  // 获取输入框,需要发送的消息    const send = doc.querySelector('#send');  // 发送按钮    // 创建websocket实例    const ws = new WebSocket('ws:localhost:8000');        // 初始化    const init = () => {        bindEvent();    }        // 绑定事件    function bindEvent () {        send.addEventListener('click',handleSendBtnClick,false);        ws.addEventListener('open',handleOpen,false);        ws.addEventListener('close',handleClose,false);        ws.addEventListener('error',handleError,false);        ws.addEventListener('message',handleMessage,false);    }    function handleSendBtnClick () {        const message = msg.value;                // 将数据发送给服务器        ws.send(JSON.stringify({            message:message        }));        msg.value = '';    }    function handleOpen () {        console.log('open');        // 当连接建立时,一般做一些页面初始化操作    }        function handleClose () {        console.log('close');        // 当连接关闭时    }    function handleError () {        console.log('error');        // 当连接出现异常时    }    function handleMessage (e) {        // 在这里获取后端广播的数据,数据通过事件对象e活得,数据存放在e.data中        const showMsg = jsON.parse(e.data);    }    init();})(document,WebSocket)

由此可见,使用原生websocket完全可以进行聊天通信,但是它提供的事件和api有限,对于一些复杂的需求实现起来比较困难,socket.io是一个websocket库,它对于websocket进行了很好的封装,提供了许多api,以及自定义事件,使用起来比较灵活。


聊天功能的前后端交互顺序图

需要实现的是客户端A发送消息给客户端B,客户端B能够自动接收并显示,实现私聊的关键是要确定需要将消息发送给谁,所以在进入聊天界面的的时候,每一个连接服务器的客户端就需要将自己的id告诉服务器,服务器会维护一个对象专门用于存放当前已连接的用户id

客户端A进入聊天界面的的时候,还需要存放客户端B的用户id,在发送消息的时候将客户端B的id传递给服务器,让服务器知道当前的这条消息要发送给谁,服务器收到后就会查询存放用户id的对象,如果客户端B连接那么就将A的消息发送给它,这就是私聊的大致思路。

建立连接

能够实现客户端之间的通信首先需要将客户端与服务器建立连接,首先下载依赖,客户端使用weapp.socket.io,服务端使用socket.io

npm i socket.io@2.3.0 --savenpm i express@4.17.1 --savenpm i weapp.socket.io@2.1.0 --save

为了保证能连接正常,建议下载指定版本,前后端版本不匹配会导致连接失败报错。

官方文档英文:Socket.IO

W3Cschool中文文档:socket.io官方文档_w3cschool

客户端:

客户端下载完毕后,可以将weapp.socket.io.js文件单独拿出,其存放的文件位置如下图

将其放在项目指定文件夹下引入,这里放在socket文件下;随后在项目的main.js中引入使用,这里将io挂载在Vue的原型上,供全局使用,连接地址为服务器的地址,端口号需与服务器socket.io监听的端口保持一致;

import io from './socket/weapp.socket.io.js'Vue.prototype.socket = io('http://localhost:8000');

服务器:

服务器使用node的express框架搭建,在入口js中配置如下,io.on用于绑定事件,connection事件在连接时触发,它是socket.io内置事件之一。

const express = require('express');const app = express();let server = app.listen(8000);let io = require('socket.io').listen(server);io.on('connection',(socket) => {       console.log("socket.io连接成功");});

socket.io建立连接会产生跨域问题,这里直接通过express的方式使用CORS解决跨域:

app.all('*', function(req, res, next) {  res.header("Access-Control-Allow-Origin", "*");  res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");  res.header("X-Powered-By",' 3.2.1')  if(req.method=="OPTIONS") res.send(200);  else  next();});

当然socket.io也提供了跨域的解决方案,具体可见 Handling CORS | Socket.IO

完成以上配置后,启动项目,客户端便可使用socket.io与服务器正常连接。

观察浏览器network选项卡,请求类型为websocket,响应状态码101,可见socket.io的连接底层走的就是websocket协议

存储连接的用户

用户登陆成功跳转到index主页,每一位用户在注册时都会在数据库生成一个唯一的用户id,这里需要将每一个连接成功的用户id发送给服务器

       =>     

socket.io服务端除了connection(socket连接成功之后触发),message(客户端通过socket.send来传送消息时触发此事件),disconneting(socket失去连接时触发,包括关闭浏览器,主动断开,掉线等任何断开连接的情况) 等内置的默认事件外,还可以使用自定义事件,客户端也类似。

API上,使用emit()触发事件,使用on()绑定事件,进入首页后在客户端onLoad中触发自定义事件login,同时从本地存储中取出用户uid,上传服务器

export default {data() {return {uid:'',  // 当前用户id},    onLoad() {this.getStroage();        this.addUserToSocket(this.uid);    },    methods:{        // 获取本地存储        getStroage(){const value = uni.getStorageSync('user');if(value){    this.uid = value.id;} else {uni.navigateTo({ url:'/pages/login/login'})}    },        // 添加连接的用户        addUserToSocket(uid){    this.socket.emit('login',uid);},    }}

在服务端绑定login事件,同时创建对象connectedUsers存放连接的用户, 将用户uid作为key保存,value是socket.id,socket.id是connection回调参数的一个属性,socket.id用于socket.io唯一标识连接的用户

当用户退出应用时触发disconnecting事件,将此用户信息从connectedUsers对象中删除。

let connectedUsers = {}; io.on('connection',(socket) => {           console.log("socket.io连接成功");    // console.log(socket);    // 用户进入主页时获取用户id保存    socket.on('login',(id) => {        console.log("socket.id:" + socket.id);        socket.name = id;        connectedUsers [id] = socket.id;    });    // 用户离开    socket.on('disconnecting',() => {        console.log('leave:' + socket.id);        if(users.hasOwnProperty(socket.name)){            delete connectedUsers [socket.name];        }    });});

总结

1)io.on可用来给当前socket连接绑定connection事件,参数socket可以获取这次连接的配置信息,最常用的就是socket.id,它是本次连接的唯一标识

io.on('connection',function(socket){ ...... })

2)on用于绑定事件,用于接收传递的数据

socket.on('自定义事件名',function(参数1,参数2,......,参数n) { ...... });

3)emit用于触发事件,用于传递数据

socket.emit('自定义事件名',参数1,参数2,......,参数n);

4)disconnecting在失去连接时时触发,断开可能是关闭浏览器,主动断开,掉线等导致

socket.on('disconnecting',() => {})

发送聊天信息 

客户端发送消息,将聊天内容加工处理后,触发自定义事件msg,将内容,发送者id和接收者id发送给服务器,代码如下:

客户端chatroom.vue:

// 发送聊天数据sendSocket(msg){if(this.type === '0'){// 1对1聊天this.socket.emit('msg',msg,this.uid,this.fid);} else {// 群消息this.socket.emit('gmsg',msg,this.uid,this.fid);}},

服务器绑定msg事件,得到客户端发来数据,首先需要操作数据库完成插入最新的聊天内容,更改最后的通讯时间等操作,如果对方用户在线,则connectedUsers 对象中必然存在该用户的id,使用socket.to(指定接收者的socket.io)将消息发送给指定的用户,同时触发自定义事件backMsg,用法如下:

发送给指定 socketid 的客户端(私密消息)

socket.to().emit('自定义事件名', 参数);

注意:如果不使用socket.to方法直接调用emit,则会发送给所有在线的用户。 

服务器代码:

// 引入数据库文件let dataBase= require("./dataBase");// 1对1消息发送socket.on('msg',(msg,fromId,toId) => {    console.log('服务器收到用户' + fromId + '发送给' + toId + '的消息')    console.log('发送的消息是:',msg);    // 修改好友最后通讯时间    dataBase.updateLastMsgTime(fromId,toId);    dataBase.updateLastMsgTime(toId,fromId);    // 添加消息    dataBase.insertMsg(fromId,toId,msg.message,msg.types);    console.log('数据库插入成功');        // 将获取的消息发送给好友,users[toId]就是好友的socket.id    if(connectedUsers[toId]){        console.log('将消息发送给',toId,'成功');        socket.to(connectedUsers[toId]).emit('backMsg',msg,fromId,0);    }   });

这样客户端绑定backMsg事件,就能拿到发送消息了!处理消息展示即可,但需要判断当前用户此时打开的聊天界面是否就是当前发送者聊天对话框即if(fromId === this.fid && type === 0),否则会造成聊天内容的错误展示,比如当前用户可能存在多个好友,客户端A给客户端B发消息时B打开的是和C的聊天对话框,此时就会在C的对话框中错误的收到A发来的消息

客户端chatroom.vue:

this.socket.on('backMsg',(msg,fromId,type) => {// 如果是1对1消息fromId是当前聊天窗口的好友id时执行if(fromId === this.fid && type === 0){......// 一条聊天记录let newMsg = {fromId:fromId,id:msg.id,imgUrl:msg.imgUrl,message:msg.message,types:msg.types,  // 0 - 文字信息,1 - 图片信息, 2 - 音频time:new Date(),isFirstPlay:true,};this.msg.push(newMsg);  // 如果消息是图片if(msg.types === '1') {this.msgImage.push(msg.message)}this.$nextTick(function(){this.scrollToView = 'msg' + this.msg[this.msg.length - 1].id;});......}});

测试效果如下: 

 

服务器终端输出结果如下:

首页新消息提示

如下图,用户有新消息会在首页及时显示,并提示未读消息数量

 

需要给首页绑定获取消息的自定义事件backMsg,绑定时机是在生命周期onLoad中,事件一旦触发代表有好友向你发送消息了,会获取服务器传来的消息,在事件回调中要完成两个操作,首先查找发来新消息的好友在首页好友列表数组索引下标,随后修改指定的数组元素内容,更新这个好友最后消息的时间、最后消息的内容、未读消息数;并将该元素现有位置删除,添加到整个数组的头部,即把这个好友item放到首页列表的最上方,首页index.vue相关代码如下:

                    {{item.unreadMsg}}                {{item.nickName}}{{getTime(item.lastTime)}}                {{item.lastMsgUsername ? item.lastMsgUsername : ''}}{{item.lastMsg}}{{item.lastMsgUsername ? item.lastMsgUsername : ''}}[图片]{{item.lastMsgUsername ? item.lastMsgUsername : ''}}[语音]{{item.lastMsgUsername ? item.lastMsgUsername : ''}}[位置]......onLoad() {    this.receiveSocket('backMsg');}methods:{    // 接收个人/群聊天信息    receiveSocket(eventName){    this.socket.on(eventName,(msg,fromId,type) => {    if(type === 0){    let index;    if(eventName == 'backMsg') {                    // 获取有新消息的好友在整个好友数组中的索引下标    index = this.friends.findIndex((item) => {    return item.id === fromId    });    }    // 修改未读消息数     this.getUnreadMsg(this.friends[index]);                // 修改最后聊天时间    this.friends[index].lastTime = msg.time;                // 修改最后聊天信息    this.friends[index].lastMsg = msg.message;                // 修改最后聊天信息的类型    this.friends[index].lastMsgType = msg.types;    // 删除当前item,将其插入到数组的首部,即展示在列表最上方    const tempItem = this.friends[index];    this.friends.splice(index,1);    this.friends.unshift(tempItem);    }    });    },}

此外还有一个问题就是何时清空未读消息数,清空的操作需要进行两次,一次是用户进入聊天页面时进行清空,在聊天页生命周期onLoad中调用清空消息数的后端接口,清空现有的未读消息;另一次是在点击返回按钮如下图,返回首页时清空,在此按钮事件的回调中调用清空未读消息数的接口,这是为了清空用户和他人聊天时已读的消息,两次操作缺一不可。

实现群聊

群聊的前后端顺序图如下所示:

需要实现的是客户端A在群内发送了消息后,在同一群内的客户端BCD都能同时收到A发送的消息。群聊的大致思路和私聊基本相似,不同点在于群聊中引入了房间的概念,在房间内的成员就是这个群聊的群成员,任何群成员的群内发言就会在这个房间内进行广播所有在线的群成员都能及时够收到。

加入房间

使用socket.join()加入房间,具体使用如下:

socket.join('room',function(){ ...... });

room:房间id,是一个字符串,用户自定义,加入房间会触发参数二回调

socket.leave(room,function(){ ...... })

与join相对应的是leave方法,即退出指定的房间,参数二异常回调函数为可选值。需要注意的是,当与客户端断开连接时,会自动将其从加入的房间中移除

在这个项目里房间id使用的是每一个群聊的群id号,它可以唯一标识一个群聊;

加入房间的操作同样是在用户登录成功进入首页时进行,一个用户可能加入了多个群聊,那么在主页请求用户群聊接口后,需要依次遍历接口返回的群聊列表,为每一个群聊触发addGroup事件,将当前的群id发送给后端,让当前用户加入每个群聊的房间。

index.vue

// 获取当前用户的群消息getGroup(){uni.request({url:`${this.baseUrl}/index/getGroupList`,method:'POST',data:{uid:this.uid,  // 用户id},success: (res) => {let data = res.data.result;            // 遍历当前用户的群列表for (var i = 0; i < data.length; i++) {......                // 触发addGroup事件,携带群id,加入房间this.socket.emit('addGroup',data[i].id);}                        ......}});},

 服务器绑定addGroup事件,调用socket.join,让当前用户连接加入房间号为groupId的房间

io.on('connection',(socket) => {     // 加入群    socket.on('addGroup',(groupId) => {        console.log('用户',socket.id,'加入了groupId为',groupId,'的群聊');        socket.join(groupId);    });}

效果:例如当前这个用户加入了三个群聊,首页加载后就会触发addGroup三次,依次加入这三个群id标识的房间。

服务器终端输出效果如下:

发送群消息

某一群成员在群内发送消息,会和私聊同样的方式将语音和图片这些静态资源上传服务器,返回服务器存放地址后进行封装,触发gmsg事件将处理后的消息提交服务器

// 发送聊天数据sendSocket(msg){if(this.type === '0'){// 1对1聊天this.socket.emit('msg',msg,this.uid,this.fid);} else {// 群消息this.socket.emit('gmsg',msg,this.uid,this.fid);}},

群内广播消息使用到的api是socket.to,具体使用如下:

将内容发送给同在房间名roomName的所有客户端,除了发送者

socket.to(roomName).emit('事件名',参数1,参数2,......参数n);

如果需要包含发送者可以使用

io.in(roomName).emit('事件名',参数1,参数2,......参数n);

也可以同时发送给在多间房间的客户端,使用to链式调用的形式,不包含发送者

socket.to(roomName1).to(roomName2).emit('事件名',参数1,参数2,......参数n);

当然,当前项目中只需要使用第一种方式即可

服务器的gmsg事件回调中,同样需要将获取到的消息插入数据库,同时修改群最后通信时间以及全体成员的未读消息数,最后调用 socket.to方法,触发groupMsg事件,将消息发送给群聊内的其它在线用户。

// 引入数据库文件let dataBase = require("./dataBase");// 接收群消息socket.on('gmsg',(msg,fromId,groupId) => {    console.log('服务器接收到来自群',groupId,'的用户',fromId,'的消息',msg);    // 修改群的最后通信时间    dataBase.updateGroupLastTime(groupId);    // 添加群消息    dataBase.insertGroupMsg(fromId,groupId,msg.message,msg.types);    //将所有成员的未读消息数加一    dataBase.changeGroupUnreadMsgNum(groupId);    console.log('消息',msg.message,'插入数据库成功')    // 获取当前用户的名字和头像    dataBase.userDetails(fromId).then((data) => {        console.log('查询发送者用户名成功,用户名是:',data[0]);        console.log('正在将信息',msg.message,'发送至群',groupId,'内');        // 群内广播消息        socket.to(groupId).emit('groupMsg',msg,fromId,0,data[0].name,groupId);    });});

客户端在线群成员收到消息,执行groupMsg事件回调中的方法,内部大致逻辑和私聊完全一致,可以将其封装成公共方法使用,需要注意的依旧是要做群id一致性判断,防止获取的消息显示在其它聊天窗口中,即 if(fromId !== this.uid && groupId === this.fid)。

this.socket.on('groupMsg',(msg,fromId,type,friendName,groupId) => {// 判断当前打开的群id和接收消息的群id是否一致,防止消息错误显示if(fromId !== this.uid && groupId === this.fid){......// 模拟服务器数据let newMsg = {fromId:fromId,id:msg.id,imgUrl:msg.imgUrl,message:msg.message,types:msg.types,  // 0 - 文字信息,1 - 图片信息, 2 - 音频time:new Date(),isFirstPlay:true,friendName:friendName   // 群需显示发送消息用户的名字};this.msg.push(newMsg);// 如果消息是图片if(msg.types === '1') {this.msgImage.push(msg.message)}this.$nextTick(function(){this.scrollToView = 'msg' + this.msg[this.msg.length - 1].id;});......}});

效果演示:输入一段文字发送到群内

服务器此时终端输出如下

以上就是项目聊天功能难点的全部内容,前端实现实时聊天主要就是对于socket.io提供api的合理使用,剩余的难点就是页面显示的部分逻辑处理,用户体验的优化,还可以在此基础上添加更多的功能,若有不足之处恳请指正!

来源地址:https://blog.csdn.net/weixin_43655896/article/details/123588670

--结束END--

本文标题: 【uni-app】小程序实现微信在线聊天(私聊/群聊)

本文链接: https://www.lsjlt.com/news/391801.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【uni-app】小程序实现微信在线聊天(私聊/群聊)
    之前学习使用uni-app简单实现一个在线聊天的功能,今天记录一下项目核心功能的实现过程。页面UI以及功能逻辑全部来源于微信,即时聊天业务的实现使用socket.io,前端使用uni-app开发,后端服务器基于node实现,数据库选择mon...
    99+
    2023-09-03
    uni-app 前端 小程序
  • uni-app小程序实现微信在线聊天功能(私聊/群聊)
    目录聊天信息列表的渲染聊天信息发送的相关问题实现一对一聊天关于websocket建立连接存储连接的用户发送聊天信息 首页新消息提示实现群聊加入房间发送群消息之前学习使用un...
    99+
    2023-02-18
    uni-app小程序微信聊天 uni-app微信小程序聊天
  • 【uni-app】uni-app实现聊天页面功能(小程序)——布局篇
    文章目录 前言划分区域问题内容溢出关于调试聊天框 代码实现 前言 在工作中使用uni-app参与开发一个小程序,其中要写一个简单的聊天页面,虽然功能不多(只有一个发送文字的功能),但是其中的细节比较多,也踩过很多坑,...
    99+
    2023-08-16
    uni-app 小程序 前端 vue.js
  • 微信小程序实现聊天室功能
    本文通过实例为大家分享了微信小程序实现聊天室的具体代码,供大家参考,具体内容如下 1.实现效果展示 2.room.wxml <view class="container"...
    99+
    2022-11-12
  • 微信小程序实现简单聊天室
    本文实例为大家分享了微信小程序实现简单聊天室的具体代码,供大家参考,具体内容如下 cha.js // pages/chat/chat.js // 获取小程序实例 let app ...
    99+
    2022-11-12
  • 微信小程序中如何实现聊天室
    小编给大家分享一下微信小程序中如何实现聊天室,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!微信小程序中如何实现聊天室utils文...
    99+
    2022-10-19
  • 微信小程序怎么实现仿微信聊天界面
    本篇内容介绍了“微信小程序怎么实现仿微信聊天界面”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!仿微信聊天界面,数据来自mock数据,支持聊天...
    99+
    2023-06-26
  • 【微信开发】微信小程序实现实时聊天功能
    最近在做一个项目,需要运用到实时聊天功能,分享一下。      分为: 界面如何布局以及细节; 如何实现实时更新; 全部代码展示;         一、界面如何布局以及细节:         1.说到底,聊天界面就是循环一个数组,每一行...
    99+
    2023-09-02
    微信小程序 小程序
  • 微信小程序如何实现简单聊天室
    这篇文章主要介绍了微信小程序如何实现简单聊天室的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇微信小程序如何实现简单聊天室文章都会有所收获,下面我们一起来看看吧。cha.js// pages/chat/...
    99+
    2023-06-08
  • C++ SOCKET多线程实现聊天小程序
    本文实例为大家分享了C++ SOCKET多线程实现聊天小程序的具体代码,供大家参考,具体内容如下 TCP/IP协议与SOCKET 什么是网络协议? 计算机网络中,各个实体之间的数据交...
    99+
    2022-11-12
  • 微信小程序 | 基于小程序+Java+WebSocket实现实时聊天功能
    一、文章前言 此文主要实现在小程序内聊天对话功能,使用Java作为后端语言进行支持,界面友好,开发简单。 二、开发流程及工具准备 2.1、注册微信公众平台账号。 2.2、下载安装Inte...
    99+
    2023-09-06
    小程序 微信小程序 java
  • C++ SOCKET多线程怎么实现聊天小程序
    本篇内容介绍了“C++ SOCKET多线程怎么实现聊天小程序”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!TCP/IP协议与SOCKET什么...
    99+
    2023-06-08
  • 如何用PHP实现微信小程序的实时聊天功能?
    如何用PHP实现微信小程序的实时聊天功能?随着移动互联网的发展,微信小程序成为了很多开发者的首选平台。而实时聊天功能作为一种关键的社交功能,很多用户都希望在自己的小程序中实现。本文将介绍如何使用PHP来实现微信小程序的实时聊天功能,并提供具...
    99+
    2023-10-27
    PHP 微信小程序 实时聊天
  • C++ SOCKET多线程实现聊天小程序的方法
    本篇内容主要讲解“C++ SOCKET多线程实现聊天小程序的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++ SOCKET多线程实现聊天小程序的方法”吧!本文实例为大家分享了C++ SO...
    99+
    2023-06-20
  • 微信小程序如何实现实时聊天并支持图片预览
    这篇文章给大家分享的是有关微信小程序如何实现实时聊天并支持图片预览的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先看一下界面,界面很简单,就是首页刚进来获取了用户信息头像,昵称...
    99+
    2022-10-19
  • 微信小程序使用stomp.js实现STOMP传输协议的实时聊天
    简介: uniapp开发的小程序中使用 本来使用websocket,后端同事使用了stomp协议,导致前端也需要对应修改。 如何使用 在static/js中新建stomp.js和websocket.js,然后在需要使用的页面引入监听代码+...
    99+
    2023-08-30
    微信小程序 小程序 stomp websocket IM 即时通信
  • 如何利用微信小程序和php实现即时通讯聊天功能
    目录一、PHP7安装Swoole扩展1、自定义安装2、宝塔面板安装PHP swoole扩展二、配置nginx反向代理三、微信小程序socket合法域名配置四、效果演示和代码1、小程序...
    99+
    2022-11-13
  • Python使用django框架实现多人在线匿名聊天的小程序
    最近看到好多设计类网站,都提供了多人在线匿名聊天的小功能,感觉很有意思,于是基于python的django框架自己写了一个,支持手动实时更名,最下方提供了完整的源码. 在线聊天地址(无需登录,开一个窗口,...
    99+
    2022-06-04
    在线 框架 程序
  • 使用chatgpt实现微信聊天小程序(秒回复),github开源(附带链接)
    文章目录 前言效果展示原理说明服务器端代码说明微信小程序代码说明代码链接总结更新日志2023/5/13 14:42更新 前言 我在前一段时间突发奇想,就使用java来调用chatgpt的接口,然后写了一个简单小程序,也上了热...
    99+
    2023-08-30
    小程序 chatgpt java 微信小程序 spring boot
  • 怎么在android中利用Socket实现一个聊天小程序
    本篇文章为大家展示了怎么在android中利用Socket实现一个聊天小程序,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。具体内容如下服务器端:package org.hwq.echo; impo...
    99+
    2023-05-31
    android socket roi
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作