VueSSE
VueSSE enables effortless use of Server-Sent Events by providing a high-level interface to an underlying EventSource.
Install
npm install --save vue-sse
yarn add vue-sse
import VueSSE from 'vue-sse';
Vue.use(VueSSE);
Vue.use(VueSSE, {
format: 'json',
polyfill: true,
url: '/my-events-server',
withCredentials: true,
});
Quickstart
this.$sse.create('/my-events-server')
.on('message', (msg) => console.info('Message:', msg))
.on('error', (err) => console.error('Failed to parse or lost connection:', err))
.connect()
.catch((err) => console.error('Failed make initial connection:', err));
Usage
Clients can be created from the Vue object via Vue.$sse.create(...)
or from within components via this.$sse.create(...)
All of the following are valid calls to create a client:
this.$sse.create('/your-events-endpoint')
to connect to the specified URL without specifying any configthis.$sse.create({ url: '/your-events-endpoint', format: 'json' })
will automatically parse incoming messages as JSONthis.$sse.create({ url: '/your-events-endpoint', withCredentials: true })
will set CORS on the request
Once you've created a client, you can add handlers before or after calling connect()
, which must be called.
Configuration
$sse.create
accepts the following config options when installing VueSSE via Vue.use
and when calling $sse.create
.
Option | Type | Description | Default |
---|
format | "plain" | "json" | (event: MessageEvent) => any | Specify pre-processing, if any, to perform on incoming messages. Messages that fail formatting will emit an error. | "plain" |
url | string | The location of the SSE server. | "" |
withCredentials | boolean | Indicates if CORS should be set to include credentials. | false |
polyfill | boolean | Include an EventSource polyfill for older browsers. | false |
forcePolyfill | boolean | Forces the EventSource polyfill to always be used over native. | false |
polyfillOptions | object | Custom options to provide to the EventSource polyfill. Only used if forcePolyfill is true. | null |
If $sse.create
is called with a string, it must be the URL to the SSE server.
Methods
Once you've successfully connected to an events server, a client will be returned with the following methods:
Name | Description |
---|
connect(): Promise | Connects to the server. Must be called. |
on(event: string, (data: any) => void): SSEClient | Adds an event-specific listener to the event stream. The handler function receives the message as its argument (formatted if a format was specified), and the original underlying Event. For non-event messages, specify "" or "message" as the event. |
once(event: string, (data: any) => void): SSEClient | Same as on(...) , but only triggered once. |
off(event: string, (data: any => void)): SSEClient | Removes the given handler from the event stream. The function must be the same as provided to on /once . |
on('error', (err) => void): SSEClient | Allows your application to handle any errors thrown, such as loss of server connection and pre-processing errors. |
disconnect(): void | Closes the connection. The client can be re-used by calling connect() . Must be called! (Usually, in the beforeDestroy of your component.) |
Properties
Name | Type | Description |
---|
source | EventSource | Returns the underlying EventSource. |
Cleanup
Every connection must be disconnected when the component is destroyed. There are two ways to achieve this:
- Call
disconnect()
on the client during beforeDestroy
, or - Add the following option to your component to have them automatically closed for you during
beforeDestroy
:
export default {
name: 'my-component',
data() { },
sse: {
cleanup: true,
},
}
Vue 3
This plugin works the same in both Vue 2 and 3. The Composition API is not yet supported.
Example
An example project is provided at tserkov/vue-sse-example.
Kitchen Sink
<template>
<div>
<p
v-for="(message, idx) in messages"
:key="idx"
>{{ message }}</p>
</div>
</template>
<script>
let sseClient;
export default {
name: 'sse-test',
data() {
return {
messages: [],
};
},
mounted() {
sseClient = this.$sse.create({
url: '/your-events-server',
format: 'json',
withCredentials: true,
polyfill: true,
});
sseClient.on('error', (e) => {
console.error('lost connection or failed to parse!', e);
});
sseClient.on('message', this.handleMessage);
sseClient.on('chat', this.handleChat);
sseClient.once('ban', this.handleBan);
sseClient.connect()
.then(sse => {
console.log('We\'re connected!');
setTimeout(() => {
sseClient.off('message', this.handleMessage);
console.log('Stopped listening to event-less messages!');
}, 7000);
setTimeout(() => {
sse.off('chat', this.handleChat);
console.log('Stopped listening to chat messages!');
}, 14000);
})
.catch((err) => {
console.error('Failed to connect to server', err);
});
},
methods: {
handleBan(banMessage) {
this.messages.push(`You've been banned! Reason: ${banMessage.reason}`);
},
handleChat(message) {
this.messages.push(`${message.user} said: ${message.text}`);
},
handleMessage(message, lastEventId) {
console.warn('Received a message w/o an event!', message, lastEventId);
},
},
beforeDestroy() {
sseClient.disconnect();
},
};
</script>