Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fullstack IoT 2017 專欄, #5: React 元件與 IoT 的邂逅 #26

Open
jollen opened this issue Sep 19, 2016 · 0 comments
Open

Fullstack IoT 2017 專欄, #5: React 元件與 IoT 的邂逅 #26

jollen opened this issue Sep 19, 2016 · 0 comments

Comments

@jollen
Copy link
Owner

jollen commented Sep 19, 2016

有了 Web of Things 初體驗後,應該會對 React 元件與 IoT 的關係有了好奇心。React 在 IoT 的全端開發,最簡單的使用情境就是:製作能接收 Server Push 的 React 元件。

另外,還有一件事情也吸引我的目光:Flux 模式。把 Flux 模式用在這裡,似乎是再好不過了,因為,根據 Flux 模式的設計:我們可以用 Actions 來調用 REST API。把思路放大一下:Actions 是用來與 Backend 互動的單元,運用這個觀念,或許可以實現一個簡單的 Flux 程式庫,並在 Action 裡建立與 WebSocket Server 的連線。

範例

一個簡單的範例由此而生。先下載與運行 react-websocket-biolerplate 範例:

$ git clone https://github.com/jollen/react-websocket-biolerplate.git
$ cd react-websocket-biolerplate
$ npm install
$ gulp compile

使用瀏覽器開啟 dist/index.html 文件即可,你會看到來自 wot.city 服務器的即時數據。

  • 如果要修改服務器來源,請開啟 src/App.jsx,並修改 server prop
  • 修改完成後,必須運行 gulp compile 命令重新編譯文件

觀念

這個範例的實現觀念非常簡單:

  • 使用 react-websocket-flux 模組,這是一個簡單 Flux 實現
  • 註冊事件函數到 react-websocket-flux 裡後,透過 onMessage 接收即時數據

Flux 模式運用在這幾個地方:

  • 在 React 元件的 constructor 裡調用 WebsocketActions.connect() 與 WebSocket 服務器建立連線
  • 在 React 元件裡實現 onMessage 事件回調函數
  • 在 React 元件的 componentDidMount lifecycle 裡調用 WebsocketStore.addMessageListener 註冊 onMessage callback
  • 在 React 元件的 componentWillUnmount lifecycle 裡調用 WebsocketStore.removeMessageListener 解除註冊

Put All Together

以下是完整的實現步驟說明。根據此,也能為現有的 React 元件注入 WebSocket 功能。

import React, { Component } from 'react';
import { render } from 'react-dom';

// 1. 引入 'react-websocket-flux'
import { WebsocketStore, WebsocketActions } from 'react-websocket-flux';

export class MyComponent extends Component {
    constructor(props, context) {
        super(props, context);

        // 2. 初始化 this.state
        this.state = {
            temperature: -1
        };

        // 3. WebSocket 的 'onMessage' callback
        this.onMessage = this.onMessage.bind(this);

        // 4. 連線到 WebSocket Server
        WebsocketActions.connect(this.props.server);
    }

    componentDidMount() {
        // 5. 將 'onMessage' 註冊到 react-websocket-flux
        WebsocketStore.addMessageListener(this.onMessage);
    }

    componentWillUnmount() {
        // 將 'onMessage' 從 react-websocket-flux 解除註冊       
        WebsocketStore.removeMessageListener(this.onMessage);      
    }

    onMessage(data) {
        // 6. Deserialize: 從 Server 推送過來的 JSON data 取出資料,並放入 this.state
        this.setState({
            temperature: data.temperature
        });
        console.log(data)
    }

    render() {
        return (    
            <div>
                <h1>{this.state.temperature}</h1>
            </div>
        );
    }
}

在 React 應用程式裡,引入你的元件使用:

  • 加入 server prop 指定 WebSocket 服務器 URI
  • 可以使用本專案提供的 wss://wot.city/object/testman/viewer 測試數據

範例片斷如下:

// 我的 React 元件
import { MyComponent } from './Component';

// 加入 server prop
render(
    <MyComponent server="wss://wot.city/object/testman/viewer">
    </MyComponent>,
    document.getElementById('content')
);

小結

本文的完整範例 react-websocket-biolerplate.git

@jollen jollen changed the title Fullstack IoT 2017 專欄, #5: React 元件與 IoT broker 串接 Fullstack IoT 2017 專欄, #5: React 元件與 IoT 的邂逅 Sep 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant