299 lines
7.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-link
class="mb-[20px]"
href="https://gitee.com/youlaiorg/vue3-element-admin/blob/master/src/views/demo/websocket.vue"
target="_blank"
type="primary"
>示例源码 请点击>>>>
</el-link
>
<el-row :gutter="10">
<el-col :span="12">
<el-card>
<el-row>
<el-col :span="16">
<el-input v-model="socketEndpoint" class="w-220px"/>
<el-button
:disabled="isConnected"
class="ml-5"
type="primary"
@click="connectWebSocket"
>连接
</el-button
>
<el-button
:disabled="!isConnected"
type="danger"
@click="disconnectWebSocket"
>断开
</el-button
>
</el-col>
<el-col :span="8" class="text-right">
连接状态:
<el-tag v-if="isConnected" class="ml-2" type="success"
>已连接
</el-tag
>
<el-tag v-else class="ml-2" 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="queneMessage" 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="message-container">
<div
v-for="(message, index) in messages"
:key="index"
:class="{
'tip-message': message.type === 'tip',
message: message.type !== 'tip',
'message--sent': message.sender === userStore.user.username,
'message--received': message.sender !== userStore.user.username,
}"
>
<div v-if="message.type != 'tip'" class="message-content">
<div
:class="{
'message-sender':
message.sender === userStore.user.username,
'message-receiver':
message.sender !== userStore.user.username,
}"
>
{{ message.sender }}
</div>
<div class="color-#333">{{ message.content }}</div>
</div>
<div v-else>{{ message.content }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<!-- websocket 示例 -->
<script lang="ts" setup>
//与主进程通信
import {invoke, vueListen, IpcChannel} from "@/utils/ipcRenderer";
import {useUserStoreHook} from "@themeDefault/store/modules/user";
import {TOKEN_KEY} from "@themeDefault/enums/CacheEnum";
/**
* STOMPStreaming Text Oriented Messaging Protocol是一种简单且广泛使用的TCP套接字上的消息协议允许客户端通过标准的帧格式向服务器发送和接收消息。
*/
// import Stomp from "stompjs";
// import SockJS from "sockjs-client";
const userStore = useUserStoreHook();
const isConnected = ref(false);
var baseURL = __CONFIG__.BASE_API;
baseURL = "http://127.0.0.1:8888"
const socketEndpoint = ref(baseURL + "/ws"); // 本地
const receiver = ref("root");
interface MessageType {
type?: string; // 消息类型: tip-提示消息
sender?: string;
content: string;
}
const messages = ref<MessageType[]>([]);
const topicMessage = ref(
"亲爱的大冤种们由于一只史诗级的BUG系统版本已经被迫回退到了0.0.1。"
); // 广播消息
const queneMessage = ref(
"hi , " +
receiver.value +
" , 我是" +
userStore.user.username +
" , 想和你交个朋友 ! "
);
function sendToAll() {
// stompClient.send("/app/sendToAll", {}, topicMessage.value);
socket.send("/app/sendToAll", {}, "我是从ws客户端发出来的消息");
messages.value.push({
sender: userStore.user.username,
content: topicMessage.value,
});
}
function sendToUser() {
// stompClient.send("/app/sendToUser/" + receiver.value, {}, queneMessage.value);
socket.send("/app/sendToUser/" + receiver.value, {}, queneMessage.value);
messages.value.push({
sender: userStore.user.username,
content: queneMessage.value,
});
}
let stompClient, socket;
function connectWebSocket() {
//先让主进程开启WS服务器
invoke(IpcChannel.StartWsServer).then((r) => {
console.log(r);
});
// socket = new SockJS(socketEndpoint.value);
socket = new WebSocket("ws://localhost:8888/ws");
socket.onopen = (r) => {
console.log("WebSocket监测-连接", r);
isConnected.value = true;
socket.send("ping");
};
socket.onmessage = (r) => {
console.log("WebSocket监测-消息", r);
};
// stompClient = Stomp.over(socket);
//
// stompClient.connect(
// { Authorization: localStorage.getItem(TOKEN_KEY) },
// () => {
// isConnected.value = true;
// messages.value.push({
// sender: "Server",
// content: "Websocket 已连接",
// type: "tip",
// });
//
// stompClient.subscribe("/topic/notice", (res: any) => {
// messages.value.push({
// sender: "Server",
// content: res.body,
// });
// });
//
// stompClient.subscribe("/user/queue/greeting", (res) => {
// const messageData = JSON.parse(res.body) as MessageType;
// messages.value.push({
// sender: messageData.sender,
// content: messageData.content,
// });
// });
// },
// (error) => {
// console.log("连接失败: " + error);
// isConnected.value = false; // 更新连接状态
// messages.value.push({
// sender: "Server",
// content: "Websocket 已断开",
// type: "tip",
// });
// }
// );
}
function disconnectWebSocket() {
if (stompClient && stompClient.connected) {
stompClient.disconnect(() => {
isConnected.value = false; // 更新连接状态
messages.value.push({
sender: "Server",
content: "Websocket 已断开",
type: "tip",
});
});
}
}
onMounted(() => {
// connectWebSocket();
//测试监听主进程事件 TBD,没写对,待完成
// vueListen(channels("StartWsServer"), (r) => {
// console.log(r);
// sendToUser()
// });
});
</script>
<style scoped>
.message-container {
display: flex;
flex-direction: column;
}
.message {
padding: 10px;
margin: 10px;
border-radius: 5px;
}
.message--sent {
align-self: flex-end;
background-color: #dcf8c6;
}
.message--received {
align-self: flex-start;
background-color: #e8e8e8;
}
.message-content {
display: flex;
flex-direction: column;
}
.message-sender {
margin-bottom: 5px;
font-weight: bold;
text-align: right;
}
.message-receiver {
margin-bottom: 5px;
font-weight: bold;
text-align: left;
}
.tip-message {
align-self: center;
padding: 5px 10px;
margin-bottom: 5px;
font-style: italic;
text-align: center;
background-color: #f0f0f0;
border-radius: 5px;
}
</style>