在Web或移動項目中,服務器向客戶端實時推送消息是一種常見的業務需求。javascript
實現方式html
應用場景:java
簡單點說就是:經過HTTP協議進行握手創建鏈接後直接進行雙向TCP通信
WebSocket是HTML5新增長的一種通訊協議,目前流行的瀏覽器都支持這個協議,例如 Chrome,Safari,Firefox,Opera,IE等等,對該協議支持最先的應該是Chrome,從Chrome12就已經開始支持,隨着協議草案的不斷變化,各個瀏覽器對協議的實現也在不停的更新。該協議仍是草案,沒有成爲標準,不過成爲標準應該只是時間問題了。 node
包裝了 WebSocket 以後的高級 API,咱們一般不會直接使用 WebSocket 而是使用 SockJS
應對不支持 WebSocket 的場景,若是 WebSocket 不可用,則使用其餘協議模擬 WebSocket API。react
Mac下安裝 node.js
推薦:web
$ brew install node $ node -v v6.11.4
Windows 等其餘環境能夠直接下載安裝包或自行百度https://nodejs.org/en/download/typescript
Mac下安裝 yarn
推薦:express
$ brew install yarn $ yarn -v 1.5.1
Windows 等其餘環境能夠直接下載安裝包或自行百度
安裝 create-react-app
segmentfault
$ yarn global add create-react-app
以後咱們就能夠經過 create-react-app 來快速建立 react 項目
這個程序功能很簡單:當客戶端經過 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
$ 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/ 並顯示以下內容,其中時間部分會不斷收到服務端數據進行刷新
原文:http://www.javashuo.com/article/p-yctuowam-hq.htmlThis is the timer value: 2018-03-07T12:40:35.613Z