|
|
@@ -2,11 +2,17 @@
|
|
|
<el-row class="movie-list">
|
|
|
<el-col :md="18">
|
|
|
<div class="movie-list" style="height: 70vh;">
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="submit"
|
|
|
+ class="el-icon-delete"
|
|
|
+ @click="onClear"
|
|
|
+ >清空</el-button>
|
|
|
<!-- 注意需要给 el-scrollbar 设置高度,判断是否滚动是看它的height判断的 -->
|
|
|
- <el-scrollbar ref="myScrollbar" style="width: 100%; height: 100%;">
|
|
|
+ <el-scrollbar ref="myScrollbar" style="width: 100%; height: 100%; background-color: #B3C0D1">
|
|
|
<el-row class="movie-list">
|
|
|
<div
|
|
|
- v-for="(item, index) in dataList"
|
|
|
+ v-for="(item, index) in talkItems"
|
|
|
:key="index"
|
|
|
:md="6"
|
|
|
:sm="12"
|
|
|
@@ -35,8 +41,7 @@
|
|
|
</el-col>
|
|
|
<el-col :md="6">
|
|
|
<el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
|
|
|
- <span v-if="online" style="color: forestgreen">在线</span>
|
|
|
- <span v-else style="color: orangered">离线</span>
|
|
|
+ <span style="color: forestgreen">{{socketStatus}}</span>
|
|
|
<!-- <el-col>
|
|
|
<el-button
|
|
|
size="mini"
|
|
|
@@ -45,11 +50,13 @@
|
|
|
@click="clear"
|
|
|
>清空</el-button>
|
|
|
</el-col>-->
|
|
|
- <el-select v-model="receiverId" placeholder="选择用户">
|
|
|
- <el-option label="西瓜" value="10001" />
|
|
|
- <el-option label="土豆" value="10002" />
|
|
|
- <el-option label="番茄" value="10003" />
|
|
|
- <el-option label="芒果" value="10004" />
|
|
|
+ <el-select v-model="receiverId" placeholder="选择联系人">
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in contactList"
|
|
|
+ :key="index"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
</el-select>
|
|
|
</el-row>
|
|
|
<el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
|
|
|
@@ -82,10 +89,14 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+import { mapState, mapGetters } from 'vuex'
|
|
|
import { getAccessToken, getAuthedUser } from '@/utils/auth'
|
|
|
+import { getUserContact } from '@/api/contact'
|
|
|
+import SocketInstance from '@/utils/ws/socket-instance'
|
|
|
+import store from '@/store'
|
|
|
|
|
|
export default {
|
|
|
- name: 'WebSocket',
|
|
|
+ name: 'Chat',
|
|
|
filters: {
|
|
|
ellipsis(value) {
|
|
|
if (!value) return ''
|
|
|
@@ -98,21 +109,66 @@ export default {
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
+ wsClient: null,
|
|
|
+ heartbeatConfig: {
|
|
|
+ setInterval: null,
|
|
|
+ pingInterval: 20000,
|
|
|
+ pingTimeout: 60000
|
|
|
+ },
|
|
|
+ reconnectConfig: {
|
|
|
+ lockReconnect: false,
|
|
|
+ setTimeout: null, // 计时器对象
|
|
|
+ time: 5000, // 重连间隔时间
|
|
|
+ number: 1000 // 重连次数
|
|
|
+ },
|
|
|
+ // 最后心跳时间
|
|
|
+ lastTime: 0,
|
|
|
user: null,
|
|
|
- dataList: [],
|
|
|
+ contactList: [],
|
|
|
text: '',
|
|
|
- receiverId: '10001',
|
|
|
+ receiverId: null,
|
|
|
websocket: null,
|
|
|
token: null,
|
|
|
online: false
|
|
|
}
|
|
|
},
|
|
|
+ computed: {
|
|
|
+ ...mapState({
|
|
|
+ socketStatus: state => state.socketStatus
|
|
|
+ }),
|
|
|
+ ...mapGetters(['talkItems'])
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ const token = getAccessToken()
|
|
|
+ if (token === null) {
|
|
|
+ this.$message.error('当前未登入')
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ this.token = token
|
|
|
+ }
|
|
|
+
|
|
|
+ const wsUrl = 'ws:' + process.env.VUE_APP_SERVER_URL + '/ws/chat?token=' + this.token
|
|
|
+ this.wsClient = new SocketInstance(wsUrl)
|
|
|
+ this.wsClient.connect()
|
|
|
+ },
|
|
|
created() {
|
|
|
- document.title = 'MessageStream'
|
|
|
+ document.title = 'Chat'
|
|
|
const userInfo = getAuthedUser()
|
|
|
- if (userInfo !== null) {
|
|
|
- this.user = userInfo
|
|
|
+ if (userInfo === null) {
|
|
|
+ this.$message.error('当前未登入')
|
|
|
+ return
|
|
|
}
|
|
|
+ this.user = userInfo
|
|
|
+ getUserContact().then(resp => {
|
|
|
+ if (resp.code === 0) {
|
|
|
+ for (const item of resp.data) {
|
|
|
+ var option = {}
|
|
|
+ option.label = item.nickname
|
|
|
+ option.value = item.id
|
|
|
+ this.contactList.push(option)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
|
|
|
const token = getAccessToken()
|
|
|
if (token === null) {
|
|
|
@@ -120,7 +176,6 @@ export default {
|
|
|
} else {
|
|
|
this.token = token
|
|
|
}
|
|
|
- this.initWebSocket()
|
|
|
},
|
|
|
methods: {
|
|
|
keyDown(e) {
|
|
|
@@ -137,92 +192,38 @@ export default {
|
|
|
},
|
|
|
clear() {
|
|
|
this.text = ''
|
|
|
- // this.dataList = []
|
|
|
+ },
|
|
|
+ onClear() {
|
|
|
+ store.commit('REMOVE_TALK_ITEM')
|
|
|
},
|
|
|
onSubmit() {
|
|
|
+ if (this.receiverId === null) {
|
|
|
+ this.$message.error('没有选择联系人')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
var jsonData = {}
|
|
|
jsonData.event = 'event_talk'
|
|
|
jsonData.data = {}
|
|
|
jsonData.data.receiverId = this.receiverId
|
|
|
jsonData.data.senderId = this.user.userId
|
|
|
jsonData.data.content = this.text
|
|
|
- this.websocketSend(jsonData)
|
|
|
+ this.wsClient.send(jsonData)
|
|
|
this.text = ''
|
|
|
- },
|
|
|
- initWebSocket: function() {
|
|
|
- var url = 'ws:' + process.env.VUE_APP_SERVER_URL + '/ws/chat?token=' + this.token
|
|
|
- this.websock = new WebSocket(url)
|
|
|
- this.websock.onopen = this.websocketOnopen
|
|
|
- this.websock.onerror = this.websocketOnerror
|
|
|
- this.websock.onmessage = this.websocketOnmessage
|
|
|
- this.websock.onclose = this.websocketOnclose
|
|
|
- },
|
|
|
- websocketOnopen: function() {
|
|
|
- console.log('WebSocket连接成功')
|
|
|
- this.online = true
|
|
|
- // 心跳检测重置
|
|
|
- // this.heartCheck.reset().start();
|
|
|
- },
|
|
|
- websocketOnerror: function(e) {
|
|
|
- console.log('WebSocket连接发生错误')
|
|
|
- this.online = false
|
|
|
- this.reconnect()
|
|
|
- },
|
|
|
- websocketOnclose: function(e) {
|
|
|
- console.log('connection closed (' + e.code + ')')
|
|
|
- this.online = false
|
|
|
- this.reconnect()
|
|
|
- },
|
|
|
- websocketOnmessage: function(e) {
|
|
|
- const evtData = JSON.parse(e.data)
|
|
|
- const receiverId = evtData.receiverId
|
|
|
- const senderId = evtData.senderId
|
|
|
- const payload = evtData.payload
|
|
|
|
|
|
var justify = 'end'
|
|
|
- if (receiverId === this.user.userId) {
|
|
|
+ /* if (jsonData.data.senderId === this.user.userId) {
|
|
|
justify = 'start'
|
|
|
- }
|
|
|
-
|
|
|
+ }*/
|
|
|
var msg = {}
|
|
|
- msg.senderId = evtData.senderId
|
|
|
- msg.content = evtData.payload
|
|
|
- this.dataList.push({
|
|
|
+ msg.receiverId = jsonData.data.receiverId
|
|
|
+ msg.content = jsonData.data.content
|
|
|
+ var item = {
|
|
|
content: msg,
|
|
|
justify: justify
|
|
|
- })
|
|
|
- },
|
|
|
- websocketSend(jsonData) { // 数据发送
|
|
|
- try {
|
|
|
- this.websock.send(JSON.stringify(jsonData))
|
|
|
- this.$message.success('消息已发送')
|
|
|
-
|
|
|
- var justify = 'start'
|
|
|
- if (jsonData.data.senderId === this.user.userId) {
|
|
|
- justify = 'end'
|
|
|
- }
|
|
|
-
|
|
|
- var msg = {}
|
|
|
- msg.receiverId = jsonData.data.receiverId
|
|
|
- msg.content = jsonData.data.content
|
|
|
- this.dataList.push({
|
|
|
- content: msg,
|
|
|
- justify: justify
|
|
|
- })
|
|
|
- } catch (err) {
|
|
|
- this.$message.error('send failed (' + err.code + ')')
|
|
|
}
|
|
|
- },
|
|
|
- reconnect() {
|
|
|
- const that = this
|
|
|
- if (that.lockReconnect) return
|
|
|
- that.lockReconnect = true
|
|
|
- // 没连接上会一直重连,设置延迟避免请求过多
|
|
|
- setTimeout(function() {
|
|
|
- console.info('尝试重连...')
|
|
|
- that.initWebSocket()
|
|
|
- that.lockReconnect = false
|
|
|
- }, 5000)
|
|
|
+
|
|
|
+ store.commit('PUSH_TALK_ITEM', item)
|
|
|
}
|
|
|
}
|
|
|
}
|