uniapp+websocket聊天功能实现(超详细!!附代码,可直接复用)

这篇具有很好参考价值的文章主要介绍了uniapp+websocket聊天功能实现(超详细!!附代码,可直接复用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近项目上用到了聊天的功能,下面来分享一下关于websocket,键盘弹出等问题,避免别的朋友踩坑。

先给大家看看效果图 

uniapp websocket聊天,uniapp,uni-app

 接着进入正文了!!!!!

一、需要注意的几个点

1.scroll-view的高度

先看看整体的页面布局

uniapp websocket聊天,uniapp,uni-app

 system.windowHeight : 页面总高度

totalHeight:顶部导航栏高度

sendHeight:底部输入框高度 (设置样式的时候自己设置的)

keyboardHeight:键盘高度(键盘没有弹出的时候为0)

	            uni.getSystemInfo({
					success: res => {
						this.system = res
					}
				})

				// #ifdef MP-WEIXIN
				//获取胶囊信息
				this.menu = uni.getMenuButtonBoundingClientRect()

				//计算组件高度
				this.statusBarHeight = this.system.statusBarHeight //状态栏高度
				this.navigatorHeight = (this.menu.top - this.system.statusBarHeight) * 2 + this.menu.height //导航栏高度
				this.totalHeight = this.statusBarHeight + this.navigatorHeight //总高度
				// 保存到全局
				this.$store.state.totalHeight = this.totalHeight
				this.$store.state.system = this.system
				// #endif

				// #ifdef APP
				this.statusBarHeight = this.system.statusBarHeight //状态栏高度
				this.navigatorHeight = this.system.statusBarHeight + 45 //导航栏高度
				this.totalHeight = this.navigatorHeight //总高度
				// 保存到全局
				this.$store.state.totalHeight = this.totalHeight
				this.$store.state.system = this.system

				// #endif

这里需要注意的是scroll-view没有高度就和view差不多,scroll-into-view属性就不生效。

2.键盘弹起时,使页面向上移动,顶部导航栏不动

使用textarea原生的键盘弹起时,页面向上移是这样的

uniapp websocket聊天,uniapp,uni-app

 解决后的图片:

uniapp websocket聊天,uniapp,uni-app

 是不是看着顺眼多了

首先的话需要在页面加载的时候监听一下键盘的高度

		listenerKeyboardHeight() {
			this.listener = (res) => {
				console.log("键盘高度", res.height)
				this.keyboardHeight = res.height
				this.$nextTick(() => {
					this.scrollToBottom()
				})
			}
			uni.onKeyboardHeightChange(this.listener)
		}

当键盘弹出的时候,将scroll-view的高度减去键盘高度,底部发送框向上移动‘键盘高度’的px

底部的发送框一般都是position: fixed;来定位的,将bottom属性变一下就行了

		<view class="information-box lky-flex-items-center" :style="{bottom: bottom+'px'}">
			<view style="margin-right: 20rpx; width: 100%">
				<u--textarea :confirmType="null" v-model="value" placeholder="请输入" height="40rpx" :showConfirmBar="false"
					:placeholderStyle="placeholderStyle" @focus="textfocus" :adjustPosition="false" />
			</view>
			<image src="@/static/images/chat/icon_attachment.svg" class="icon" v-if="isUploadFile" @click="openFile" />
			<image src="@/static/images/chat/icon_send.svg" class="icon" @click="send" />
		</view>

3.定位到底部

先再来看看我们的页面布局

uniapp websocket聊天,uniapp,uni-app

最后一条是用于定位到底部的

<!-- 用于定位到底部 -->
<view id="last-msg-item" style="height: 1px;"></view>

方法:

		// 定位到底部
		scrollToBottom() {
			this.$nextTick(() => {
				this.scrollIntoView = "last-msg-item"
                // 清空,为下一次定位做准备
				this.$nextTick(() => {
					this.scrollIntoView = ""
				})
			})
		},

二、websocket代码

这是封装的一个mixin类

import {
	socket
} from "@/common/mixin/socket.js"

//引入方法
export default {
    mixins: [socket],
}

socket.js

export const socket = {
	data() {
		return {
			// socket是否开启
			socketOpen: false,
			// 定时器
			timer: null,

			// 链接
			surl: `websocket链接`,

			// 底部id用于定位到底部
			scrollIntoView: "",

			// 键盘高度
			keyboardHeight: 0,

			// 监听键盘高度的方法
			listener: null
		}
	},

	onLoad(option) {
		// 开启键盘高度监听
		this.listenerKeyboardHeight()

		// socket初始化
		this.init()

		// 定时器,定时判断socket有没有掉线
		this.timer = setInterval(() => {
			this.isSocketConnct()
		}, 2000)

	},
	beforeDestroy() {
		// 关闭定时器
		clearInterval(this.timer)

		// 关闭键盘高度监听
		uni.offKeyboardHeightChange(this.listener)

		// 关闭Socket
		this.closeSocket()
	},
	methods: {
		// 发送消息
		sendSocketMessage(msg) {
			console.log("发送消息", msg);
			let that = this
			if (this.socketOpen) {
				uni.sendSocketMessage({
					data: msg,
					success: (res) => {
						setTimeout(() => {
                            // json转对象
							let param = JSON.parse(msg)
							that.sendMessageHandle(param)
						}, 300)
					},
					fail(err) {
						// 发送失败处理
					}
				});
			} else {
				// Socket没有开启,重新连接并重新发送消息
				this.init()
				setTimeout(() => {
					this.sendSocketMessage(msg)
				},300)
			}
		},

		// 判断是否连接
		isSocketConnct() {
			if (!this.socketOpen) {
				console.log("WebSocket 再次连接!");
				this.init()
			}
		},

		// 初始化
		init() {
			this.connect()
			this.openSocket()
			this.onclose()
			this.onSocketMessage()
		},

		// 建立连接
		connect() {
			console.log(this.surl);
			uni.connectSocket({
				url: this.surl,
				method: 'GET'
			});
		},

		// 监听关闭
		onclose() {
			let that = this
			uni.onSocketClose((res) => {
				that.socketOpen = false
				console.log('WebSocket 已关闭!');
			});
		},

		// 关闭
		closeSocket() {
			uni.closeSocket();
		},

		// 打开Soceket
		openSocket() {
			let that = this
			uni.onSocketOpen((res) => {
				that.socketOpen = true
				console.log('WebSocket连接已打开!');
			});
		},

		// 接收事件
		onSocketMessage() {
			let that = this
			uni.onSocketMessage((res) => {
				let obj = JSON.parse(res.data)
				console.log("接收事件", obj);
				this.onMessageHandle(obj)
			});
		},

		// 接收到事件后处理的方法(可自己重写)
		onMessageHandle(obj) {
			// 根据自己业务逻辑重写
		},

		// 发送消息后处理的方法(可自己重写)
		sendMessageHandle(msg) {
			// 根据自己业务逻辑重写
		},


		// 定位到底部
		scrollToBottom() {
			this.$nextTick(() => {
				this.scrollIntoView = "last-msg-item"
				this.$nextTick(() => {
					this.scrollIntoView = ""
				})
			})
		},

        // 开启键盘高度的监听
		listenerKeyboardHeight() {
			this.listener = (res) => {
				console.log("键盘高度", res.height)
				this.keyboardHeight = res.height
				this.$nextTick(() => {
					this.scrollToBottom()
				})
			}
			uni.onKeyboardHeightChange(this.listener)
		}
	}

}

直接引入就可以使用啦 , 接下来说说几个可能用到的方法,在自己的页面直接用就可以啦文章来源地址https://www.toymoban.com/news/detail-720077.html

	// 发送消息方法
	send(value) {
        // 自定义消息体
		let param = {
			"type": 1,
			"content": value,
	   	}

        // 对象转json
		let m = JSON.stringify(param)
		this.sendSocketMessage(m)
	},
			// 接收到事件后处理的方法(可自己重写)
			onMessageHandle(obj) {   
                // obj 接收到的事件对象
			},

			// 发送消息后处理的方法(可自己重写)
			sendMessageHandle(msg) {
				// msg 发送的消息对象
			}

三、页面布局代码

<template>
	<view>
        <!-- 自定义顶部导航栏 用原生的话下面scroll-view应该可以不用减去导航栏的高度的-->
		<u-navbar :placeholder='true' :autoBack='true' leftIconSize='40rpx'>
			<view class="navbar-title" slot="center">{{navbarTitle}}</view>
		</u-navbar>

		<scroll-view 
            scroll-y="true" 
            class="content-box" id="chat"
			:style="{'height':system.windowHeight - totalHeight - sendHeight - keyboardHeight+'px' }"
			:scroll-into-view='scrollIntoView'>
			<lky-gap size='40' />
			<view id="msglistview"></view>
			<view id="last-msg-item" style="height: 1px;"></view>
		</scroll-view>

		<lky-send 
            @send="send" 
            :is-upload-file="false" 
            @imageSend="imageSend" 
            @fileSend="fileSend"
			:bottom-copy='keyboardHeight'></lky-send>
	</view>
</template>

<script>

	import {
		mapState
	} from 'vuex'

	import {
		socket
	} from "@/common/mixin/socket.js"


	import LkySend from "../component/lky-p-send/lky-p-send.vue"

	export default {
		components: {
		},
		mixins: [socket],
		data() {
			return {
				src: '',
                
                // 聊天记录列表
				messageList: [],

                // socket链接,如果在socket.js中改了的话就不用写这个了
				surl: ``,

			};
		},
        
        //  我的高度存在vuex的
		computed: mapState([
			"totalHeight", "system", "sendHeight"
		]),

		onLoad(option) {
			// 获取聊天记录
			this.messageList = uni.getStorageSync(`messageList_${this.$store.state.userInfo.id}`) || []
			console.log("缓存中的聊天记录", this.messageList);
			this.scrollToBottom()
		},

		methods: {

			send(value) {
				let param = {
					"type": 1,
					"content": value,
				}
				let m = JSON.stringify(param)
				this.sendSocketMessage(m)
			},


            // 预览图片
			imageClick(url) {
				uni.previewImage({
					urls: [
						url
					]
				})
			},

            // 发送图片
			imageSend(url) {
				let param = {
					"type": 3,
					"text": "",
					"url": url,
					"userId": this.$store.state.userInfo.id
				}
				let m = JSON.stringify(param)
				this.sendSocketMessage(m)
			},

            // 发送文件
			fileSend(url, name) {
				let param = {
					"type": 4,
					"text": name,
					"url": url,
					"userId": this.$store.state.userInfo.id
				}
				let m = JSON.stringify(param)
				this.sendSocketMessage(m)
			},
            
            // 打开文件
			openFile(item) {
				uni.downloadFile({
					url: item.url,
					success: (res) => {
						var filePath = res.tempFilePath;
						uni.openDocument({
							filePath: filePath,
							showMenu: true,
							success: function(res) {}
						});
					}
				});
			},

			// 接收到事件后处理的方法(可自己重写)
			onMessageHandle(obj) {
                //根据业务逻辑重写
                // obj接收到的事件

			},

			// 发送消息后处理的方法(可自己重写)
			sendMessageHandle(msg) {
				 //根据业务逻辑重写
                // msg 发送的消息
			},
		}
	}
</script>

<style lang="scss">
	body {
		box-sizing: border-box;
		padding: 0 ;
		background-color: $lky-hui-bg ;
	}
</style>

<style lang="scss" scoped>

	.content-box {
		padding: 0 28rpx;
		box-sizing: border-box;
		height: auto;
		z-index: -1;
		overflow: hidden;
	}
</style>

到这里一个聊天的功能就结束了 ,这应该已经很详细了,其余的自己根据自己的业务逻辑和ui进行调整就行了!

最后有什么不足的地方也请各位指正优化一下

结束!

到了这里,关于uniapp+websocket聊天功能实现(超详细!!附代码,可直接复用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot集成WebSocket实现及时通讯聊天功能!!!

    注意:   至此,后端代码就集成完了,集成完之后,记得重启你的Springboot项目 前端Vue 1:新建Vue 页面  路由: 代码:路由根据你项目的实际情况写 在用户登录的时候,需要将你的用户名存储到本地Session 中  效果图:  用户甲:   用户乙:   注:网上学习来源 SpringBoot集

    2024年02月01日
    浏览(33)
  • 蓝牙聊天App设计3:Android Studio制作蓝牙聊天通讯软件(完结,蓝牙连接聊天,结合生活情景进行蓝牙通信的通俗讲解,以及代码功能实现,内容详细,讲解通俗易懂)

    前言:蓝牙聊天App设计全部有三篇文章(一、UI界面设计,二、蓝牙搜索配对连接实现,三、蓝牙连接聊天),这篇文章是:三、蓝牙连接聊天。 课程1:Android Studio小白安装教程,以及第一个Android项目案例“Hello World”的调试运行 课程2:蓝牙聊天App设计1:Android Studio制作蓝

    2024年02月12日
    浏览(27)
  • Ratchet实现PHP WebSocket多人聊天功能的示例

       composer 安装ratchet 使用PDO连接数据库,创建mysql命令如下 使用Redis存储消息列表 这个示例代码中,PHP代码使用Ratchet来创建WebSocket服务器,并实现了简单的聊天功能。HTML代码使用JavaScript来建立WebSocket连接,并处理消息传输和用户输入。要运行此代码,请确保已安装Ratchet并

    2024年02月11日
    浏览(30)
  • Springboot + Websocket的集成实现简单的聊天室功能

    WebSocket是一种网络通信协议,它可以在单个TCP连接上实现双向(全双工)通信。WebSocket使用HTML5标准,并且可以在客户端和服务器之间建立持久连接,这意味着连接在浏览器刷新或关闭后仍然保持打开状态。 WebSocket的主要优点包括: 1. 双向通信:WebSocket支持客户端和服务器之

    2024年03月21日
    浏览(36)
  • 微信小程序WebSocket实现stream流式聊天对话功能

    要在微信小程序实现聊天对话功能,回话是流式应答,这里使用了WebSocket技术。WebSocket大家应该都很熟悉,使用wx.connectSocket就可以了。这里可能需要注意下的是流式应答,后端如何发送,前端如何接收。直接上代码: 可以扫码体验: 后端关键代码: 小程序ts代码: 可以扫码

    2024年04月10日
    浏览(68)
  • 微信小程序 | 基于小程序+Java+WebSocket实现实时聊天功能

    此文主要实现在小程序内聊天对话功能,使用Java作为后端语言进行支持,界面友好,开发简单。 2.1、注册微信公众平台账号。 2.2、下载安装IntelliJ IDEA(后端语言开发工具),Mysql数据库,微信Web开发者工具。 1.创建maven project 先创建一个名为SpringBootDemo的项目,选择【New Proje

    2024年02月02日
    浏览(40)
  • SpringBoot和Vue2集成WebSocket,实现聊天室功能

    springboot集成websocket实现聊天室的功能。如有不足之处,还望大家斧正。

    2024年01月23日
    浏览(36)
  • thinkphp websocket 开发实时聊天系统的用户群组与订阅功能实现 (一)

    PHP开发实时聊天系统的用户群组与订阅功能实现 在当今社交互联网时代,实时聊天系统已经成为人们日常交流的重要工具。为了提供更好的用户体验,我们需要实现用户群组与订阅功能,使得用户能够方便地创建和加入群组,并且能够订阅感兴趣的内容。 本篇文章将介绍如

    2024年02月07日
    浏览(33)
  • 如何使用SpringBoot和Netty实现一个WebSocket服务器,并配合Vue前端实现聊天功能?

    本文将详细介绍如何使用SpringBoot和Netty实现一个WebSocket服务器,并配合Vue前端实现聊天功能。 WebSocket是一种基于TCP的协议,它允许客户端和服务器之间进行双向通信,而不需要像HTTP那样进行请求和响应。Netty是一个Java网络编程框架,它提供了强大的异步事件驱动网络编程能

    2024年02月16日
    浏览(31)
  • uniapp 使用组件 uni-list 实现聊天列表功能

    如何使用 uniapp 的组件实现聊天列表的功能呢,翻阅了半天文档,终于找到一个实用的方法,下面是具体的步骤  1、首先需要下载对应的插件 去uniapp的官方文档进行下载(uni-ui - DCloud 插件市场),这里直接下载插件并导入到HBuilderx 中就可以了。  2、接下来就可以直接进行使

    2024年02月09日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包