Rust 如何在Iron中使用服务器发送的事件?

Rust 如何在Iron中使用服务器发送的事件?,rust,iron,Rust,Iron,我有一个小的Rust应用程序,它通过串口接收一些请求,进行一些处理,并将结果保存在本地。我想使用浏览器作为远程监视器,这样我就可以看到正在发生的一切,而且据我所知,SSE在这方面非常好 我试着用熨斗熨,但我找不到保持连接畅通的方法。请求处理程序都需要返回响应,因此我无法继续发送数据 这是我(愚蠢的)尝试: fn监视器(请求:&mut请求)->IronResult{ 让mut headers=headers::new(); set(ContentType(Mime(顶级::文本,次级::事件流,v

我有一个小的Rust应用程序,它通过串口接收一些请求,进行一些处理,并将结果保存在本地。我想使用浏览器作为远程监视器,这样我就可以看到正在发生的一切,而且据我所知,SSE在这方面非常好

我试着用熨斗熨,但我找不到保持连接畅通的方法。请求处理程序都需要返回
响应
,因此我无法继续发送数据

这是我(愚蠢的)尝试:

fn监视器(请求:&mut请求)->IronResult{
让mut headers=headers::new();
set(ContentType(Mime(顶级::文本,次级::事件流,vec![]));
set(CacheControl(vec![CacheDirective::NoCache]);
println!(“{:?}”,要求);
让mut count=0;
环路{
让mut response=response::with((iron::status::Ok,format!((数据:Count!:{},Count));
response.headers=headers.clone();
return Ok(response);//显然不会做我想做的事
计数+=1;
std::thread::sleep_ms(1000);
}
}

我认为简单的答案是:你不能。当前版本的Iron基于单个请求-响应交互。这可以在代码中看到,因为发送响应的唯一方法是返回它;终止处理程序线程

铁托有个问题,它本身就是。甚至还有一些还没有成功


如果您愿意使用Hyper master分支,那么类似的方法似乎是可行的。不能保证这是一个好的解决方案,也不能保证它不会占用您所有的RAM或CPU。但它似乎在Chrome中工作

extern crate hyper;

use std::time::{Duration, Instant};
use std::io::prelude::*;

use hyper::{Control, Encoder, Decoder, Next };
use hyper::server::{Server, HandlerFactory, Handler, Request, Response};
use hyper::status::StatusCode;
use hyper::header::ContentType;
use hyper::net::{HttpStream};


fn main() {
    let address = "0.0.0.0:7777".parse().expect("Invalid address");
    let server = Server::http(&address).expect("Invalid server");

    let (_listen, server_loop) = server.handle(MyFactory).expect("Failed to handle");

    println!("Starting...");
    server_loop.run();
}


struct MyFactory;

impl HandlerFactory<HttpStream> for MyFactory {
    type Output = MyHandler;

    fn create(&mut self, ctrl: Control) -> Self::Output {
        MyHandler {
            control: ctrl,
        }
    }
}


struct MyHandler {
    control: Control,
}

impl Handler<HttpStream> for MyHandler {
    fn on_request(&mut self, _request: Request<HttpStream>) -> Next {
        println!("A request was made");
        Next::write()
    }

    fn on_request_readable(&mut self, _request: &mut Decoder<HttpStream>) -> Next {
        println!("Request has data to read");
        Next::write()
    }

    fn on_response(&mut self, response: &mut Response) -> Next {
        println!("A response is ready to be sent");

        response.set_status(StatusCode::Ok);
        let mime = "text/event-stream".parse().expect("Invalid MIME");
        response.headers_mut().set(ContentType(mime));

        every_duration(Duration:: from_secs(1), self.control.clone());

        Next::wait()
    }

    fn on_response_writable(&mut self, response: &mut Encoder<HttpStream>) -> Next {
        println!("A response can be written");

        // Waited long enough, send some data
        let fake_data = r#"event: userconnect
data: {"username": "bobby", "time": "02:33:48"}"#;

        println!("Writing some data");
        response.write_all(fake_data.as_bytes()).expect("Failed to write");
        response.write_all(b"\n\n").expect("Failed to write");

        Next::wait()
    }
}

use std::thread;

fn every_duration(max_elapsed: Duration, control: Control) {
    let mut last_sent: Option<Instant> = None;
    let mut count = 0;

    thread::spawn(move || {
        loop {
            // Terminate after a fixed number of messages
            if count >= 5 {
                println!("Maximum messages sent, ending");
                control.ready(Next::end()).expect("Failed to trigger end");
                return;
            }

            // Wait a little while between messages
            if let Some(last) = last_sent {
                let elapsed = last.elapsed();
                println!("It's been {:?} since the last message", elapsed);

                if elapsed < max_elapsed {
                    let remaining = max_elapsed - elapsed;
                    println!("There's {:?} remaining", remaining);
                    thread::sleep(remaining);
                }
            }

            // Trigger a message
            control.ready(Next::write()).expect("Failed to trigger write");

            last_sent = Some(Instant::now());
            count += 1;
        }
    });
}
extern crate hyper;

use std::time::{Duration, Instant};
use std::io::prelude::*;

use hyper::{Control, Encoder, Decoder, Next };
use hyper::server::{Server, HandlerFactory, Handler, Request, Response};
use hyper::status::StatusCode;
use hyper::header::ContentType;
use hyper::net::{HttpStream};


fn main() {
    let address = "0.0.0.0:7777".parse().expect("Invalid address");
    let server = Server::http(&address).expect("Invalid server");

    let (_listen, server_loop) = server.handle(MyFactory).expect("Failed to handle");

    println!("Starting...");
    server_loop.run();
}


struct MyFactory;

impl HandlerFactory<HttpStream> for MyFactory {
    type Output = MyHandler;

    fn create(&mut self, ctrl: Control) -> Self::Output {
        MyHandler {
            control: ctrl,
        }
    }
}


struct MyHandler {
    control: Control,
}

impl Handler<HttpStream> for MyHandler {
    fn on_request(&mut self, _request: Request<HttpStream>) -> Next {
        println!("A request was made");
        Next::write()
    }

    fn on_request_readable(&mut self, _request: &mut Decoder<HttpStream>) -> Next {
        println!("Request has data to read");
        Next::write()
    }

    fn on_response(&mut self, response: &mut Response) -> Next {
        println!("A response is ready to be sent");

        response.set_status(StatusCode::Ok);
        let mime = "text/event-stream".parse().expect("Invalid MIME");
        response.headers_mut().set(ContentType(mime));

        every_duration(Duration:: from_secs(1), self.control.clone());

        Next::wait()
    }

    fn on_response_writable(&mut self, response: &mut Encoder<HttpStream>) -> Next {
        println!("A response can be written");

        // Waited long enough, send some data
        let fake_data = r#"event: userconnect
data: {"username": "bobby", "time": "02:33:48"}"#;

        println!("Writing some data");
        response.write_all(fake_data.as_bytes()).expect("Failed to write");
        response.write_all(b"\n\n").expect("Failed to write");

        Next::wait()
    }
}

use std::thread;

fn every_duration(max_elapsed: Duration, control: Control) {
    let mut last_sent: Option<Instant> = None;
    let mut count = 0;

    thread::spawn(move || {
        loop {
            // Terminate after a fixed number of messages
            if count >= 5 {
                println!("Maximum messages sent, ending");
                control.ready(Next::end()).expect("Failed to trigger end");
                return;
            }

            // Wait a little while between messages
            if let Some(last) = last_sent {
                let elapsed = last.elapsed();
                println!("It's been {:?} since the last message", elapsed);

                if elapsed < max_elapsed {
                    let remaining = max_elapsed - elapsed;
                    println!("There's {:?} remaining", remaining);
                    thread::sleep(remaining);
                }
            }

            // Trigger a message
            control.ready(Next::write()).expect("Failed to trigger write");

            last_sent = Some(Instant::now());
            count += 1;
        }
    });
}
var evtSource = new EventSource("http://127.0.0.1:7777");

evtSource.addEventListener("userconnect", function(e) {
    const obj = JSON.parse(e.data);
    console.log(obj);
}, false);