|
|
@@ -1,82 +1,82 @@
|
|
|
<template>
|
|
|
- <div id="app">
|
|
|
- <transition name='fade' mode="out-in">
|
|
|
- <router-view/>
|
|
|
- </transition>
|
|
|
- </div>
|
|
|
+ <div id="app">
|
|
|
+ <transition name='fade' mode="out-in">
|
|
|
+ <router-view/>
|
|
|
+ </transition>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import Vue from 'vue';
|
|
|
-export default {
|
|
|
- name: 'App',
|
|
|
- // apiToken:'',//WebSocket链接凭证
|
|
|
- // time:'',
|
|
|
- data(){
|
|
|
- return{
|
|
|
- reconnectData:null,
|
|
|
- lockReconnect:false, //避免重复连接,因为onerror之后会立即触发 onclose
|
|
|
- timeout:10000, //10s一次心跳检测
|
|
|
- timeoutObj:null,
|
|
|
- serverTimeoutObj:null,
|
|
|
- apiToken:'',
|
|
|
- linkfailure:true,
|
|
|
+ import Vue from 'vue';
|
|
|
+ export default {
|
|
|
+ name: 'App',
|
|
|
+ // apiToken:'',//WebSocket链接凭证
|
|
|
+ // time:'',
|
|
|
+ data(){
|
|
|
+ return{
|
|
|
+ reconnectData:null,
|
|
|
+ lockReconnect:false, //避免重复连接,因为onerror之后会立即触发 onclose
|
|
|
+ timeout:10000, //10s一次心跳检测
|
|
|
+ timeoutObj:null,
|
|
|
+ serverTimeoutObj:null,
|
|
|
+ apiToken:'',
|
|
|
+ linkfailure:true,
|
|
|
|
|
|
- }
|
|
|
- },
|
|
|
- methods:{
|
|
|
- /**************************************/
|
|
|
- //初始化weosocket
|
|
|
- initWebSocket(apiToken) {
|
|
|
- // 书写接口信息
|
|
|
- const wsuri = "ws://103.108.43.176:9101?apiToken=" + apiToken;//www.service.com 线上
|
|
|
- //const wsuri = "ws://192.168.2.187:9101?apiToken=" + apiToken;//www.service.com //192.168.2.186 本地
|
|
|
- // 创建websocket实例
|
|
|
- Vue.prototype.$websocket = new WebSocket(wsuri);
|
|
|
- this.$websocket.onopen = this.websocketonopen; //连接成功
|
|
|
- this.$websocket.onmessage = this.websocketonmessage; //接收消息
|
|
|
- this.$websocket.onerror = this.websocketonerror;//链接错误提示
|
|
|
- this.$websocket.onclose = this.socket_close;//链接断开提示
|
|
|
- },
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods:{
|
|
|
+ /**************************************/
|
|
|
+ //初始化weosocket
|
|
|
+ initWebSocket(apiToken) {
|
|
|
+ // 书写接口信息
|
|
|
+ const wsuri = "ws://103.108.43.176:9101?apiToken=" + apiToken;//www.service.com 线上
|
|
|
+ // const wsuri = "ws://192.168.2.187:9101?apiToken=" + apiToken;//www.service.com //192.168.2.186 本地
|
|
|
+ // 创建websocket实例
|
|
|
+ Vue.prototype.$websocket = new WebSocket(wsuri);
|
|
|
+ this.$websocket.onopen = this.websocketonopen; //连接成功
|
|
|
+ this.$websocket.onmessage = this.websocketonmessage; //接收消息
|
|
|
+ this.$websocket.onerror = this.websocketonerror;//链接错误提示
|
|
|
+ this.$websocket.onclose = this.socket_close;//链接断开提示
|
|
|
+ },
|
|
|
|
|
|
-
|
|
|
- /**************************************/
|
|
|
- //连接成功
|
|
|
- websocketonopen() {
|
|
|
- console.log('已经链接');
|
|
|
- Vue.prototype.$socket_open = true;
|
|
|
- this.heatBeat();
|
|
|
- },
|
|
|
|
|
|
- /*******************************************/
|
|
|
- //连接关闭触发
|
|
|
- socket_close(e){
|
|
|
- console.log('断开连接',e);
|
|
|
- //this.init()
|
|
|
- this.reconnect();
|
|
|
- },
|
|
|
+ /**************************************/
|
|
|
+ //连接成功
|
|
|
+ websocketonopen() {
|
|
|
+ console.log('已经链接');
|
|
|
+ Vue.prototype.$socket_open = true;
|
|
|
+ this.heatBeat();
|
|
|
+ },
|
|
|
|
|
|
- /******************************************/
|
|
|
- //数据接收
|
|
|
- websocketonmessage(e){
|
|
|
- this.heatBeat();//收到消息会刷新心跳检测,如果一直收到消息,就推迟心跳发送
|
|
|
- const redata = JSON.parse(e.data);//接收数据源
|
|
|
- if(redata.type != "pong"){
|
|
|
- console.log(redata);
|
|
|
- }
|
|
|
- let getters = this.$store.getters;
|
|
|
- //获取vuex数据
|
|
|
- let session = getters.get_session;//会话列表
|
|
|
- let offline = getters.get_offline;//离线列表
|
|
|
- let sessionType = getters.get_type;//选择状态(会话/离线)
|
|
|
- let dataIndex = getters.get_num;//列表下标
|
|
|
- let current_session = getters.get_current;//当前会话
|
|
|
- let session_name = getters.get_session_name;//当前用户名
|
|
|
-
|
|
|
- if(e.data.type == "pong" ) return
|
|
|
- this.$store.dispatch("SET_SESSION_MESSAGE",JSON.parse(e.data));
|
|
|
+ /*******************************************/
|
|
|
+ //连接关闭触发
|
|
|
+ socket_close(e){
|
|
|
+ console.log('断开连接',e);
|
|
|
+ //this.init()
|
|
|
+ this.reconnect();
|
|
|
+ },
|
|
|
|
|
|
- // 用户接入数据
|
|
|
+ /******************************************/
|
|
|
+ //数据接收
|
|
|
+ websocketonmessage(e){
|
|
|
+ this.heatBeat();//收到消息会刷新心跳检测,如果一直收到消息,就推迟心跳发送
|
|
|
+ const redata = JSON.parse(e.data);//接收数据源
|
|
|
+ if(redata.type != "pong"){
|
|
|
+ console.log(redata);
|
|
|
+ }
|
|
|
+ let getters = this.$store.getters;
|
|
|
+ //获取vuex数据
|
|
|
+ let session = getters.get_session;//会话列表
|
|
|
+ let offline = getters.get_offline;//离线列表
|
|
|
+ let sessionType = getters.get_type;//选择状态(会话/离线)
|
|
|
+ let dataIndex = getters.get_num;//列表下标
|
|
|
+ let current_session = getters.get_current;//当前会话
|
|
|
+ let session_name = getters.get_session_name;//当前用户名
|
|
|
+
|
|
|
+ if(e.data.type == "pong" ) return
|
|
|
+ this.$store.dispatch("SET_SESSION_MESSAGE",JSON.parse(e.data));
|
|
|
+
|
|
|
+ // 用户接入数据
|
|
|
if(redata.message_type == "connect"){
|
|
|
let _this = this;
|
|
|
let arr =[
|
|
|
@@ -90,8 +90,8 @@ export default {
|
|
|
]
|
|
|
_this.$public.visitorsConnect(arr,function(data){
|
|
|
//离线匹配列表访客链接回调
|
|
|
- _this.$store.dispatch("SET_OFFLINE",data);
|
|
|
-
|
|
|
+ _this.$store.dispatch("SET_OFFLINE",data);
|
|
|
+
|
|
|
},function(data,session,offline,type,num,dataList,name){
|
|
|
//将用户添加到会话列表中
|
|
|
session.push(data.user_info);
|
|
|
@@ -104,10 +104,10 @@ export default {
|
|
|
_this.$store.dispatch("SET_NUM",num);//列表下标
|
|
|
_this.$store.dispatch("SET_CURRENT",dataList);//当前会话数据
|
|
|
_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
|
|
|
-
|
|
|
+
|
|
|
})
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
//用户离线后会话窗口切换
|
|
|
if(redata.message_type == "userClose"){
|
|
|
@@ -115,14 +115,14 @@ export default {
|
|
|
let arr= [
|
|
|
redata.data,
|
|
|
session,
|
|
|
- offline,
|
|
|
+ offline,
|
|
|
sessionType,
|
|
|
dataIndex,
|
|
|
session_name,
|
|
|
current_session,
|
|
|
]
|
|
|
_this.$public.userOffline(arr,function(session,offline,type,index,name,list,userInfo){
|
|
|
- _this.$store.dispatch("SET_CURRENT",list);//当前会话数据
|
|
|
+ _this.$store.dispatch("SET_CURRENT",list);//当前会话数据
|
|
|
_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
|
|
|
_this.$store.dispatch("SET_NUM",index);
|
|
|
_this.$store.dispatch("SET_TYPE",type);
|
|
|
@@ -139,159 +139,159 @@ export default {
|
|
|
let arr= [
|
|
|
redata.data,
|
|
|
session,
|
|
|
- offline,
|
|
|
+ offline,
|
|
|
sessionType,
|
|
|
dataIndex,
|
|
|
session_name,
|
|
|
current_session,
|
|
|
]
|
|
|
_this.$public.sessionEnd(arr,function(session,offline,type,index,name,list,userInfo){
|
|
|
- _this.$store.dispatch("SET_CURRENT",list);//当前会话数据
|
|
|
+ _this.$store.dispatch("SET_CURRENT",list);//当前会话数据
|
|
|
_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
|
|
|
_this.$store.dispatch("SET_NUM",index);
|
|
|
_this.$store.dispatch("SET_TYPE",type);
|
|
|
_this.$store.dispatch("SET_SESSION",session);
|
|
|
_this.$store.dispatch("SET_OFFLINE",offline);
|
|
|
- // _this.get_user_info(userInfo);
|
|
|
+ // _this.get_user_info(userInfo);
|
|
|
})
|
|
|
}
|
|
|
|
|
|
//接收用户消息数据
|
|
|
if(redata.message_type == "chatMessage"){
|
|
|
|
|
|
- this.receiveAudio();
|
|
|
+ this.receiveAudio();
|
|
|
let _this =this;
|
|
|
this.$public.receivesMessage(redata.data,session,this.$frce,function(data,chatList,index){
|
|
|
//判断是否是当前对话信息
|
|
|
if(dataIndex == index){
|
|
|
- // _this.data =[];
|
|
|
- // _this.data = chatList.data;
|
|
|
- _this.$store.dispatch("SET_CURRENT",chatList.data);//当前会话数据
|
|
|
+ // _this.data =[];
|
|
|
+ // _this.data = chatList.data;
|
|
|
+ _this.$store.dispatch("SET_CURRENT",chatList.data);//当前会话数据
|
|
|
}else{
|
|
|
- let num = Number.isInteger(chatList.num) ? chatList.num : 0;
|
|
|
- // _this.$set(chatList,'num',num+1)
|
|
|
- session[index].num = num+1
|
|
|
+ let num = Number.isInteger(chatList.num) ? chatList.num : 0;
|
|
|
+ // _this.$set(chatList,'num',num+1)
|
|
|
+ session[index].num = num+1
|
|
|
}
|
|
|
//更新会话时间
|
|
|
- // _this.$set(chatList,'intime',data.time);
|
|
|
- session[index].intime =data.time
|
|
|
-
|
|
|
+ // _this.$set(chatList,'intime',data.time);
|
|
|
+ session[index].intime =data.time
|
|
|
+
|
|
|
//更新会话列表中最新回复消息
|
|
|
if(data.content.text){
|
|
|
- // _this.$set(chatList,'text',data.content.text)
|
|
|
- session[index].text =data.content.text
|
|
|
- }
|
|
|
- _this.$store.dispatch("SET_SESSION",session);
|
|
|
+ // _this.$set(chatList,'text',data.content.text)
|
|
|
+ session[index].text =data.content.text
|
|
|
+ }
|
|
|
+ _this.$store.dispatch("SET_SESSION",session);
|
|
|
})
|
|
|
}
|
|
|
-
|
|
|
- //reLoginErr
|
|
|
- if(redata.message_type == "reLoginErr"){
|
|
|
- console.log('haha');
|
|
|
- this.init()
|
|
|
- }
|
|
|
|
|
|
- },
|
|
|
+ //reLoginErr
|
|
|
+ if(redata.message_type == "reLoginErr"){
|
|
|
+ console.log('haha');
|
|
|
+ this.init()
|
|
|
+ }
|
|
|
|
|
|
- /**************************************/
|
|
|
- //连接断开,失败
|
|
|
- websocketonerror(e) {
|
|
|
- console.log('失败',e);
|
|
|
- if(this.linkfailure){
|
|
|
- this.init()
|
|
|
- }
|
|
|
- },
|
|
|
+ },
|
|
|
|
|
|
- /******************************************/
|
|
|
- //断开链接数据初始化
|
|
|
- init(){
|
|
|
- this.$store.dispatch("SET_STATEVALUE",'隐身');
|
|
|
- this.$store.dispatch("SET_SESSION",[]);
|
|
|
- this.$store.dispatch("SET_OFFLINE",[]);
|
|
|
- this.$store.dispatch("SET_SESSION",[]);//会话列表
|
|
|
- this.$store.dispatch("SET_OFFLINE",[]);//离线列表
|
|
|
- this.$store.dispatch("SET_TYPE",1);//选择类型(会话/离线)
|
|
|
- this.$store.dispatch("SET_NUM",0);//列表下标
|
|
|
- this.$store.dispatch("SET_CURRENT",[]);//当前会话数据
|
|
|
- this.$store.dispatch("SET_SESSION_NAME",'');//当前会话对象名
|
|
|
- this.$store.dispatch("SET_SESSION_MESSAGE",{});
|
|
|
- this.$store.dispatch("SET_IS_INIT",false);
|
|
|
- this.$token = '';
|
|
|
- this.$router.push('/login')
|
|
|
- this.linkfailure = true;
|
|
|
- //this.reconnect();
|
|
|
- },
|
|
|
+ /**************************************/
|
|
|
+ //连接断开,失败
|
|
|
+ websocketonerror(e) {
|
|
|
+ console.log('失败',e);
|
|
|
+ if(this.linkfailure){
|
|
|
+ this.init()
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
- /*******************************************/
|
|
|
- // 接收消息音频提示
|
|
|
- receiveAudio() {
|
|
|
- let receive = new Audio()
|
|
|
+ /******************************************/
|
|
|
+ //断开链接数据初始化
|
|
|
+ init(){
|
|
|
+ this.$store.dispatch("SET_STATEVALUE",'隐身');
|
|
|
+ this.$store.dispatch("SET_SESSION",[]);
|
|
|
+ this.$store.dispatch("SET_OFFLINE",[]);
|
|
|
+ this.$store.dispatch("SET_SESSION",[]);//会话列表
|
|
|
+ this.$store.dispatch("SET_OFFLINE",[]);//离线列表
|
|
|
+ this.$store.dispatch("SET_TYPE",1);//选择类型(会话/离线)
|
|
|
+ this.$store.dispatch("SET_NUM",0);//列表下标
|
|
|
+ this.$store.dispatch("SET_CURRENT",[]);//当前会话数据
|
|
|
+ this.$store.dispatch("SET_SESSION_NAME",'');//当前会话对象名
|
|
|
+ this.$store.dispatch("SET_SESSION_MESSAGE",{});
|
|
|
+ this.$store.dispatch("SET_IS_INIT",false);
|
|
|
+ this.$token = '';
|
|
|
+ this.$router.push('/login')
|
|
|
+ this.linkfailure = true;
|
|
|
+ //this.reconnect();
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ // 接收消息音频提示
|
|
|
+ receiveAudio() {
|
|
|
+ let receive = new Audio()
|
|
|
receive.src = "../static/audio/receive.wav";
|
|
|
- receive.play();
|
|
|
- },
|
|
|
+ receive.play();
|
|
|
+ },
|
|
|
|
|
|
- /***************************************/
|
|
|
- //socket重连
|
|
|
- reconnect(){
|
|
|
- if(this.lockReconnect){ //这里很关键,因为连接失败之后之后会相继触发 连接关闭,不然会连接上两个 WebSocket
|
|
|
- return
|
|
|
- }
|
|
|
- this.lockReconnect = true;
|
|
|
- this.reconnectData && clearTimeout(this.reconnectData);
|
|
|
- this.reconnectData = setTimeout(()=>{
|
|
|
- this.initWebSocket(this.apiToken);
|
|
|
- this.lockReconnect = false;
|
|
|
- },3000)
|
|
|
- },
|
|
|
+ /***************************************/
|
|
|
+ //socket重连
|
|
|
+ reconnect(){
|
|
|
+ if(this.lockReconnect){ //这里很关键,因为连接失败之后之后会相继触发 连接关闭,不然会连接上两个 WebSocket
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.lockReconnect = true;
|
|
|
+ this.reconnectData && clearTimeout(this.reconnectData);
|
|
|
+ this.reconnectData = setTimeout(()=>{
|
|
|
+ this.initWebSocket(this.apiToken);
|
|
|
+ this.lockReconnect = false;
|
|
|
+ },3000)
|
|
|
+ },
|
|
|
|
|
|
- /*************************************/
|
|
|
- //心跳检测
|
|
|
- heatBeat(){
|
|
|
- this.timeoutObj && clearTimeout(this.timeoutObj);
|
|
|
- this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
|
|
|
- this.timeoutObj = setTimeout(()=>{
|
|
|
- // console.log('发送',{type:'ping'});
|
|
|
- this.$websocket.send(JSON.stringify({type:'ping'})) //根据后台要求发送
|
|
|
- this.serverTimeoutObj = setTimeout(()=> {
|
|
|
- this.$websocket.close(); //如果 5秒之后我们没有收到 后台返回的心跳检测数据 断开socket,断开后会启动重连机制
|
|
|
- }, 5000);
|
|
|
- }, this.timeout)
|
|
|
- },
|
|
|
-
|
|
|
- /******************************/
|
|
|
-
|
|
|
- },
|
|
|
- mounted() {
|
|
|
- // 获取系统时间
|
|
|
- let t = new Date().getTime();
|
|
|
- this.get('api'+this.$ports.TIME+'?t='+t).then(res => {
|
|
|
- //this.get('http://kfadmin.bocai186.com'+this.$ports.TIME+'?t='+t).then(res => {
|
|
|
- if (res.data.code == 1) {
|
|
|
- let time = res.data.data.time.split(' ');
|
|
|
- time[0] =(new Date( time[0].replace(/-/g,'/')).getTime()) /1000;
|
|
|
- sessionStorage.setItem("time",JSON.stringify(time));
|
|
|
- sessionStorage.setItem("logo",res.data.data.logo);
|
|
|
- this.apiToken = this.$md5('customer-service'+time[0]+window.location.origin)
|
|
|
- this.initWebSocket(this.apiToken);
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- destroyed() {
|
|
|
- this.lockReconnect = true;
|
|
|
- this.websock.close() //离开路由之后断开websocket连接
|
|
|
- clearTimeout(this.reconnectData); //离开清除 timeout
|
|
|
- clearTimeout(this.timeoutObj); //离开清除 timeout
|
|
|
- clearTimeout(this.serverTimeoutObj); //离开清除 timeout
|
|
|
- }
|
|
|
-}
|
|
|
+ /*************************************/
|
|
|
+ //心跳检测
|
|
|
+ heatBeat(){
|
|
|
+ this.timeoutObj && clearTimeout(this.timeoutObj);
|
|
|
+ this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
|
|
|
+ this.timeoutObj = setTimeout(()=>{
|
|
|
+ // console.log('发送',{type:'ping'});
|
|
|
+ this.$websocket.send(JSON.stringify({type:'ping'})) //根据后台要求发送
|
|
|
+ this.serverTimeoutObj = setTimeout(()=> {
|
|
|
+ this.$websocket.close(); //如果 5秒之后我们没有收到 后台返回的心跳检测数据 断开socket,断开后会启动重连机制
|
|
|
+ }, 5000);
|
|
|
+ }, this.timeout)
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************************/
|
|
|
+
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ // 获取系统时间
|
|
|
+ let t = new Date().getTime();
|
|
|
+ //this.get('api'+this.$ports.TIME+'?t='+t).then(res => {
|
|
|
+ this.get('http://kfadmin.bocai186.com'+this.$ports.TIME+'?t='+t).then(res => {
|
|
|
+ if (res.data.code == 1) {
|
|
|
+ let time = res.data.data.time.split(' ');
|
|
|
+ time[0] =(new Date( time[0].replace(/-/g,'/')).getTime()) /1000;
|
|
|
+ sessionStorage.setItem("time",JSON.stringify(time));
|
|
|
+ sessionStorage.setItem("logo",res.data.data.logo);
|
|
|
+ this.apiToken = this.$md5('customer-service'+time[0]+window.location.origin)
|
|
|
+ this.initWebSocket(this.apiToken);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ destroyed() {
|
|
|
+ this.lockReconnect = true;
|
|
|
+ this.websock.close() //离开路由之后断开websocket连接
|
|
|
+ clearTimeout(this.reconnectData); //离开清除 timeout
|
|
|
+ clearTimeout(this.timeoutObj); //离开清除 timeout
|
|
|
+ clearTimeout(this.serverTimeoutObj); //离开清除 timeout
|
|
|
+ }
|
|
|
+ }
|
|
|
</script>
|
|
|
|
|
|
<style>
|
|
|
- .fade-enter-active, .fade-leave-active {
|
|
|
- transition: opacity .5s;
|
|
|
- }
|
|
|
-
|
|
|
- .fade-enter, .fade-leave-to {
|
|
|
- opacity: 0;
|
|
|
- }
|
|
|
+ .fade-enter-active, .fade-leave-active {
|
|
|
+ transition: opacity .5s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .fade-enter, .fade-leave-to {
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
</style>
|