vue------websocket

  Vue项目实现websocket连接步骤:

1、安装依赖:cnpm install stompjs

                  cnpm install sockjs-client

2、在main.js中全局注册 

import * as socketApi from './api/socket'// socket api文件夹下新建socket.js文件
Vue.prototype.socketApi = socketApi 

3、socket.js文件:

import SockJS from 'sockjs-client'
import Stomp from 'stompjs'

var websock = null
var saveObj = {}
var websocketurl = null
var stompClient = null
// 初始化weosocket
function initWebSocket(url = websocketurl) {
// ws地址 -->这里是你的请求路径
websocketurl = url // 请求地址
// 建立连接对象(还未发起连接)
var socket = new SockJS(websocketurl)
/* var socket = new SockJS(process.env.VUE_APP_BASE_API + '/Authorization=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJNSU5HIiwiZXhwIjoxNTc4NDUyNzY4LCJpYXQiOjE1Nzg0NTA5NjgsInVzZXIiOiJ7XCJwaG9uZVwiOjE4OTQ0NDQ0NDQ0LFwib3JnSWRcIjo1MDAxMDcwMDIsXCJvcmdUeXBlXCI6NSxcInJvbGVJZFwiOjQzNH0ifQ.XnStuxg3ZT8mkfORanCU_79SO4xfcG9DYrR9VdWQ7rM')
*/
// 获取 STOMP 子协议的客户端对象
stompClient = Stomp.over(socket)
// 向服务器发起websocket连接并发送CONNECT帧【连接】
stompClient.connect({}, function(frame) {
// 订阅频道
stompClient.subscribe('/topic/getResponse', function(response) {
   /topic/getResponse根据后台写好的名字来

websocketonmessage(response)
})
// 监听通道(也得根据后台写好的来)
stompClient.subscribe('/user/topic/channelMessage', function(response) {
websocketonmessage(response)
})
})
socket.onclose = websocketclose
}

// 实际调用的方法
function sendSock(agentData, callback) {
if (websock.readyState === websock.OPEN) {
// 若是ws开启状态
websocketsend(agentData)
} else if (websock.readyState === websock.CONNECTING) {
// 若是 正在开启状态,则等待1s后重新调用
setTimeout(function() {
sendSock(agentData, callback)
}, 1000)
} else {
// 若未开启 ,则等待1s后重新调用
setTimeout(function() {
sendSock(agentData, callback)
}, 1000)
}
}

// 数据接收
function websocketonmessage(e) {
const data = e.body
if (data.indexOf('{') !== -1 && data.indexOf('}') !== -1) { // 是JSON字符串
const obj = JSON.parse(data)
if (saveObj[obj.messageType]) { // messageType:根据后台的类型变换 ,可能是其他

saveObj[obj.messageType](obj)
}
}
}

function proxyFunction(messageType, callback) {
saveObj[messageType] = callback
}

// 数据发送
function websocketsend(agentData) {
websock.send(JSON.stringify(agentData))
}

// 关闭
function websocketclose(e) {
initWebSocket()
}

// 创建 websocket 连接
function websocketOpen(e) {
console.log('连接成功')
}

export {
initWebSocket, // 真正调用的两个方法
proxyFunction
}
 
4、调用:
vue文件:
<template>
<div v-if="messageCount>0" class="em-alarm">
<el-tooltip class="item" effect="dark" :content="content" placement="top-start">
<el-badge :value="messageCount" style="line-height: 25px;margin-top: -5px;" @click.native="dialogTableVisible=true">
<el-button style="padding: 8px 10px;" size="small" type="danger" class="em-alarm-btn">
<svg-icon icon-class="alarm" class-name="alarm-icon" />
</el-button>
</el-badge>
</el-tooltip>
<el-dialog :visible.sync="dialogTableVisible" title="消息详情" width="40%" append-to-body>
<el-table :data="messageData" border empty-text="暂无数据">
<el-table-column type="index" width="50" :index="tableIndex" />

