image_stream/
server.rs

1use std::io::prelude::*;
2use image::RgbImage;
3
4use message::*;
5
6#[derive(Debug)]
7pub struct Server<S: Read + Write> {
8    messenger: Messenger<S>,
9    dimensions: (u32, u32)
10}
11
12impl<S: Read + Write> Server<S> {
13    pub fn new(stream: S, dimensions: (u32, u32)) -> Result<Server<S>, String> {
14        let messenger = Messenger::new(stream);
15       
16        match messenger.send(&Message::Dimensions(dimensions)) {
17            Err(e) => return Err(e),
18            Ok(len) => println!("sent {} bytes", len)
19        };
20
21        Ok(Server {
22            messenger,
23            dimensions
24        })
25    }
26
27    pub fn recv(&self) -> Result<RgbImage, String> {
28        let message = match self.messenger.recv() { 
29            Ok(m) => m,
30            Err(e) => return Err(e)
31        };
32
33
34        match message {
35            Message::RgbImage(raw) => {
36                let (width, height) = self.dimensions;
37                match RgbImage::from_raw(width, height, raw) {
38                    Some(image) => Ok(image),
39                    None => Err("Couldn't deserialize RgbImage: Mismatched dimensions".to_string())
40                }
41            },
42            _ => Err("Unexpected Message, expected ImageData".to_string())
43        }
44    }
45}
46
47
48#[cfg(test)]
49mod tests {
50    use std::net::{TcpStream, TcpListener};
51    use std::time;
52    use image::Rgb;
53    use rand::random;
54
55    use super::*;
56    use client::Client;
57    
58    fn server_client(dimensions: (u32, u32)) -> (Server<TcpStream>, Client<TcpStream>) {
59        let server_addr = "127.0.0.1:31415";
60        let listener = TcpListener::bind(server_addr).unwrap();
61        let client_stream = TcpStream::connect(server_addr).unwrap();
62        let (server_stream, _client_addr) = listener.accept().unwrap();
63
64        let server = Server::new(server_stream, dimensions.clone()).unwrap();
65        let client = Client::new(client_stream).unwrap();
66
67        (server, client)
68    }
69
70    #[test]
71    fn dimensions() {
72        let dimensions = (64, 32);
73        let (_server, client) = server_client(dimensions);
74        assert_eq!(dimensions, client.dimensions());
75
76        let (_server, client) = server_client(dimensions);
77        let dimensions = (65, 32);
78        assert_ne!(dimensions, client.dimensions());
79    }
80
81    #[test]
82    fn simple_image() {
83        let (width, height) = (64, 32);
84        let (server, client) = server_client((width, height));
85        let image = RgbImage::from_fn(width, height, |x, y| {
86            let (x, y) = (x as u8, y as u8);
87            if x.wrapping_mul(y) % 5 == 0 {
88                Rgb([x, y, x.wrapping_add(y)])
89            }
90            else {
91                Rgb([255u8.wrapping_sub(y), 255u8.wrapping_sub(x.wrapping_mul(y)), x.wrapping_add(y)])
92            }
93        });
94        client.send(image.clone()).unwrap();
95        let recieved_image = server.recv().unwrap();
96        assert_eq!(image.into_raw(), recieved_image.into_raw());
97    }
98
99    fn framerate(minimum: u8) {
100        let (width, height) = (64, 32);
101        let (server, client) = server_client((width, height));
102        let test_duration = time::Duration::new(2, 0);
103        let start = time::Instant::now();
104        let mut frames = 0;
105
106        let image = RgbImage::from_fn(width, height, |_, _| {
107            Rgb([random::<u8>(), random::<u8>(), random::<u8>()])
108        });
109        let image_raw = image.clone().into_raw();
110
111        while time::Instant::now() - start < test_duration {
112            let t0 = time::Instant::now();
113            for _ in 0..10 {
114                client.send(image.clone()).unwrap();
115            }
116            let t1 = time::Instant::now();
117            for _ in 0..10 {
118                let recieved_image = server.recv().unwrap();
119                assert_eq!(image_raw, recieved_image.into_raw());
120            }
121            let t2 = time::Instant::now();
122            frames += 10;
123            println!("send:   {:?}", t1 - t0);
124            println!("recv:   {:?}", t2 - t1);
125            println!("total : {:?}", t2 - t0);
126            println!("===============");
127        }
128
129        let rate = (frames / test_duration.as_secs()) as u8;
130        println!("Framerate: {}, minimum: {}", rate, minimum);
131        assert!(rate >= minimum);
132    }
133
134    #[test]
135    fn framerate_20() {
136        framerate(20);
137    }
138    
139    #[test]
140    fn framerate_40() {
141        framerate(40);
142    }
143
144    #[test]
145    fn framerate_60() {
146        framerate(60);
147    }
148}