Skip to main content
Version: v3

Server-sent events send request

strategy type

use hook

Before using extended hooks, make sure you are familiar with the basic use of alova.

This hook is implemented using the EventSource API.

::: warning note

When you are not to be used in useSSE add custom header, because the standard does not contain the behavior

:::

Features

  • A simpler and easier way to use;
  • Automatically manage connections;

Usage

import { useSSE } from 'alova/client';

const method = (value: string) => alova.Get('/api/source', { param: { key: value } });
const {
// Received data, each reception will modify data
data,

// Current EventSource instance
eventSource,

// Connection status, 0-connecting, 1-open, 2-closed
readyState,

// Bind connection event
onOpen,

// Bind message reception
onMessage,

// Bind error event
onError,

// Bind custom event
on,

// Connect and send message
send,

// Close connection
close
} = useSSE(method, {
withCredentials: true, // Will be passed to EventSource
initialData: 'initial-data' // Data in data at the beginning
});

Send request

By default, no request will be sent. You need to call send to send the request, or you can set immediate = true to send the request immediately.

const { data, eventSource, readyState, onMessage, onError, on, send, close } = useSSE(method, {
immediate: true
});

useSSE can only connect to one source at present. That is, when trying to connect to multiple targets, the previous connection will always be disconnected.

const { data, eventSource, readyState, onMessage, onError, on, send, close } = useSSE(method);

send('value1');
send('value2'); // This will disconnect the previous connection
send('value3'); // This will also disconnect the previous connection

Receive data

When data is received, it will automatically be assigned to the state data. You can bind it directly to the view, or listen to it to perform some operations.

<template>
<div>
<span v-if="readyState === 0">Connecting</span>
<span v-else-if="readyState === 1">Connected</span>
<span v-else-if="readyState === 2">Disconnected</span>
</div>
<div>Last received data: {{data}}</div>
<ul>
<li
v-for="item in dataList"
:key="item">
{{item}}
</li>
</ul>
<button @click="send">Connect</button>
<button @click="close">Close</button>
</template>

<script setup>
import { ref } from 'vue';

const { data, readyState, onMessage, close, send } = useSSE(method);
const dataList = ref([]);
onMessage(({ data }) => {
dataList.value.push(data);
});
</script>

Binding events

useSSE provides a series of binding event methods, and will return the unbinding function when binding.

const { onMessage, onError, close } = useSSE(method);

// Corresponding to the message event of eventsource
const offMessage = onMessage(event => {
console.log(event.eventSource); // Current EventSource instance
console.log(event.data);
});

const offError = onError(event => {
console.log(event.eventSource); // Current EventSource instance
console.error('sse error', event.error);
close();
});

// Unbind event
offMessage();
offError();

In addition, you can also listen to custom EventSource events, which will call the addEventListener binding of EventSource.

const { on } = useSSE(method);

// The following code will listen for events with the field `event: update`
const offUpdate = on('update', event => {
console.log(event.eventSource); // Current EventSource instance
console.log(event.data);
});

Global response interception

By default, response data is captured by the global response interceptor. If this is not the behavior you expect, you can turn it off manually.

const { data, readyState, onMessage, on } = useSSE(method, {
interceptByGlobalResponded: false // Now dataWill not be intercepted by response
});

Type declaration

const enum SSEHookReadyState {
CONNECTING = 0,
OPEN = 1,
CLOSED = 2
};

type SSEHookConfig = {
/**
* Will be passed to new EventSource
*/
withCredentials?: boolean;

/**
* Whether to intercept by responding of alova instance
* @default true
*/
interceptByGlobalResponded?: boolean;

/**
* Initial data
*/
initialData?: any;

/**
* Whether to initiate a request immediately
* @default false
*/
immediate?: boolean;
};

type SSEReturnType<S, Data> = {
readyState: ExportedType<SSEHookReadyState, S>;
data: ExportedType<Data | undefined, S>;
eventSource: ExportedType<EventSource | undefined, S>;
/**
* Manually initiate a request. This method is automatically triggered when `immediate: true` is used
* @param args request parameters, which will be passed to method
*/
send: (...args: any[]) => Promise<void>;
/**
* Close the connection
*/
close: () => void;
/**
* Register the callback function of EventSource open
* @param callback callback function
* @returns cancel the registration function
*/
onOpen(callback: SSEOnOpenTrigger): () => void;

/**
* Register the callback function of EventSource message
* @param callback callback function
* @returns cancel the registration function
*/
onMessage<T = Data>(callback: SSEOnMessageTrigger<T>): () => void;

/**
* Register the callback function of EventSource error
* @param callback callback function
* @returns cancel the registration function
*/
onError(callback: SSEOnErrorTrigger): () => void;

/**
* @param eventName event name, default exists `open` | `error` | `message`
* @param handler event handler
*/
on(
eventName: string,
handler: (event: AlovaSSEMessageEvent<S, E, R, T, RC, RE, RH>) => void
) => () => void;
};