Created
September 5, 2018 11:22
-
-
Save ntr-808/eb805124d55a0adba2b95ff1428fba76 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate failure; | |
#[macro_use] | |
extern crate serde_derive; | |
extern crate serde_cbor; | |
#[macro_use] | |
extern crate yew; | |
use failure::Error; | |
use yew::prelude::*; | |
use yew::services::Task; | |
// use yew::services::fetch::{FetchTask, Request, Response}; | |
use yew::format::{Nothing, Json, Cbor}; | |
use yew::services::websocket::{WebSocketService, WebSocketTask, WebSocketStatus}; | |
use yew::services::ConsoleService; | |
use serde_cbor::{Value,to_value}; | |
struct Cryp { | |
name: String, | |
} | |
pub struct Model { | |
ws_service: WebSocketService, | |
link: ComponentLink<Model>, | |
data: Option<Value>, | |
ws: Option<WebSocketTask>, | |
console: ConsoleService, | |
} | |
pub enum WsAction { | |
Connect, | |
SendData, | |
Disconnect, | |
Lost, | |
} | |
pub enum Msg { | |
WsAction(WsAction), | |
WsReady(Result<WsResponse, Error>), | |
Ignore, | |
} | |
impl From<WsAction> for Msg { | |
fn from(action: WsAction) -> Self { | |
Msg::WsAction(action) | |
} | |
} | |
/// This type is used as a request which sent to websocket connection. | |
#[derive(Serialize, Debug)] | |
struct WsRequest { | |
value: u32, | |
} | |
/// This type is an expected response from a websocket connection. | |
#[derive(Deserialize, Debug)] | |
pub struct WsResponse { | |
value: Vec<u8>, | |
} | |
impl Component for Model { | |
type Message = Msg; | |
type Properties = (); | |
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self { | |
Model { | |
ws_service: WebSocketService::new(), | |
console: ConsoleService::new(), | |
link, | |
data: None, | |
ws: None, | |
} | |
} | |
fn update(&mut self, msg: Self::Message) -> ShouldRender { | |
match msg { | |
Msg::WsAction(action) => { | |
match action { | |
WsAction::Connect => { | |
self.console.log("connecting"); | |
let callback = self.link.send_back(|Cbor(data)| Msg::WsReady(data)); | |
let notification = self.link.send_back(|status| { | |
match status { | |
WebSocketStatus::Opened => Msg::Ignore, | |
WebSocketStatus::Closed | WebSocketStatus::Error => WsAction::Lost.into(), | |
} | |
}) ; | |
let task = self.ws_service.connect("ws://localhost:40000/", callback, notification); | |
self.ws = Some(task); | |
} | |
WsAction::SendData => { | |
let request = WsRequest { | |
value: 321, | |
}; | |
self.ws.as_mut().unwrap().send_binary(Cbor(&request)); | |
} | |
WsAction::Disconnect => { | |
self.ws.take().unwrap().cancel(); | |
} | |
WsAction::Lost => { | |
self.ws = None; | |
} | |
} | |
} | |
Msg::WsReady(response) => { | |
self.console.log("ready"); | |
self.data = match response { | |
Ok(v) => { | |
self.console.log("yay"); | |
Some(to_value(v.value).unwrap()) | |
}, | |
Err(e) => { | |
self.console.log("there was an error"); | |
None | |
}, | |
} | |
} | |
Msg::Ignore => { | |
return false; | |
} | |
} | |
true | |
} | |
} | |
impl Renderable<Model> for Model { | |
fn view(&self) -> Html<Self> { | |
html! { | |
<div> | |
<nav class="menu",> | |
{ self.view_data() } | |
<button disabled=self.ws.is_some(), | |
onclick=|_| WsAction::Connect.into(),>{ "Connect To WebSocket" }</button> | |
<button disabled=self.ws.is_none(), | |
onclick=|_| WsAction::SendData.into(),>{ "Send To WebSocket" }</button> | |
<button disabled=self.ws.is_none(), | |
onclick=|_| WsAction::Disconnect.into(),>{ "Close WebSocket connection" }</button> | |
</nav> | |
</div> | |
} | |
} | |
} | |
impl Model { | |
fn view_data(&self) -> Html<Model> { | |
if let Some(value) = self.data.clone() { | |
html! { | |
<p>{ "Got a value" }</p> | |
} | |
} else { | |
html! { | |
<p>{ "Data hasn't fetched yet." }</p> | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment