SSE服务端向客户端单向推送消息
服务端
[ApiController] [Route("[controller]")] public class SseController : ControllerBase { public async Task SendEvent() { HttpContext.Response.ContentType = "text/event-stream"; HttpContext.Response.Headers["Cache-Control"]= "no-cache"; HttpContext.Response.Headers["Connection"]="no"; try { while (!HttpContext.RequestAborted.IsCancellationRequested ) { var message=new StringBuilder(); message.AppendLine("data: Hello, world!"); message.AppendLine(); //发送消息 await HttpContext.Response.WriteAsync(message.ToString()); // 写入数据到响应后不要忘记 FlushAsync(),因为该api方法是异步的,所以要全程异步,调用同步方法会报错。 await HttpContext.Response.Body.FlushAsync(); // 等待一段时间后再发送下一个消息 await Task.Delay(3000); // 检查连接是否仍然打开 if (HttpContext.Response.HasStarted && HttpContext.Response.Body.CanRead) { var buffer = new byte[256]; var result = await HttpContext.Response.Body.ReadAsync(buffer, 0, buffer.Length); if (result == 0) { // 客户端已断开连接 break; } } } }catch (Exception ex) { } } }
客户端
以VUE为例
安装包:
npm install event-source-polyfill --save
onMounted(() => { initSSE() }) function initSSE() { sse.value = SSEService.subscribeWarnMsg( instance, '/csc/rest/api/Sse/events', function (event: any) { console.log('收到新消息!!!') // var info = JSON.parse(event.data) console.log('sse:', event.data) } ) }
SSEService
import { EventSourcePolyfill } from 'event-source-polyfill'
import storage from 'store'
export default class SSEService {
static subscribeWarnMsg(proxy: any, url: string, onmessage: any) {
const token = storage.get('token')
const eventSource = new EventSourcePolyfill('http://test.go.com'+url, {
heartbeatTimeout: 3 * 60 * 1000,
headers: {
Authorization: 'Bearer ' + token,
Accept: 'text/event-stream'
},
withCredentials: true
})
eventSource.onopen = function (e) {
console.log(e, '连接刚打开时触发')
// e.target.addEventListener('onmessage', function (e: any) {
// console.log('心跳检测', e)
// })
}
eventSource.onmessage = async (event) => {
onmessage(event)
}
eventSource.onerror = (event) => {
console.error('SSE 连接出错:', event)
}
}
}

浙公网安备 33010602011771号