WebSocket:也是一种协议,基于tcp协议,这里来和Http协议做一个对比
场景:http或https协议只能用来从前端发送请求给后端,而当服务端需要主动给前端发送消息时就没办法实现了,如:聊天系统;如果使用http协议就只能实现发送消息,而不能接收消息(因为接收消息需要服务端主动发送,这时候就需要用到WebSocket来进行通讯了)
websocket协议:ws://或wss://(区别一下http/https)
方法:websocket协议有这么几个方法
1、创建WebSocket对象
websocket = new WebSocket('ws://192.168.x.xxx:8001/api/customerService?token=xxx')
注:直接通过new WebSocket(指定后端url,一般来说传个token身份参数就够了)
2、连接:websocket.onopen
websocket.onopen = webSocketOpen
// 连接成功
function webSocketOpen () {
console.log('连接成功')
}
3、消息发送:websocket.send
// 注:websocket只能发送字符串,所以如果要发送一个对象的话,可以通过JSON.stringfy转为字符串
websocket.send(JSON.stringify({
data:{
message: data,
type: type,
}
}));
4、接收消息:websocket.onmessage
websocket.onmessage = webSocketMessage
// 数据接收:传输过来的也是字符串,可以转为JSON对象
function webSocketMessage (e) {
console.log(JSON.parse(e.data))
}
5、连接关闭:websocket.onclose和websocket.close()
5.1 websocket.onclose是监听到连接已关闭,比如网络不好,服务端主动断开连接等;
5.2 websocket.close()是前端主动调用websocket的连接关闭方法
/**
* 监听到连接关闭
*/
websocket.onclose = webSocketClose
// 连接关闭
function webSocketClose (e) {
console.log('连接已关闭', e)
}
/**
* 手动关闭连接
*/
function closeWebSocket () {
websocket.close()
console.log('已手动关闭连接')
}
6、连接发生错误:websocket.onerror
websocket.onerror = webSocketError
// 连接发生错误
function webSocketError () {
console.log('连接发生错误...')
}
实际在项目中使用,上面代码不方便重复使用,于是需要封装,下面提供一个封装的代码:
/**
* WebSocket通讯工具
*/
let websocket = null // webSocket实例
let receiveCallback = null // 消息接收的回调函数
let closeCallback = null // 连接关闭的回调函数
let code = '' // 唯一随机字符串来标志每一次会话
// 初始化websocket
function initWebSocket () {
console.log('VUE_APP_ENV',process.env.VUE_APP_ENV)
let wsUrl = `${process.env.VUE_APP_SOCKET_BASE_URL}/api/customerService?token=${xxx}
websocket = new WebSocket(wsUrl)
code = getUuid()
websocket.onmessage = webSocketMessage
websocket.onclose = webSocketClose
websocket.onopen = webSocketOpen
websocket.onerror = webSocketError
}
// 数据发送 data:需要发送的数据; type:消息类型
function webSocketSend (data, type) {
websocket.send(JSON.stringify({
type: 1,
data:{
code: code,
message: data,
type: type,
}
}));
}
// 连接成功
function webSocketOpen () {
console.log('连接成功')
}
// 数据接收
function webSocketMessage (e) {
receiveCallback(JSON.parse(e.data))
}
// 连接关闭(同上)
function webSocketClose (e) {
closeCallback(e)
}
// 连接发生错误
function webSocketError () {
console.log('连接发生错误...')
}
/**
* 发送消息
* @param data
*/
function sendMessage (data, type=messageType.TEXT, parentId=null, uiArea=0) {
if (websocket.readyState === websocket.OPEN) {
// 若是ws开启状态
webSocketSend(data, type)
} else if (websocket.readyState === websocket.CONNECTING) {
// 若是 正在开启状态,则等待1s后重新调用
setTimeout(function () {
sendMessage(data)
}, 1000)
}
}
/**
* 传递接收消息时的回调函数(消息接收之前必须先传一个回调函数给receiveCallback)
* @param callback
*/
function transferReceiveCallback (callback) {
receiveCallback = callback
}
/**
* 传递连接关闭时的回调函数(同上)
* @param callback transferCloseCallback
*/
function transferCloseCallback (callback) {
closeCallback = callback
}
/**
* 手动关闭连接
*/
function closeWebSocket () {
websocket.close()
console.log('已手动关闭连接')
}
/**
* 获取当前会话code
*/
function getCode() {
return code
}
// 将方法暴露出去
export default {
initWebSocket,
sendMessage,
transferReceiveCallback,
transferCloseCallback,
closeWebSocket,
getCode
}
在组建中使用:
xx.vue中
mounted(){
// 注:接收消息和监听连接关闭的调用要在初始化之前,这样才能接住初始化时的回调赋值
// 接收消息
this.receiveMessage()
// 监听连接关闭
this.connectionClosed()
// 初始化WebSocket(这里就调用到了websocket.js工具里的初始化方法)
webSocketUtil.initWebSocket()
}
// 接收消息
receiveMessage() {
webSocketUtil.transferReceiveCallback((data)=>{
console.log('接收到消息:', data)
})
}
// 监听连接关闭
connectionClosed() {
webSocketUtil.transferCloseCallback((data)=>{
console.log('连接已关闭')
})
},