<div class="dialogBox">
<div class="dialogCont" :style="{ height: height }" ref="mainScrollRef" @scroll="scrollEvent">
<van-loading class="showTime" v-if="request.loading" type="circular" size="16">{{ request.loadText }}</van-loading>
<div class="itemBox" v-for="(item, index) in dialogList" :key="index" :id="`msg-${item.id}`">
<text class="showTime">{{ item.currentTimeIntervalString }}</text>
<div class="cont_item_l" v-if="item.fromUserId !== userId || item.other">
<img class="avatar" :src="getAvatar('fromUserAvatar')" />
<text class="word" v-if="item.content && item.type === 0"> {{ item.content }}</text>
<van-image width="50%" :src="getImgMessage(item.content?.fileKey || item.fileKey)" v-if="item.type === 1" />
</div>
<div class="cont_item_r" v-else>
<van-image width="50%" :src="getImgMessage(item.fileKey)" v-if="item.type === 1" />
<text class="word" v-if="item.content && item.type === 0">{{ item.content }}</text>
<img class="avatar" :src="getAvatar('toUserAvatar')" />
</div>
</div>
</div>
<div class="fool_input">
<van-cell-group inset class="input">
<van-field v-model="newsInput" rows="1" autofocus maxlength="200" @focus="headerShow" @blur="inputBlur"
:autosize="{ maxHeight: 100 }" ref="field" type="textarea" />
</van-cell-group>
<van-icon name="add-o" v-if="!showFunction" color="#5E5F66" size="22" />
<van-icon name="close" v-else color="#5E5F66" size="22" />
</div>
<van-button v-if="newsInput" type="success" size="mini" @click="sendMsg(newsInput, 0)">发送</van-button>
</div>
<van-grid v-if="showFunction" :border="false" class="grid_list">
<van-grid-item>
<div class="item">
<van-uploader :before-read="beforeRead" :after-read="afterRead" :max-size="isOverSize">
<img src="./images/album.png" alt="album">
</van-uploader>
<text>相册</text>
</div>
</van-grid-item>
</div>
<script setup lang="ts">
const userId = '123456' //发起人id
const token = '154665464454354'
const toUserId = '1666666'
const sessionId = '6666' //会话id
//创建webSocket 会话
const initWebSocket = (userId, sessionId) => {
console.log(userId, "userId", token)
websock.value = new WebSocket(`${webSocketUrl}/${userId}?Authorization=${token}`)
websock.value.onopen = websocketonopen
websock.value.onerror = websocketonerror
websock.value.onmessage = websocketonmessage
websock.value.onclose = websocketclose
console.log('创建会话开始')
}
//websocket连接成功
const websocketonopen = () => {
console.log('WebSocket连接成功')
}
//websocket连接失败
let cont = 0
const websocketonerror = e => {
console.log('WebSocket连接发生错误', e)
if (userId != null && cont <= 16) {
if (sessionId != null) {
initWebSocket(userId, sessionId)
cont++
}
}
}
//websocket关闭
const websocketclose = e => {
console.log('断开连接', e);
}
//websocket发送消息接收
const websocketonmessage = (e) => {
let data = JSON.parse(e?.data)
dialogList.value.push(data)
console.log(dialogList.value, "实时接收的聊天内容--")
setPageScrollTo()//
}
// 输入框消息发送
const field = ref()
const sendMsg = (message, type) => {
if (!message.replace(/\n/g, '').trim()) {
newsInput.value = ''
Toast('不能发送空白消息')
return
}
let params = {
id: `${new Date().getTime()}`,
fromUserId: userId,
message,
toUserId: toUserId,
type
}
dialogList.value.push({ params})
websock.value.send(params)
type === 0 && (newsInput.value = '') //清空输入框
getHight('.fool_input')
setPageScrollTo()
field.value.focus()
}
//图片上传成功后
const fileObj = ref({})
const afterRead = async (file) => {
const formData = new FormData()
formData.append('file', file.file)
// const { fileKey } = await uploadFile(formData)
fileObj.value = await uploadFile(formData)
sendMsg(fileObj.value.fileKey, 1)
}
// 动态获取高度
const getHight = (val?) => {
let view = document.querySelector(val ? val : '.cont_fool') as HTMLElement
height.value = `calc(100vh - ${view.getBoundingClientRect().height}px)`
}
// 设置页面滚动位置
const setPageScrollTo = (selector?) => {
if (!selector) {
nextTick(() => {
mainScrollRef.value.scrollTo({ top: mainScrollRef.value.scrollHeight })
})
return
}
let view = document.querySelector(selector) as HTMLElement
nextTick(() => {
const selectorPosition = view.getBoundingClientRect().top
const scrollEl = unref(mainScrollRef)
// -30 为多显示出大半个消息的高度,示意上面还有信息。
scrollEl.scrollTo({ top: selectorPosition - 30 })
})
}
// 监听滚动
const scrollEvent = (e) => {
// 滚动到顶部
if (e.srcElement.scrollTop < 5) {
getHistoryMessage()
}
}
// 监听滚动
const scrollEvent = (e) => {
// 滚动到顶部
if (e.srcElement.scrollTop < 5) {
getHistoryMessage()
}
}
onMounted(() => {
//页面首次进来 就开始创建会话
initWebSocket(userId, sessionId)
})
onUnmounted(() => {
//离开页面 断开会话
unref(websock)?.close()
})
</script>
小程序 h5 使用 webSocket 实现实时对话
于 2023-05-18 20:01:52 首次发布
该代码段展示了一个基于Vue.js的WebSocket聊天应用,实现了用户之间的实时消息传递和图片上传功能。当WebSocket连接打开时,会触发消息发送和接收的处理函数。当用户发送消息或上传图片后,内容会被添加到聊天记录列表中,并自动滚动到最新消息。同时,代码也包含了处理连接错误和重试的机制。
摘要由CSDN通过智能技术生成