Dart http.client 未接收到 SSE“数据”字段

Posted

技术标签:

【中文标题】Dart http.client 未接收到 SSE“数据”字段【英文标题】:SSE "data" field not being received by Dart http.client 【发布时间】:2021-08-18 23:29:07 【问题描述】:

我正在构建一个从服务器接收 SSE 并将其转换为特定通知的 Flutter 应用程序。服务器是一个 Spring Boot 应用,返回包含 "event:""data:" 字段的事件:

public void pushNotification(String username, PushEvent event) 
    var emitter = emitters.get(username);
    if (emitter == null) 
        return;
    

    try 
        emitter.send(event.toSseEvent());
     catch (IOException e) 
        log.debug("Could not send event for user " + username);
        emitters.remove(username);
    


public class PushEvent 
    private String type;
    private Map<String, Object> body;

    public SseEmitter.SseEventBuilder toSseEvent() 
        return SseEmitter.event().name(type).data(body);
    

在 Flutter 应用上,我使用 Dart http package 打开一个 Stream 并接收事件:

Future<void> subscribe() async 
if (!_userModel.hasAuthentication()) 
  return;


var user = _userModel.user as AuthenticatedUser;
var username = user.username;
var token = _userModel.getToken();

var uri = Uri.https(ApiUtils.API_BASE, '/api/push/subscribe/$username');
try 
  var client = http.Client();
  _client = client;

  var request = new http.Request("GET", uri);
  request.headers["Accept"] = "text/event-stream";
  request.headers["Cache-Control"] = "no-cache";
  request.headers["Authorization"] = token;

  var response = await client.send(request);
  if (response.statusCode == 200) 
    _isSubscribed = true;
    response.stream.toStringStream().forEach((value) 
      var event = ServerEvent.parse(value);
      _handleEvents(event);
    ).onError((error, stackTrace) 
      log.info("Connection closed");
      log.info(error);
      log.info(stackTrace);
      unsubscribe();
    ).whenComplete(() 
      log.info("Connection completed");
      unsubscribe();
      subscribe();
    );
   else 
    _isSubscribed = false;
  
  notifyListeners();
 catch (e) 
  unsubscribe();
  log.warning("Could not subscribe to notifications");
  log.warning(e);

但是,当我从服务器接收到包含数据的事件时,数据不会显示在日志中:

I/flutter (14779): event:FRIEND_REQUEST
I/flutter (14779): data:

我确定数据是由服务器发送的,因为同一域上的 React 应用程序会解码 SSE 并按预期显示通知:

const subscribePush = () => 
  const username = sessionStorage.getItem('loggedUsername');
  const token = sessionStorage.getItem('token');
  var es = new EventSourcePolyfill(
    '/api/push/subscribe/' + username,
    
      headers: 
        "Authorization": token,
      
    
    );
  
  es.onerror = () => es.close();
  es.addEventListener("FRIEND_REQUEST", e => handleFriendRequestEvent(e));
  es.addEventListener("FRIEND_ACCEPT", e => handleFriendAcceptEvent(e));


const handleFriendRequestEvent = function (event) 
  const username = sessionStorage.getItem("loggedUsername");
  const data = JSON.parse(event.data);
  const source = data.source;
  if (source !== username) 
    var note  = `$source solicitou sua amizade!`;
    var newNotifs = notifications.concat(note);
    setNotifications(newNotifs);
    setNewNotifications(newNotifications + 1);
  

Flutter 应用上的请求中是否缺少某些内容,或者它可能是一个错误?

【问题讨论】:

【参考方案1】:

你的实现看起来和这个很相似:

https://github.com/stevenroose/dart-eventsource

查看客户端实现以及如何使用decoder.dart 文件解码响应。

【讨论】:

以上是关于Dart http.client 未接收到 SSE“数据”字段的主要内容,如果未能解决你的问题,请参考以下文章

Dart/Flutter POST 请求和流响应

go语言SSE客户端

Dart 中的模拟 http.Client 给出异常

C++ SSE:存储到数组后的未定义行为

Heroku 上的 Sinatra/Thin 未检测到 HTTP 流连接 (SSE) 客户端断开连接

在 Angular 5 中接收通量 SSE