【问题标题】:SSE "data" field not being received by Dart http.clientDart http.client 未接收到 SSE“数据”字段
【发布时间】: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 应用上的请求中是否缺少某些内容,或者它可能是一个错误?

【问题讨论】:

    标签: flutter http dart mobile server-sent-events


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      相关资源
      最近更新 更多