# 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;
```
-->