3
對於缺乏更好的例子,假設我想用Rust編寫一個簡單的客戶端,它可以建立連接並從Twitter's HTTP Streaming API接收數據。這可能嗎?我一直在關注Iron和Nickel這看起來很不錯的框架,但我不認爲他們有這個功能呢?在Rust中HTTP服務器推送(流媒體)的客戶端?
對於缺乏更好的例子,假設我想用Rust編寫一個簡單的客戶端,它可以建立連接並從Twitter's HTTP Streaming API接收數據。這可能嗎?我一直在關注Iron和Nickel這看起來很不錯的框架,但我不認爲他們有這個功能呢?在Rust中HTTP服務器推送(流媒體)的客戶端?
HTTP客戶端hyper支持只讀取響應遞增(如任何實現生鏽的Reader
性狀),但我沒能找到任何解析響應遞增,或實現Twitter的特定協議(與結束objecs \r\n
)。
這麼說,我是能夠實現概念的quick'n'dirty證明:
編輯:見與它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);
}
}
我用這個小小的西納特拉的應用程序進行測試:
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
我可以't似乎無法編譯它...獲取'未能運行'openssl-sys v0.3.5'的自定義構建命令' 過程未成功退出:'/ home/user/code/hello_rust/target/build/OpenSSL的-SYS-6694e080744fb2e2/BUIL d-script-build'(status = 101) --- stderr 線程''''找不到openssl庫',/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/openssl -sys-0.3.5/build.rs:46' –
Caballero
2015-02-12 15:18:52
@Caballero看來你錯過了一些openssl的依賴關係。我建議你看看[rust-openssl's readme](https://github.com/sfackler/rust-openssl/) – 2015-02-12 16:34:37
謝謝,完全錯過了'libssl-dev'依賴 – Caballero 2015-02-12 16:53:30