Rust 中用于 HTTP 服务器推送(流式传输)的客户端?
A client for HTTP server push (streaming) in Rust?
由于缺少更好的示例,假设我想用 Rust 编写一个简单的客户端,它可以建立连接并从 Twitter's HTTP Streaming API. Is this possible yet? I've been keeping an eye on Iron and Nickel 接收数据,这看起来是不错的框架,但我不认为他们有这个功能了吗?
http 客户端 hyper 支持增量读取响应(就像任何实现 rust 的 Reader
特性的东西一样),但我找不到任何东西来 parse 递增响应,或者实现 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
由于缺少更好的示例,假设我想用 Rust 编写一个简单的客户端,它可以建立连接并从 Twitter's HTTP Streaming API. Is this possible yet? I've been keeping an eye on Iron and Nickel 接收数据,这看起来是不错的框架,但我不认为他们有这个功能了吗?
http 客户端 hyper 支持增量读取响应(就像任何实现 rust 的 Reader
特性的东西一样),但我找不到任何东西来 parse 递增响应,或者实现 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