Emitting global events from websocket listener(从 websocket 监听器发出全局事件)
问题描述
I want to contribute to a project - it's written in Vue, and I am a beginner in Vue.
I have two components - Setup
and MainApp
Both will need to update some state based on different messages from the websocket. Some websocket messages will affect the former, some the latter.
Vue doesn't know services, so I thought I'd just create a custom component, with empty <template>
. instantiate the websocket there and then issue an this.emit()
every time a new message occurs in the listener.
Both other components would listen to the emits and would be able to react.
Unfortunately, I can't get the websocket component to work.
main.js:
import Ws from './WsService.vue';
//other imports
const routes = [
//routes
]
const router = new VueRouter({
routes // short for `routes: routes`
})
const app = new Vue({
router
}).$mount('#app')
//I thought this to be the way to instantiate my webSocket service:
const WsService = new Vue({
el: '#WsService',
components: { Ws }
});
index.html
<body>
<div id="app">
<div id="WsService"></div>
<router-link to="/setup">Setup</router-link>
<router-link to="/main-app">Main App</router-link>
<router-view></router-view>
</div>
<script src="/dist/demo-app.js"></script>
</body>
the websocket "service":
<template>
</template>
<script>
const PORT_LOCAL = 9988;
var ws = new WebSocket("ws://localhost:" + PORT_LOCAL);
ws.onopen = function() {
ws.send('{"jsonrpc":"2.0","id":"reg","method":"reg","params":null}');
};
ws.onerror = function(e) {
console.log("error in WebSocket connection!");
console.log(e);
};
export default {
data() {
return {
}
},
created() {
var self = this;
ws.onmessage = function(m) {
var msg = JSON.parse(m.data);
switch(msg.id) {
// result for address request
case "reg":
self.$emit("reg_received", msg.result);
break;
case "send":
self.$emit("send_received", msg.result);
break;
case "subscribe":
self.$emit("subscribe_received", msg.result);
break;
default:
console.log(msg);
break;
}
}
},
methods: {
},
send(id, method, params) {
ws.send('{"jsonrpc":"2.0","id":"' + id + '","method":"' + method + '","params":null}');
}
}
}
</script>
Send for example from main app (this seems to work):
import WsSvc from './WsService.vue';
export default {
data() {
//
},
subscribe() {
let jsonrpc = "the jsonrpc string";
WsSvc.send(jsonrpc);
}
}
Listening to emit
:
export default {
data() {
//
},
created() {
this.$on("reg_received", function(result){
//do smth with the result
});
}
}
Wit this configuration, the created
hook actually never gets called - and thus I'll never hit the onmessage
listener. The reason to have a custom component I thought was that I would have access to the emit
function.
It feels I am making it more complicated than it should be but I haven't managed yet to get it right. The solution doesn't need to follow this approach.
There's no need for a socket specific component in this case. What I have done in the past on a couple projects is implement an API or store object that handles the socket messages and then import that API or store into the components that need it. Also in a similar answer, I show how to integrate a WebSocket with Vuex.
Here is an example that combines the concept of using Vue as an event emitter with a web socket that can be imported into any component. The component can subscribe and listen to the messages it wants to listen to. Wrapping the socket in this way abstracts the raw socket interface away and allows users to work with $on/$off subscriptions in a more typically Vue fashion.
Socket.js
import Vue from "vue"
const socket = new WebSocket("wss://echo.websocket.org")
const emitter = new Vue({
methods:{
send(message){
if (1 === socket.readyState)
socket.send(message)
}
}
})
socket.onmessage = function(msg){
emitter.$emit("message", msg.data)
}
socket.onerror = function(err){
emitter.$emit("error", err)
}
export default emitter
Here is an example of that code being used in a component.
App.vue
<template>
<ul>
<li v-for="message in messages">
{{message}}
</li>
</ul>
</template>
<script>
import Socket from "./socket"
export default {
name: 'app',
data(){
return {
messages: []
}
},
methods:{
handleMessage(msg){
this.messages.push(msg)
}
},
created(){
Socket.$on("message", this.handleMessage)
},
beforeDestroy(){
Socket.$off("message", this.handleMessage)
}
}
</script>
And here is a working example.
这篇关于从 websocket 监听器发出全局事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从 websocket 监听器发出全局事件
- 在不使用循环的情况下查找数字数组中的一项 2022-01-01
- 如何向 ipc 渲染器发送添加回调 2022-01-01
- 从原点悬停时触发 translateY() 2022-01-01
- 是否可以将标志传递给 Gulp 以使其以不同的方式 2022-01-01
- 为什么悬停在委托事件处理程序中不起作用? 2022-01-01
- 为什么我的页面无法在 Github 上加载? 2022-01-01
- 使用 iframe URL 的 jQuery UI 对话框 2022-01-01
- 如何显示带有换行符的文本标签? 2022-01-01
- 如何调试 CSS/Javascript 悬停问题 2022-01-01
- 我不能使用 json 使用 react 向我的 web api 发出 Post 请求 2022-01-01