React WebSocket Polling(實時推送)

@老徐老徐

Sunday, 7 March 2018html

本文假設你對 React 已經比較熟悉!參考 《React Redux Quick Start》node

React WebSocket Polling

React 程序使用 WebSocket 獲取實時推送數據

基礎

實時數據推送

在Web或移動項目中,服務器向客戶端實時推送消息是一種常見的業務需求。react

實現方式web

  1. Polling:輪詢(俗稱「拉」),即按期從新請求數據。
  2. Long-Polling:長輪詢,是 Polling 技術的改進,即在保持住一個請求,在這個請求內不斷髮送數據。
  3. WebSocket Polling:是 Long-Polling 技術的改進,即經過HTTP協議握手創建鏈接後直接進行雙向TCP通信。

應用場景express

  • 聊天室
  • 股票價格變化、K線圖
  • 消息提醒

WebSocket Polling

簡單點說就是:經過HTTP協議進行握手創建鏈接後直接進行雙向TCP通信

WebSocket是HTML5新增長的一種通訊協議,目前流行的瀏覽器都支持這個協議,例如 Chrome,Safari,Firefox,Opera,IE等等,對該協議支持最先的應該是Chrome,從Chrome12就已經開始支持,隨着協議草案的不斷變化,各個瀏覽器對協議的實現也在不停的更新。該協議仍是草案,沒有成爲標準,不過成爲標準應該只是時間問題了。 編程

SockJS

包裝了 WebSocket 以後的高級 API,咱們一般不會直接使用 WebSocket 而是使用 SockJS

應對不支持 WebSocket 的場景,若是 WebSocket 不可用,則使用其餘協議模擬 WebSocket API。api

實驗

編程環境

Mac下安裝 node.js推薦:瀏覽器

$ brew install node
$ node -v
v6.11.4
Windows 等其餘環境能夠直接下載安裝包或自行百度

https://nodejs.org/en/download/bash

Mac下安裝 yarn推薦:服務器

$ brew install yarn
$ yarn -v
1.5.1
Windows 等其餘環境能夠直接下載安裝包或自行百度

https://yarnpkg.com/lang/en/d...

安裝 create-react-app

$ yarn global add create-react-app

以後咱們就能夠經過 create-react-app 來快速建立 react 項目

HelloWorld

這個程序功能很簡單:當客戶端經過 Websocket 鏈接到服務端以後服務端即開始推送數據到客戶端

Websocket 服務端

$ cd react/websocket-helloworld
$ mkdir server
$ cd server

安裝依賴包

$ yarn add socket.io express

建立文件 app.js

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);

app.get('/', function (req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

io.of('/my-namespace').on('connection', (client) => {
  client.on('subscribeToTimer', (interval) => {
    console.log('client is subscribing to timer with interval ', interval);
    setInterval(() => {
      client.emit('timer', new Date());
    }, interval);
  });
});

const port = 8000;
io.listen(port);
console.log('listening on port ', port);
指定 websocket 的 endpoint 即入口地址爲 /my-namespace

而後監聽事件 subscribeToTimer

收到事件 subscribeToTimer後開始像客戶端定時發送消息timer,消息的數據內容是當前時間

建立文件 public/index.html,這裏只是普通的頁面展現和 websocket 無關

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>React Websocket Demo</title>
  </head>
  <body>
    <h1>React Websocket Demo</h1>
  </body>
</html>

運行

$ node app.js

Websocket 客戶端

$ cd react/websocket-helloworld
$ mkdir client
$ cd client

建立 React 項目環境

$ yarn create react-app client
$ cd client
$ rm -rf src/*

建立文件 src/index.js

import React from 'react';
import ReactDOM from 'react-dom';

import { subscribeToTimer } from './api/subscribeToTimer';

class App extends React.Component {
  constructor(props) {
    super(props);
    subscribeToTimer((err, timestamp) => this.setState({
      timestamp
    }));
  }
  
  state = { timestamp: 'no timestamp yet' }

  render() {
    return (
      <h1>This is the timer value: {this.state.timestamp}</h1>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
在組件進行構造時即調用 subscribeToTimer 開始請求數據

當收到數據後回調,用 this.setState 改變 React 組件狀態從而刷新界面

建立文件 src/api/subscribeToTimer.js

import io from 'socket.io-client';

const socket = io.connect('http://localhost:8000/my-namespace');

function subscribeToTimer(cb) {
  socket.on('timer', timestamp => cb(null, timestamp));
  socket.emit('subscribeToTimer', 1000);
}

export { subscribeToTimer };
指定 websocket 的服務器地址爲 http://localhost:8000/

指定 websocket 的 endpoint 即入口地址爲 /my-namespace

subscribeToTimer 用於向服務器發一個消息請求數據

當請求到數據之後調用回調函數 cb

啓動

$ yarn start

便可看到自動打開瀏覽器 http://localhost:3000/ 並顯示以下內容,其中時間部分會不斷收到服務端數據進行刷新

This is the timer value: 2018-03-07T12:40:35.613Z
相關文章
相關標籤/搜索