在上一章中,我们介绍了使用@stomp/stompjs实现websocket和后端通信的方法。其实还有一种和@stomp/stompjs极其相似的实现,甚至我怀疑是不同版本而已。但是我不是专注于前端开发,只是因为测试需要所以研究了一下,这个技术就是websocket-client。
经过测试发现websocket-client与@stomp/stompjs的实现几乎一模一样,只在建立连接时有区别。
本片只是简单介绍其中不同之处,其他的实现,请参考:vue实现stompjs+websocket和后端(二)
使用websocket-client需要从新导入相关的组件。
npm install webstomp-client
连接方式:
// 创建SockJS对象
this.socket = new WebSocket('ws://localhost:7000/websocket-demo/stmpwebsocket');
// 创建Stomp客户端实例
let stompClient = StompClient.over(this.socket);
//请求头
let headers = {
'login': 'usename',
'userId': this.userId
}
// 连接WebSocket
stompClient.connect(headers, frame => {
console.log('Connected: ' + frame);
this.connected = true
}, error => {
console.error('STOMP error:', error);
});
还有就是发送,如果需要加入请求头的话。参数顺序有所变化:
stompClient.send(describetion, messagebODY, headers)
其他的如订阅、关闭连接和@stomp/stompjs相似。这里就不说了,也没有详细测试,有问题请大家及时指出。
全部代码如下:
<template>
<div class="f_c float_l">
<div class="m_10 float_l">
<el-input class='input_common' v-model="websocketPath" placeholder="后端websocket地址:http://ip:port/context/websocket-point" ></el-input>
<el-input class='input_common' v-model="userId" placeholder="请输入用户名" ></el-input>
<el-button v-if="!connected" @click=" connectWebsocket" >连接</el-button>
<el-button v-else @click="disConnectWebsocket" >断开</el-button>
</div>
<el-divider />
<div class="f_c" v-if="connected">
<div>
<el-input class='input_common' v-model="messageUrl" placeholder="请输入消息地址:/sendMessage"></el-input>
<el-button @click="sendMessage" v-if="connected">发送</el-button>
</div>
<el-input class='input_common mt_10' v-model="message" type="textarea" :rows="2" placeholder="请输入需要发送的消息"></el-input>
</div>
<el-divider />
<div class="f_c m_10 float_l" v-if="connected">
<div class="float_l">
<el-input class='input_common' v-model="subscribePath" placeholder="请输入监听地址:/subscribe/id"></el-input>
<el-button @click="subscribeTopic" v-if="!subscribed">广播订阅</el-button>
<el-button @click="unSubscribeTopic" v-else>取消订阅</el-button>
</div>
<div class="m_10 f_c">
<span class="float_l">收到消息</span>
<span style="border: aqua; width: 500px; height: 100px">{{receiveMessage}}</span>
</div>
</div>
<div class="f_c m_10 float_l" v-if="connected">
<div class="float_l">
<el-input class='input_common' v-model="userSubscribePath" placeholder="请输入监听地址:/subscribe/id"></el-input>
<el-button @click="subscribeUserTopic" v-if="!userSubscribed">用户订阅</el-button>
<el-button @click="unUserSubscribeTopic" v-else>取消订阅</el-button>
</div>
<div class="m_10 f_c">
<span class="float_l">收到消息</span>
<span style="border: aqua; width: 500px; height: 100px">{{receiveUserMessage}}</span>
</div>
</div>
</div>
</template>
<script>
import StompClient from 'webstomp-client';
export default {
name: "index",
data(){
return {
websocketPath:'localhost:7000/websocket-demo/stmpwebsocket',
userId:'',
subscribePath:'/topic/targetSubscribe',
receiveMessage:'',
userSubscribePath:'/user/queue/123456789',
receiveUserMessage:'',
messageUrl:'/message/stomp/sendMessage',
message:'',
connected: false,
subscribed: false,
userSubscribed:false,
socket:null,
stompClient:null,
pushSubscriptionPromise: null,
pushUserSubscriptionPromise: null
}
},
methods:{
connectWebsocket(){
if(!this.websocketPath){
this.$message.error("请先填写websocket地址信息")
return
}
if(!this.userId){
this.$message.error("请先填写用户信息")
return
}
// 创建SockJS对象
this.socket = new WebSocket('ws://' + this.websocketPath);
// 创建Stomp客户端实例
this.stompClient = StompClient.over(this.socket);
//请求头
let headers = {
'login': 'usename',
'userId': this.userId
}
// 连接WebSocket
this.stompClient.connect(headers, frame => {
console.log('Connected: ' + frame);
this.connected = true
}, error => {
console.error('STOMP error:', error);
});
},
sendMessage(){
if(!this.message || !this.messageUrl){
this.$message.error("请先填写websocket地址和消息内容信息")
return
}
let msg = { message: this.message };
console.log("数据发送:", this.messageUrl, msg)
this.stompClient.send(this.messageUrl, JSON.stringify(msg), {});
},
onceSubscribe(){
this.stompClient.subscribe('/message/subscribe/1232131321', function(message) {
console.log('onceSubscribe-Message: ' + message.body);
})
},
subscribeTopic(){
if(!this.subscribePath){
this.$message.error("请先填写订阅地址")
return
}
// 订阅某个路径
let number = 1
this.subscribed = true
//获取订阅结果用于取消订阅
this.pushSubscriptionPromise = this.stompClient.subscribe(this.subscribePath, message => {
// 处理接收到的消息
console.log('收到消息', message);
let nowMessage = '第' + number + '次收到订阅的消息:' + JSON.stringify(JSON.parse(message.body)) + '\r\n';
this.receiveMessage += nowMessage;
number ++;
});
},
subscribeUserTopic(){
if(!this.userSubscribePath){
this.$message.error("请先填写用户的订阅地址")
return
}
// 订阅某个路径
let number = 1
this.userSubscribed = true
//获取订阅结果用于取消订阅
this.pushUserSubscriptionPromise = this.stompClient.subscribe(this.userSubscribePath, message => {
// 处理接收到的消息
console.log('收到消息', message);
let nowMessage = '第' + number + '次收到订阅的消息:' + JSON.stringify(JSON.parse(message.body)) + '\r\n';
this.receiveUserMessage += nowMessage;
number ++;
});
},
unSubscribeTopic(){
// 订阅某个路径
this.pushSubscriptionPromise.unsubscribe();
this.subscribed = false;
this.receiveMessage = ''
},
unUserSubscribeTopic(){
// 订阅某个路径
this.pushUserSubscriptionPromise.unsubscribe();
this.userSubscribed = false;
this.receiveUserMessage = ''
},
disConnectWebsocket(){
if (this.stompClient != null) {
// 关闭连接
this.stompClient.disconnect()
this.stompClient = null
this.socket.close()
this.socket = null
this.connected = false
this.subscribed = false
this.userSubscribed = false
this.receiveMessage = ''
this.receiveUserMessage = ''
}
},
beforeDestroy(){
if(this.stompClient != null){
this.stompClient.disconnect()
this.stompClient = null
this.socket.close()
this.socket = null
this.connected = false
this.subscribed = false
this.userSubscribed = false
this.receiveMessage = ''
this.receiveUserMessage = ''
}
}
}
}
</script>
<style scoped>
</style>