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)
    }
  }
}

 

posted @ 2025-09-25 15:33  流年sugar  阅读(9)  评论(0)    收藏  举报