zoukankan      html  css  js  c++  java
  • 实时数据推送webSocket

    实时数据推送

    在Web或移动项目中,服务器向客户端实时推送消息是一种常见的业务需求。

    实现方式

    1. Polling:轮询(俗称“拉”),即定期重新请求数据。
    2. Long-Polling:长轮询,是 Polling 技术的改进,即在保持住一个请求,在这个请求内不断发送数据。
    3. WebSocket Polling:是 Long-Polling 技术的改进,即通过HTTP协议握手建立连接后直接进行双向TCP通讯。

    应用场景

    • 聊天室
    • 股票价格变化、K线图
    • 消息提醒

    WebSocket Polling

    简单点说就是:通过HTTP协议进行握手建立连接后直接进行双向TCP通讯

    WebSocket是HTML5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如 Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是Chrome,从Chrome12就已经开始支持,随着协议草案的不断变化,各个浏览器对协议的实现也在不停的更新。该协议还是草案,没有成为标准,不过成为标准应该只是时间问题了。 

    SockJS

    包装了 WebSocket 之后的高级 API,我们通常不会直接使用 WebSocket 而是使用 SockJS

    应对不支持 WebSocket 的场景,如果 WebSocket 不可用,则使用其他协议模拟 WebSocket API。

    实验

    编程环境

    Mac下安装 node.js推荐:

    $ brew install node
    $ node -v
    v6.11.4
    Windows 等其他环境可以直接下载安装包或自行百度

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

    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


    原文:https://segmentfault.com/a/1190000013588737
  • 相关阅读:
    第三百三十二节,web爬虫讲解2—Scrapy框架爬虫—Scrapy使用
    trim思考
    国王验毒酒问题
    有人在群里问mysql如何选择性更新部分条件的问题
    有人在群里问 20180222055怎么转20180222-055 这样的问题
    如何下载腾讯视频的视频转为MP4常用格式视频
    天气预报的大雪真的下了
    群友面试的问题 我搞笑的帮忙回答一下
    电台大神打油诗
    ajax简单手写了一个猜拳游戏
  • 原文地址:https://www.cnblogs.com/kelly-sunshine/p/10880802.html
Copyright © 2011-2022 走看看