这里演示的是一种简单的连接和接收消息的方式,如果需要自定义Header和Body之类的,可以使用第三方插件flutter_client_sse
flutter_client_sse:flutter_client_sse | Flutter Package
可以参考JS的EventSource,Flutter也内置了EventSource,使用方法如下:
Flutter接收端代码:
注意,这里的用于创建SSE连接的接口是GET类型的。
对不同的事件添加监听器:
- open:当与服务器端的连接打开时触发。
- message:当从服务器端接收到未命名的事件时触发。
- error:当连接失败或关闭时触发。
- 自定义事件:当从服务器端接收到指定了event字段的事件时触发,事件名称与event字段的值相同。
String sseURL = "http://xxx/sse";
EventSource eventSource = EventSource(sseURL);
eventSource.addEventListener("open", (event) => {
print("连接打开")
});
eventSource.addEventListener("message", (event) => {
print("收到消息:" + event.toString())
});
eventSource.addEventListener("error", (event) => {
print("发生错误:" + event.toString())
});
eventSource.addEventListener("custom", (event) => {
print("收到自定义类型的事件消息:" + event.toString())
});
SpringBoot推送端代码:
private final static Map<String, SseEmitter> SSE_CACHE= new ConcurrentHashMap<>();
// 创建连接
@Override
public SseEmitter createSession() throws IOException {
// 设置过期时间,0L表示永不过期
SseEmitter sseEmitter = new SseEmitter(0L);
String id = UUID.randomUUID().toString().replace("-","");
if (!SSE_CACHE.containsKey(id)){
SSE_CACHE.put(id,sseEmitter);
log.info("客户端:{} 新建连接成功,当前客户端总数为【{}】",id,SSE_CACHE.size() );
}
return sseEmitter;
}
// 断开连接
@Override
public void closeSession(String clientId) {
if (SSE_CACHE.containsKey(clientId)){
SSE_CACHE.get(clientId).complete();
SSE_CACHE.remove(clientId);
log.info("客户端:【{}】 断开成功,当前剩余客户端总数为【{}】",clientId,SSE_CACHE.size());
}
}
// 推送消息
@Override
public void send() {
for (SseEmitter emitter : SSE_CACHE.values()) {
try {
int i = 5;
while (i-- > 0){
log.info("发送一条消息:{}",i);
SseEmitter.SseEventBuilder data = SseEmitter.event().id(UUID.randomUUID().toString()).data("这是一条普通消息..." + i);
// 自定义事件消息
// SseEmitter.SseEventBuilder data = SseEmitter.event().name("custom").id("clewm").data("自定义消息...");
emitter.send(data);
Thread.sleep(1000);
}
}catch (Exception e){
e.printStackTrace();
}
}
}