Vue 连接 WebSocket wss://echo.websocket.org/ws
由于 wss://echo.websocket.org 不支持STOMP协议,改用原生WebSocket API
这个地址可以用来测试,wss://echo.websocket.org/ws
最终效果

代码如下:
<template>
<div class="app-container">
<el-row :gutter="10">
<el-col :span="12">
<el-card>
<el-row>
<el-col :span="18">
<el-input v-model="socketEndpoint" style="width: 260px" />
<el-button
type="primary"
class="ml-5"
:disabled="isConnected"
@click="connectWebSocket"
>
连接
</el-button>
<el-button type="danger" :disabled="!isConnected" @click="disconnectWebSocket">
断开
</el-button>
</el-col>
<el-col :span="6" class="text-right">
连接状态:
<el-tag v-if="isConnected" type="success">已连接</el-tag>
<el-tag v-else type="info">已断开</el-tag>
</el-col>
</el-row>
</el-card>
<!-- 广播消息发送部分 -->
<el-card class="mt-5">
<el-form label-width="90px">
<el-form-item label="消息内容">
<el-input v-model="topicMessage" type="textarea" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="sendToAll">发送广播</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 点对点消息发送部分 -->
<el-card class="mt-5">
<el-form label-width="90px">
<el-form-item label="消息内容">
<el-input v-model="queueMessage" type="textarea" />
</el-form-item>
<el-form-item label="消息接收人">
<el-input v-model="receiver" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="sendToUser">发送点对点消息</el-button>
</el-form-item>
</el-form>
</el-card>
</el-col>
<!-- 消息接收显示部分 -->
<el-col :span="12">
<el-card>
<div class="chat-messages-wrapper">
<div
v-for="(message, index) in messages"
:key="index"
:class="[
message.type === 'tip' ? 'system-notice' : 'chat-message',
{
'chat-message--sent': message.sender === 'sent',
'chat-message--received': message.sender !== 'received',
},
]"
>
<template v-if="message.type != 'tip'">
<div class="chat-message__content">
<div
:class="{
'chat-message__sender': message.sender === 'sent',
'chat-message__receiver': message.sender !== 'received',
}"
>
{{ message.sender }}
</div>
<div class="text-gray-600">{{ message.content }}</div>
</div>
</template>
<div v-else>{{ message.content }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts">
// 用户信息类型
interface UserInfo {
username: string;
}
// 消息类型
interface Message {
sender: string;
content: string;
type: "sent" | "received" | "tip";
}
// 模拟用户信息
const userInfo: UserInfo = {
username: "vue-user",
};
// WebSocket 地址
const socketEndpoint = ref("wss://echo.websocket.org/ws");
// 连接状态
const isConnected = ref(false);
// 消息列表
const messages = ref<Message[]>([]);
// 广播消息内容
const topicMessage = ref("亲爱的朋友们,这是一条广播消息示例!");
// 点对点消息内容
const queueMessage = ref("Hi, 这是一条点对点消息示例!");
const receiver = ref("user2");
// WebSocket 实例
let websocket: WebSocket | null = null;
// 连接 WebSocket
const connectWebSocket = (): void => {
if (isConnected.value) {
ElMessage.warning("WebSocket 已连接");
return;
}
try {
websocket = new WebSocket(socketEndpoint.value);
websocket.onopen = (): void => {
isConnected.value = true;
messages.value.push({
sender: "Server",
content: "WebSocket 连接已建立",
type: "tip",
});
ElMessage.success("WebSocket 连接成功");
};
websocket.onmessage = (event: MessageEvent): void => {
messages.value.push({
sender: "Server",
content: event.data,
type: "received",
});
};
websocket.onerror = (error: Event): void => {
console.error("WebSocket 错误:", error);
ElMessage.error("WebSocket 连接发生错误");
};
websocket.onclose = (): void => {
isConnected.value = false;
messages.value.push({
sender: "Server",
content: "WebSocket 连接已关闭",
type: "tip",
});
ElMessage.info("WebSocket 连接已关闭");
};
} catch (error) {
console.error("创建 WebSocket 连接失败:", error);
ElMessage.error("创建 WebSocket 连接失败");
}
};
// 断开 WebSocket
const disconnectWebSocket = (): void => {
if (websocket && isConnected.value) {
websocket.close();
websocket = null;
isConnected.value = false;
}
};
// 发送广播消息
const sendToAll = (): void => {
if (!isConnected.value || !websocket) {
ElMessage.warning("请先连接 WebSocket");
return;
}
if (!topicMessage.value.trim()) {
ElMessage.warning("消息内容不能为空");
return;
}
websocket.send(topicMessage.value);
messages.value.push({
sender: userInfo.username,
content: topicMessage.value,
type: "sent",
});
};
// 发送点对点消息
const sendToUser = (): void => {
if (!isConnected.value || !websocket) {
ElMessage.warning("请先连接 WebSocket");
return;
}
if (!queueMessage.value.trim()) {
ElMessage.warning("消息内容不能为空");
return;
}
// 注意:wss://echo.websocket.org 会原样返回消息,不会区分接收人
// 这里只是模拟发送点对点消息
const message = `[To: ${receiver.value}] ${queueMessage.value}`;
websocket.send(message);
messages.value.push({
sender: userInfo.username,
content: message,
type: "sent",
});
};
onMounted(() => {
// 可以设置自动连接
// connectWebSocket();
});
onBeforeUnmount(() => {
disconnectWebSocket();
});
</script>
<style scoped lang="scss">
.chat-messages-wrapper {
display: flex;
flex-direction: column;
gap: 10px;
}
.chat-message {
max-width: 80%;
padding: 10px;
border-radius: 5px;
&--sent {
align-self: flex-end;
background-color: #dcf8c6;
}
&--received {
align-self: flex-start;
background-color: #e8e8e8;
}
&__content {
display: flex;
flex-direction: column;
color: var(--el-text-color-primary); // 使用主题文本颜色
}
&__sender {
margin-bottom: 5px;
font-weight: bold;
text-align: right;
}
&__receiver {
margin-bottom: 5px;
font-weight: bold;
text-align: left;
}
}
.system-notice {
align-self: center;
padding: 5px 10px;
font-size: 0.9em;
color: var(--el-text-color-secondary);
background-color: var(--el-fill-color-lighter);
border-radius: 15px;
}
</style>
本文来自博客园,作者:VipSoft 转载请注明原文链接:https://www.cnblogs.com/vipsoft/p/19058598
浙公网安备 33010602011771号