前言
-
最近在uni-app+vue3+websocket实现聊天功能,在使用websocket还是遇到很多问题
-
这次因为是app手机应用,就没有使用websocket对象,使用的是uni-app的uni.connectSocket
-
为了方便测试这次用的是node.js一个简单的dom,来联调模拟发数据,过程有意思
首先模拟一个node.js服务来测试-代码实现
1.在桌面建立一个空文件夹-命名英文
2.打开cmd
3.初始化-下包
// 初始化包
npm init -y
// 下载node框架包
npm i express --save
// 下载websocket模块
npm i ws
4.回到项目根文件创建根文件-app.js-代码如下
// 引入express框架
var app = require('express')();
var server = require('http').Server(app);
// 引入ws框架支持webSocket实现
var WebSocket = require('ws');
// 针对8080接口进行监听
var wss = new WebSocket.Server({ port: 8080 });
// 当建立连接后,打印日志
wss.on('connection', function connection(ws) {
console.log('建立连接');
// 同时返回服务端收到的信息
ws.on('message', function incoming(message) {
// const buffer = Buffer.from(message,'hex')
// console.log('ddd',buffer.toString('utf-8'));
// console.log('message',message);
console.log('接受前端消息: %s', message);
});
// 返回信息
ws.send('接收到消息了');
});
// 绑定访问地址
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
app.listen(3000);
5.来到终端运行服务
node ./app.js
6.websocket服务地址
本机ip+3000端口
来到uni-app+vue3项目
1.来到工具文件utils下创建websocket.js 文件-代码如下
import {
ref
} from "vue"
const websoket = ref(null);
const webSoketInit = (role, id) => {
const wsUrl = "ws://localhost:8080"
// return Promise
websoket.value = uni.connectSocket({
url: wsUrl,
success: () => {
console.log('websoket连接成功');
},
fail: () => {
console.log('websoket连接失败');
uni.showToast({
title: 'websoket连接失败',
icon: 'error',
duration: 2000,
});
},
});
websoket.value.onOpen((res) => {
if (websoket.value.readyState === 1) {
websoket.value.send({
data: '测试回复',
})
}
});
websoket.value.onClose(() => {
console.log('已经被关闭了');
});
websoket.value.onMessage((res) => {
console.log('接收到后端发送消息', res);
});
};
// 获取websocket对象
const getWebSocket = () => {
return websoket
};
// 关闭websocket【离开这个页面的时候执行关闭
const closeSocket = () => {
websoket.value.close({
success(res) {
this.is_open_socket = false;
console.log('关闭成功', res);
},
fail(err) {
console.log('关闭失败', err);
},
});
};
const sendMessage = (message) => {
console.log("发送消息", message)
if (websoket.value.readyState === 1) {
websoket.value.send({
data: message,
})
}
};
export {
getWebSocket,
websoket,
webSoketInit,
closeSocket,
sendMessage,
};
2.来到任意页面-初始化建立连接
<script setup>
import {
nextTick
} from "vue"
import {
onLoad,
onReady
} from "@dcloudio/uni-app";
// websocket 通讯
import {
getWebSocket,
websoket,
webSoketInit,
closeSocket,
sendMessage
} from "@/utils/webSocket.js"
// 判断当前视口大小
onLoad((options) => {
webSoketInit()
})
onReady(() => {
// 获取websocket对象
let ws = getWebSocket()
// 接受后端消息触发
ws.value.onMessage((e) => {
console.log('接受后端消息', e);
})
})
</script>
3.如图-代码效果
注意细节
1.前端使用websoket.value.send() 发送消息时后端接收一直都是undefined
-
因为我们不是使用的浏览器的websocket对象,使用的是uni-app封装过一层的uni.connectSocket
-
想在我们的实例对象是uni.connectSocket,需要按照uni-app的格式发送数据({data:'数据'})
-
官网地址-uni.connectSocket(OBJECT) | uni-app官网
-
如图
2.真机模拟时发现只有运行连接成功接收到消息,再用按钮触发后端服务也收不到消息-连接是成功的
-
因为本机运行到浏览器测试时,是可以访问到自己内网服务
-
真机运行虽然也是局域网连接wifi-但手机机制可能只会去公网上找-意思就是服务要上线
总结:
经过这一趟流程下来相信你也对 uni-app+vue3 +uni.connectSocket 使用websocket 有了初步的深刻印象,但在实际开发中我 们遇到的情况肯定是不一样的,所以我们要理解它的原理,万变不离其宗。加油,打工人!
有什么不足的地方请大家指出谢谢 -- 風过无痕