小程序模板:专业的小程序模板与静态模板分享平台
小程序
教程
搜索
当前位置 : 首页> 小程序教程> uniapp怎么使用websock实现实时聊天功能

uniapp怎么使用websock实现实时聊天功能

创建 WebSocket 混入模块

在项目的mixins目录下创建一个名为socket.js的文件,内容如下:

export const socket = {
    data() {        return {            // socket是否开启
            socketOpen: false,            // 定时器
            timer: null,            // 链接
            surl: `ws://120.55.76.143:48080/infra/ws?token=66971089117e4372847ff4f31bc538df`, // 请替换为实际的WebSocket服务器URL            // 底部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 data = {                content: {                    "fromUserId": uni.getStorageSync("userId"),                    "text": msg,                    "single": false,
                },                type: "member-message"
            }            data = JSON.stringify(data)
            let that = this            if (this.socketOpen) {
                uni.sendSocketMessage({                    data,
                    success: (res) => {
                        setTimeout(() => {                            // json转对象
                            let param = JSON.parse(data)
                            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'
            });
        },        // 打开Soceket
        openSocket() {
            let that = this
            uni.onSocketOpen((res) => {
                that.socketOpen = true
                console.log('WebSocket连接已打开!');
            });
        },        // 监听关闭
        onclose() {
            let that = this
            uni.onSocketClose((res) => {
                that.socketOpen = false
                console.log('WebSocket 已关闭!');
            });
        },        // 关闭
        closeSocket() {
            uni.closeSocket();
        },        // 接收事件
        onSocketMessage() {
            let that = this
            uni.onSocketMessage((res) => {
                let obj = JSON.parse(res.data)
                console.log("接收事件", obj);
                this.onMessageHandle(obj)
            });
        },        // 接收---到事件后处理的方法
        onMessageHandle(obj) {
            var data = JSON.parse(obj.content)
            this.list.push({
                userType: 'friend',
                avatar: this._friendAvatar,                content: data.text
            })            // 滚动到底部
            this.scrollToBottom()
        },        // 发送---消息后处理的方法
        sendMessageHandle(obj) {
            var data = obj.content
            this.list.push({
                userType: 'self',
                avatar: this._selfAvatar,                content: data.text
            })            // 滚动到底部
            this.scrollToBottom()
        },        // 定位到底部
        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)
        }
    }
}

聊天界面组件

接下来,在聊天界面中引入上面创建的混入模块,并实现聊天功能。


	.scroll-view {		/* #ifdef H5 */
		height: calc(100vh - 44px);		/* #endif */
		/* #ifndef H5 */
		height: 100vh;		/* #endif */
		background: #eee;
		box-sizing: border-box;
	}
	.message {		display: flex;
		align-items: flex-start;
		margin-bottom: 30rpx;
		
		.avatar {
			width: 80rpx;
			height: 80rpx;
			border-radius: 10rpx;
			margin-right: 30rpx;
		}
		.content {
			min-height: 80rpx;
			max-width: 60vw;
			box-sizing: border-box;
			font-size: 28rpx;
			line-height: 1.3;
			padding: 20rpx;
			border-radius: 10rpx;
			background: #fff;
			image {
				width: 200rpx;
			}
		}		&.self {
			justify-content: flex-end;
			.avatar {
				margin: 0 0 0 30rpx;
			}
			.content {
				position: relative;				&::after {
					position: absolute;					content: '';
					width: 0;
					height: 0;
					border: 16rpx solid transparent;
					border-left: 16rpx solid #fff;					right: -28rpx;					top: 24rpx;
				}
			}
		}		&.friend {
			.content {
				position: relative;				&::after {
					position: absolute;					content: '';
					width: 0;
					height: 0;
					border: 16rpx solid transparent;
					border-right: 16rpx solid #fff;					left: -28rpx;					top: 24rpx;
				}
			}
		}
	}

	.tool {
		position: fixed;
		width: 100%;
		min-height: 120rpx;		left: 0;		bottom: 0;
		background: #fff;		display: flex;
		justify-content: space-between;
		align-items: flex-start;
		box-sizing: border-box;
		padding: 20rpx 24rpx 20rpx 40rpx;
		padding-bottom: calc(20rpx + constant(safe-area-inset-bottom)/2) !important;
		padding-bottom: calc(20rpx + env(safe-area-inset-bottom)/2) !important;
		.input {
			background: #eee;
			border-radius: 10rpx;
			height: 70rpx;
			margin-right: 30rpx;
			flex: 1;
			padding: 0 20rpx;
			box-sizing: border-box;
			font-size: 28rpx;
		}		>view {
			width: 150rpx;
			line-height: 70rpx;
			text-align: center;
			height: 70rpx;
			background-color: #eee;
			border-radius: 10rpx;
		}
	}


联系客服 意见反馈

签到成功!

已连续签到1天,签到3天将获得积分VIP1天

知道了