Rust 中的 HTTP 服务器推送(流式传输)客户端?

Posted

技术标签:

【中文标题】Rust 中的 HTTP 服务器推送(流式传输)客户端?【英文标题】:A client for HTTP server push (streaming) in Rust? 【发布时间】:2015-04-12 02:29:32 【问题描述】:

由于没有更好的例子,假设我想用 Rust 编写一个简单的客户端,它可以建立连接并从Twitter's HTTP Streaming API 接收数据。这可能吗?我一直在关注Iron 和Nickel 这两个看起来不错的框架,但我认为他们还没有这个功能?

【问题讨论】:

【参考方案1】:

http 客户端 hyper 支持增量读取响应(作为实现 rust 的 Reader 特征的任何东西),但我找不到任何东西来解析增量响应,或者实现twitter 的特定协议(以\r\n 结束对象)。

也就是说,我能够实现一个快速的概念证明:

编辑:查看并使用它on github。

use rustc_serialize::json::Json;
use std::str;

pub trait JsonObjectStreamer 
    fn json_objects(&mut self) -> JsonObjects<Self>;


impl<T: Buffer> JsonObjectStreamer for T 
    fn json_objects(&mut self) -> JsonObjects<T> 
        JsonObjects  reader: self 
    


pub struct JsonObjects<'a, B> where B: 'a 
    reader: &'a mut B


impl<'a, B> Iterator for JsonObjects<'a, B> where B: Buffer + 'a 
    type Item = Json;

    fn next(&mut self) -> Option<Json> 
        let mut line_bytes = match self.reader.read_until(b'\r') 
            Ok(bytes) => bytes,
            Err(_)    => return None,
        ;

        if line_bytes.last() == Some(&b'\r') 
            // drop the \r
            line_bytes.pop();

            // skip the \n
            match self.reader.read_char() 
                Ok(_)  => (),
                Err(_) => return None,
            
        

        let line = match str::from_utf8(&line_bytes) 
            Ok(line) => line,
            Err(_)   => return None
        ;

        Json::from_str(line).ok()
    

用法:(假设您已将其放在项目的src/json_streamer.rs 文件中)

#![feature(io)]

extern crate hyper;
extern crate "rustc-serialize" as rustc_serialize;

mod json_streamer;

use hyper::Client;

use std::old_io::BufferedReader;
use json_streamer::JsonObjectStreamer;

fn main() 
    let mut client = Client::new();
    let res = client.get("http://localhost:4567/").send().unwrap();

    for obj in BufferedReader::new(res).json_objects() 
        println!("object arrived: ", obj);
    

我用这个小小的 sinatra 应用来测试它:

require 'sinatra'
require 'json'

class Stream
  def each
    hash =  index: 0 

    loop do
      hash[:index] += 1
      yield hash.to_json + "\r\n"
      sleep 0.5
    end
  end
end

get '/' do
  Stream.new
end

【讨论】:

我似乎无法编译它...获取failed to run custom build command for 'openssl-sys v0.3.5' Process didn't exit successfully: '/home/user/code/hello_rust/target/build/openssl-sys-6694e080744fb2e2/build-script-build' (status=101) --- stderr thread '&lt;main&gt;' panicked at 'Unable to find openssl libraries', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/openssl-sys-0.3.5/build.rs:46 @Caballero 看来您缺少一些 openssl 依赖项。我建议你看看rust-openssl's readme 谢谢,完全错过了libssl-dev 依赖

以上是关于Rust 中的 HTTP 服务器推送(流式传输)客户端?的主要内容,如果未能解决你的问题,请参考以下文章

从 Java Swing App 中的 URL 流式传输音频

gRPC 客户端流是如何实现的

使用 httpc lib 将大型 http 响应流式传输到 Erlang 中的磁盘

极客漫画:HTTP2 服务器推送

适用于 iPhone 的 HTTP 实时流式传输

使用 GWT 进行在线音乐流式传输