# Obniz Rust設計 ###### tags: `Rust` `obniz` `趣味` ## リポジトリ https://github.com/MrBearing/obniz-rust ## 開発ロードマップ https://www.mindomo.com/mindmap/obniz_rust-7fb0a99ef73845a9af1369a3d631de5c ## 外部設計 以下のような書き方でプログラムできると嬉しい。。 <!-- ```rust= let obniz = Obniz::new("1234-5678"); obniz.connect(|obniz_cap| { loop{ obniz_cap.io0.set(true); sleep(10); obniz_cap.io0.set(false); sleep(10); } }); ``` ```rust= let obniz = Obniz::new("1234-5678"); match obniz.connect() { Ok(_) => println!("connect"), _ => panic!() }; loop{ obniz.io0.set(true); sleep(10); obniz.io0.set(false); sleep(10); } ``` 現実的な実装案 --> ```rust= let obniz_connector = ObnizConnector::new("1234-5678"); let obniz = match obniz_connector.connect().await { Ok(_) => println!("connect"), _ => panic!() }; loop{ obniz.io_set(0,true); sleep(10); obniz.io_set(0,false); sleep(10); } ``` ## 内部設計 ```plantuml actor User as user participant "obniz::connect()" as connector participant Obniz as cap participant "websocket dispatch thread" as th_sock participant "<<websocket server>>\nwss://obniz.io/obniz/OBNIZE_ID/ws/1" as io_server participant "<<websocket server>>\nwss://REDIRECT_HOST/obniz/OBNIZE_ID/ws/1" as server activate connector user -> connector : obniz::connect() connector -> io_server : connect connector <-- io_server : response redirect host name connector -> cap : Obniz::new() activate th_sock activate cap user <- connector : Future<Obniz> deactivate connector user -> cap: io_get(0) cap -> server: [{"io0":"get"}] th_sock <-- server: [{"io0": true}] cap <- th_sock : [{"io0": true}] user <- cap: true deactivate cap ``` ## 参考資料 ### obnizのWebsocketAPI https://obniz.com/ja/doc/reference/cloud/hardware-api/websocket-api ### 設計の参考にしたクレート https://crates.io/crates/rspotify https://docs.rs/rspotify/0.10.0/rspotify/ https://github.com/sfackler/rust-postgres https://docs.rs/tokio-postgres/0.7.2/tokio_postgres/ https://github.com/davidrhyswhite/rust-firebase https://crates.io/crates/mysql_common https://crates.io/crates/mongodb https://crates.io/crates/mysql_async https://github.com/wyyerd/pulsar-rs ### tungstenite , tokioの理解 https://docs.rs/tokio-tungstenite/0.15.0/tokio_tungstenite/struct.WebSocketStream.html#method.forward ### 他参考資料 https://qiita.com/mutuya/items/b09881839c4e02b2f485 #### テスト用 https://crossbar.io/autobahn/ ## メモ - ~~非同期での処理はいらないのでは疑惑~~ - 非同期IOのAPIが存在するので実装は必要 - 後々RestでのAPI操作必要? - 先にRestの実装した方が早いかも。。 <!-- ```rust // on_connected を動作させるスレッドをスポーン・実行 // ************************************************************ // 非同期にやるなら以下の実装が必要だが取り急ぎ実装しない // ************************************************************ fn call_me<F: Fn()>(f: F) { f(); } // response 待機・ループするスレッドをスポーン self.response_half .expect("Failed to unwrap") .for_each(|message|async { // 受信したらレスポンスを分配 // X XX 以下の処理は別の関数に分離する let message = match message { Err(err) => return, Ok(some_response) => some_response, }; let response = match message.to_text(){ Err(err) => return, Ok(response_text) => response_text, }; let res : Vec<Response> = match serde_json::from_str(response) { Err(err) => return, Ok(response_object) => response_object, }; println!("response is {:?}",res[0]); // T ODO レスポンス受信後の処理を別の関数で実行 // match &res[0] { // Response::Ws(ws) => match ws { // }, // _response => panic!("response is not ws. response. {:?}", _response) // } }); // pin_mut!(read_response); // read_response.await; ``` -->