Dart/Flutter POST 请求和流响应

Posted

技术标签:

【中文标题】Dart/Flutter POST 请求和流响应【英文标题】:Dart/Flutter POST request and stream response 【发布时间】:2020-11-21 11:54:58 【问题描述】:

我想向相机发送一个 POST 请求并接收一个 motionJPEG 流返回。我正在使用 Dart http 包。据我所知,我不能使用http.post 接收流作为响应。我正在尝试使用http.Client.send。我不知道如何为http.Request 创建正确的正文和标题。

大多数 IP 摄像机使用 GET 来访问 MotionJPEG 字节流。但是,我使用的相机是 RICOH THETA 相机,它需要一个带有有效负载的 POST 命令才能发送到相机。如果有人知道我如何使用 dart http 模块创建正确的 POST 请求以返回带有标题和正文的流,请帮助。

import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';

main() async 
  Uri url = Uri.parse('https://192.168.1.1/osc/commands/execute');
  var request = http.Request('POST', url);

  Map<String, String> bodyMap = 'name': 'camera.getLivePreview';
  request.body = jsonEncode(bodyMap);

  Map<String, String> headers = "Content-type": "application/json";
  http.Client client = http.Client();
  StreamSubscription videoStream;
  client.head(url, headers: headers);
  client.send(request).then((response) 
    var startIndex = -1;
    var endIndex = -1;
    List<int> buf = List<int>();
    videoStream = response.stream.listen((List<int> data) 
      for (var i = 0; i < data.length; i++) 
        print(data[i]);
      
    );
  );

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,您所做的实际上是正确的,但HTTP 包修改了您的请求并添加了一些额外的细节,所以宁愿使用dart:io HttpClient

示例代码

import 'dart:convert';
import 'dart:io';
import 'dart:async';

main() async 
   String url =
  'https://pae.ipportalegre.pt/testes2/wsjson/api/app/ws-authenticate';
  Map map = 
       'data': 'apikey': '12345678901234567890',
  ;

  print(await apiRequest(url, map));
 

 Future<String> apiRequest(String url, Map jsonMap) async 
     HttpClient httpClient = new HttpClient();
     HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
     request.headers.set('content-type', 'application/json');
     request.add(utf8.encode(json.encode(jsonMap)));
     HttpClientResponse response = await request.close();
  // todo - you should check the response.statusCode
     String reply = await response.transform(utf8.decoder).join();
     httpClient.close();
     return reply;
 

为了更清楚,请前往this *** 帖子

【讨论】:

谢谢。我能够使用这个技巧让它工作。 dart 中的 http 包有一些问题太糟糕了。【参考方案2】:

这是如何发送帖子和接收流回的 sn-p。就我而言,我正在获取视频流并提取帧。在 sn-p 中,我提取 10 帧进行测试。

仍然可以使用 dart http 模块,但我还没有想出办法。使用 HttpClient 对我有用,并且在易用性方面大致相同。

import 'dart:async';
import 'dart:io';
import 'dart:convert';

Uri apiUrl = Uri.parse('http://192.168.1.1/osc/commands/execute');

Map payload = 'name': 'camera.getLivePreview';

void main() async 
  var client = HttpClient();
  StreamSubscription videoStream;

  var request = await client.postUrl(apiUrl)
    ..headers.contentType = ContentType.json
    ..write(jsonEncode(payload));

  HttpClientResponse response = await request.close();

  var startIndex = -1;
  var endIndex = -1;

  // frame buffer for a single frame
  List<int> buf = List<int>();
  int counter = 0;

  Duration ts = null;
  Stopwatch timer = Stopwatch();

  timer.start();

// set up list of frames
  var frameList = [];
  for (int frameCount = 0; frameCount < 10; frameCount++) 
    frameList.add(await new File('frame$frameCount.jpg'));
  

  //  Handle the response
  var resStream = response.listen(
    (List<int> data) 
      for (var i = 0; i < data.length - 1; i++) 
        if (data[i] == 0xff && data[i + 1] == 0xd8) 
          startIndex = buf.length + i;
        
        if (data[i] == 0xff && data[i + 1] == 0xd9) 
          endIndex = buf.length + i;
        
      
      buf.addAll(data);


【讨论】:

以上是关于Dart/Flutter POST 请求和流响应的主要内容,如果未能解决你的问题,请参考以下文章

[Dart] Flutter 上传文件

Dart Flutter 通用 Api 响应类 动态类 数据类型

如何通过 Dart/Flutter 中的“application/octet-stream”将 png 文件发送到 Microsoft Custom Vision?

Dart / Flutter Json 解析问题

在 Dart/Flutter 中解析嵌套的 JSON

解析json数组响应/颤动