<el-table-column v-for="info in tableHeader" :key="info.key" :label="info.label" :formatter="formatterFn">
<template slot-scope="scope">
<span>{{ scope.row[info.key] }}</span>
</template>
</el-table-column>
</el-table>
<Pagination :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" :hide-on-single-page="pageOne" @pagination="handlePaginationChange"
@current-change="handleCurrentChange" />
</el-dialog>
</div>
</template>

<script>
import { messageCount, messageDetails } from '@/api/schoolService/tableInfo'
import { staticFormatterMap } from '@/utils/formatterMap'
export default {
name: 'SchoolAlarm',
data() {
return {
dialogTableVisible: false,
BASE_API: process.env.VUE_APP_BASE_API, //基础地址:http://......
messageCount: '', // badge标记的值
messageData: [], // 详情列表
content: '', // 提示消息
formatterMap: {},
tableHeader: [
{
label: '消息标题',
key: 'msgTitle'
},
{
label: '消息类型',
key: 'messageType'
},
{
label: '消息详情',
key: 'describeStr'
}
],
pageOne: false,
total: 0,
listQuery: {
limit: 10,
page: 1
}
}
},
created() {
this.init()
this.getList()
后台的url地址:
const token = this.$store.getters.token // 登录时自带的token(为了区分通道)从vueX中国获取的。
// ws:neinx那边加的,要是没有ws则会自动加上一个info,通道没法连接上
    // access_token: //后端的token名字
// sockets: 接口基本地址必须带的
const url = this.BASE_API + '/ws/sockets?access_token=' + token
this.socketApi.initWebSocket(url)
this.socketApi.proxyFunction(5, (res) => { //对应socket里面的messageType
if (res) {
this.init() // 校徽传递通知消息后继续获取数量
}
})
},
methods: {
init() {
const _param = {
messageType: 5
}
messageCount({
url: '/sockets/push/queryCountAllByPageParams',
params: _param
}).then(response => {
this.content = 'xxx报警'
this.messageCount = response.data // 校内sos报警消息
})
},
tableIndex(index) { // 第二页开始表格数据行号不从1开始
return (this.listQuery.page - 1) * this.listQuery.limit + index + 1
},
// 分页改变:改变条数和分页
handlePaginationChange(res) {
this.listQuery = res
this.getList()
},
// 获取详情列表数据
getList() {
const _params = {
pageSize: this.listQuery.limit,
pageNum: this.listQuery.page,
messageType: 5
}
messageDetails({
url: '/sockets/push/queryNoContentAllByPageParams',
params: _params
}).then(res => {
if (res.statusCode === 200) {
this.messageData = res.data.list
this.total = res.data.total
} else if (res.statusCode === 503) {
this.$message({
showClose: true,
message: '没有指定消息内容哦!',
type: 'info',
duration: 1000
})
}
})
},
handleCurrentChange(val) {
},
// 过滤字段
formatterFn(row, column) {
let _val = ''
const _formatterMap = Object.assign({}, this.formatterMap, staticFormatterMap) // 动态和静态数据求交集
console.log('过滤', _formatterMap)
if (column.property in _formatterMap) {
_val = _formatterMap[column.property].get(row[column.property])
} else {
_val = row[column.property]
}
return _val
}
}
}
</script>

<style scoped lang="scss">
.em-alarm /deep/{
}
.message-title {
font-size: 16px;
color: #333;
font-weight: bold;
padding-right: 8px;
}
.alarm-icon{
cursor: pointer;
font-size: 20px;
vertical-align: middle;
}
.el-button--danger.em-alarm-btn{
border-radius: 50%;
}
</style>
总结:在实现的过程中没有注意nginx服务端的websocket定义的名字,于是在连接时使用了请求地址token名字加上token,直接请求,出现了请求地址正常明明正确无误,但是发送请求时地址
的toekn名前面多了关键字info。。。。。找了很久才发现问题!
补充:




 













 

posted on 2020-01-09 10:23  小虾米吖~  阅读(526)  评论(0编辑  收藏  举报