use std::net::TcpStream;
use std::marker::PhantomData;
use std::io::Result as IoResult;
use ws;
use ws::util::url::ToWebSocketUrlComponents;
use ws::receiver::{DataFrameIterator, MessageIterator};
use result::WebSocketResult;
use stream::WebSocketStream;
use dataframe::DataFrame;
use ws::dataframe::DataFrame as DataFrameable;
use openssl::ssl::{SslContext, SslMethod, SslStream};
pub use self::request::Request;
pub use self::response::Response;
pub use sender::Sender;
pub use receiver::Receiver;
pub mod request;
pub mod response;
pub struct Client<F, S, R> {
sender: S,
receiver: R,
_dataframe: PhantomData<fn(F)>
}
impl Client<DataFrame, Sender<WebSocketStream>, Receiver<WebSocketStream>> {
pub fn connect<T: ToWebSocketUrlComponents>(components: T) -> WebSocketResult<Request<WebSocketStream, WebSocketStream>> {
let context = try!(SslContext::new(SslMethod::Tlsv1));
Client::connect_ssl_context(components, &context)
}
pub fn connect_ssl_context<T: ToWebSocketUrlComponents>(components: T, context: &SslContext) -> WebSocketResult<Request<WebSocketStream, WebSocketStream>> {
let (host, resource_name, secure) = try!(components.to_components());
let connection = try!(TcpStream::connect(
(&host.hostname[..], host.port.unwrap_or(if secure { 443 } else { 80 }))
));
let stream = if secure {
let sslstream = try!(SslStream::connect(context, connection));
WebSocketStream::Ssl(sslstream)
}
else {
WebSocketStream::Tcp(connection)
};
Request::new((host, resource_name, secure), try!(stream.try_clone()), stream)
}
pub fn shutdown_sender(&mut self) -> IoResult<()> {
self.sender.shutdown()
}
pub fn shutdown_receiver(&mut self) -> IoResult<()> {
self.receiver.shutdown()
}
pub fn shutdown(&mut self) -> IoResult<()> {
self.receiver.shutdown_all()
}
}
impl<F: DataFrameable, S: ws::Sender, R: ws::Receiver<F>> Client<F, S, R> {
pub fn new(sender: S, receiver: R) -> Client<F, S, R> {
Client {
sender: sender,
receiver: receiver,
_dataframe: PhantomData
}
}
pub fn send_dataframe<D>(&mut self, dataframe: &D) -> WebSocketResult<()>
where D: DataFrameable {
self.sender.send_dataframe(dataframe)
}
pub fn send_message<'m, M, D>(&mut self, message: &'m M) -> WebSocketResult<()>
where M: ws::Message<'m, D>, D: DataFrameable {
self.sender.send_message(message)
}
pub fn recv_dataframe(&mut self) -> WebSocketResult<F> {
self.receiver.recv_dataframe()
}
pub fn incoming_dataframes<'a>(&'a mut self) -> DataFrameIterator<'a, R, F> {
self.receiver.incoming_dataframes()
}
pub fn recv_message<'m, M, I>(&mut self) -> WebSocketResult<M>
where M: ws::Message<'m, F, DataFrameIterator = I>, I: Iterator<Item = F> {
self.receiver.recv_message()
}
pub fn incoming_messages<'a, M, D>(&'a mut self) -> MessageIterator<'a, R, D, F, M>
where M: ws::Message<'a, D>,
D: DataFrameable
{
self.receiver.incoming_messages()
}
pub fn get_sender(&self) -> &S {
&self.sender
}
pub fn get_receiver(&self) -> &R {
&self.receiver
}
pub fn get_mut_sender(&mut self) -> &mut S {
&mut self.sender
}
pub fn get_mut_receiver(&mut self) -> &mut R {
&mut self.receiver
}
pub fn split(self) -> (S, R) {
(self.sender, self.receiver)
}
}