Vue 2 plugin for reconnecting WebSocket clients.
This plugin installs a reconnecting WebSocket instance on Vue.prototype as
this.$socket, and adds a component-level sockets option so Vue components
can subscribe to socket events with automatic cleanup on destroy.
- Designed for Vue 2.
- Exposes the socket instance as
this.$socket. - Supports component-level
socketsevent handlers. - Automatically binds socket listeners in
beforeCreate. - Automatically removes component socket listeners in
beforeDestroy. - Accepts either an existing socket instance or a socket config object.
- Keeps the underlying reconnecting WebSocket API available.
This package is the Vue integration layer. The socket behavior itself comes from the underlying reconnecting WebSocket client.
The underlying client provides:
- Automatic reconnect.
- Promise-based
send. - Optional reply waiting with timeout.
beforeSendHookandbeforeEmitHook.- Events such as
connect,reconnect,message,close, anderror.
Use a browser environment that supports:
WebSocketPromiseProxyObject.defineProperty
For older browsers, provide the required polyfills before installing the plugin.
This repository contains source code and build scripts. Build the package before
using files from dist/.
npm install
npm run buildAfter build, the generated files are configured as:
dist/vue-plugin-reconentWebsockt.js- UMD build for browsers.dist/vue-plugin-reconentWebsockt.min.js- minified UMD build.dist/vue-plugin-reconentWebsockt.common.js- CommonJS build.dist/vue-plugin-reconentWebsockt.esm.js- ES module build.
Naming note: this repository and build configuration contain historical spelling variants such as
reconenctandreconent. The package name inpackage.jsonisvue-plugin-reconnectWebsocket, while the source currently importsreconenct-websockets. Verify package names before publishing or installing from npm.
import Vue from 'vue'
import VueSocket from 'vue-plugin-reconnectWebsocket'
Vue.use(VueSocket, {
url: 'ws://localhost:3000',
reconnect: true,
autoconnect: true,
reconnectTime: 10,
beforeEmitHook(event) {
return JSON.parse(event.data)
}
})
new Vue({
el: '#app',
render: h => h(App)
})Then use this.$socket and the sockets component option:
export default {
name: 'ChatPanel',
sockets: {
connect() {
console.log('socket connected')
},
reconnect() {
console.log('socket reconnected')
},
message(event) {
console.log(event.data)
},
chat(event) {
this.messages.push(event.data)
}
},
methods: {
sendMessage(text) {
return this.$socket.send({
type: 'chat',
data: text
})
}
}
}If you already created a socket instance, pass it to Vue.use.
import Vue from 'vue'
import VueSocket from 'vue-plugin-reconnectWebsocket'
const socket = new VueSocket('ws://localhost:3000', {
beforeEmitHook(event) {
return JSON.parse(event.data)
}
})
Vue.use(VueSocket, socket)If the second argument has a url field, the plugin creates the socket
internally.
Vue.use(VueSocket, {
url: 'ws://localhost:3000',
reconnect: true,
autoconnect: true,
reconnectTime: 10
})The sockets option maps socket event names to component methods.
export default {
sockets: {
connect(event) {
console.log(event.type)
},
say(text) {
this.messages.push(text)
},
close(event) {
console.log('closed', event)
}
}
}Handlers are registered with the component instance as their context, so this
points to the Vue component.
When the component is destroyed, the plugin removes all handlers declared in
sockets.
The plugin replaces this.$options.sockets with a Proxy, so assigning and
deleting handlers also binds and unbinds socket listeners.
export default {
created() {
this.$options.sockets.notice = this.handleNotice
},
beforeDestroy() {
delete this.$options.sockets.notice
},
methods: {
handleNotice(event) {
console.log(event)
}
}
}Use the underlying socket instance through this.$socket.
this.$socket
.send(
{
type: 'say',
data: 'hello'
},
{
rep: 'say-success',
timeout: 5000,
retry: true
}
)
.then(event => {
console.log('message sent', event)
})
.catch(error => {
console.error(error)
})If rep is provided, the Promise resolves when that event is emitted. If the
reply event is not emitted before timeout, the Promise rejects.
Use beforeEmitHook to parse server messages and route them by type.
Vue.use(VueSocket, {
url: 'ws://localhost:3000',
beforeEmitHook(event) {
try {
return JSON.parse(event.data)
} catch (error) {
return false
}
}
})For this server message:
{
"type": "say",
"data": "hello"
}The component handler below will run:
export default {
sockets: {
say(event) {
console.log(event.data)
}
}
}Use beforeSendHook to normalize outgoing messages before the underlying
WebSocket sends them.
Vue.use(VueSocket, {
url: 'ws://localhost:3000',
beforeSendHook(options, send) {
options.data = JSON.stringify({
type: options.type || 'message',
data: options.data
})
send(options)
}
})| Name | Type | Default | Description |
|---|---|---|---|
url |
string |
required for config install | WebSocket URL used by the plugin when creating a socket internally. |
protocol |
string | string[] |
'' |
WebSocket subprotocol. |
reconnect |
boolean |
true |
Whether to reconnect automatically after unexpected close. |
autoconnect |
boolean |
true |
Whether to connect immediately after socket creation. |
reconnectTime |
number |
10 |
Maximum automatic reconnect counter before emitting reconnet-fail. |
binaryType |
'blob' | 'arraybuffer' |
'blob' |
Binary data type for the native WebSocket. |
beforeSendHook |
function |
undefined |
Hook called before each send. |
beforeEmitHook |
function |
undefined |
Hook called before each incoming message is emitted. |
| Event | Description |
|---|---|
open |
Native WebSocket open event. |
connect |
First successful connection. |
reconnect |
Successful connection after reconnect. |
message |
Native WebSocket message event when no custom beforeEmitHook changes the event type. |
close |
Native WebSocket close event. |
error |
Native WebSocket error or internal send error. |
reconnet-fail |
Emitted when automatic reconnect exceeds the retry counter. The event name keeps the current source spelling. |
| Custom event | Any event object returned by beforeEmitHook with a type field. |
npm install
npm run buildRun the demo server:
npm run devRun the webpack dev server:
npm run startThe example app is in example/main.
ISC