手触りでWebSocketの使い方を教えてくれます[実はWebSocketも難しくありません]


この文章の前に、WebSocket多くの人が聞いたことがありますが、見たことがなく、使ったことがなく、とても高い技術だと思っていましたが、実際にはこの技術は神秘的ではなく、簡単に身につけることができる技術だと言えます.
水泳、フィットネス理解:ブログ、フロントエンド蓄積ドキュメント、公衆番号、GitHubWebSocketは、次の問題を解決しました.
クライアント(ブラウザ)とサーバ側は通信を行い、クライアントがajax要求を開始してこそ通信を行うことができ、サーバ側は自発的にクライアントに情報をプッシュすることができない.
スポーツの試合、チャットルーム、リアルタイムの位置などのシーンが発生した場合、クライアントはサーバ側の変化を取得するには、ポーリング(タイミング要求)によってサーバ側に新しい情報の変化があるかどうかを知るしかありません.
ポーリングの効率が低く、リソースが非常に浪費されます(リクエストを送信し続け、サーバをリンクする必要があります).
WebSocketの登場により、サーバ側がクライアントに情報を自発的に送信できるようになり、ブラウザがリアルタイムで双方向に通信できるようになったのがWebSocketの問題です.
超シンプルな栗:htmlの書類を新しく作って、本栗をどこかに探して走ってみると、WebSocketに簡単に入ることができます.
function socketConnect(url) {
    //            
    let ws = new WebSocket(url); //   `WebSocket`  ,     ws
    //       
    ws.onopen = e => {
        console.log('    ', e)
        ws.send('         '); //           
    }
    //            
    ws.onmessage = e => {
        console.log('      :', e.data)
        // do something
    }
    return ws; //   websocket  
}
let wsValue = socketConnect('ws://121.40.165.18:8800'); // websocket  

上記栗のWebSocketのインタフェースアドレスは、WebSocketオンラインテストから出ており、開発時にバックエンドから与えられたアドレスが利用可能かどうかをテストするためにも使用できます.
WebSocketのclassクラス:
プロジェクトの多くの場所でWebSocketを使用する場合は、classクラスにカプセル化するのがより良い選択です.
下の栗は、非常に詳しい注釈をしてhtmlファイルを作ってもそのまま使えますし、websocketの常用APIが入っています.
下の注記のコードは、まず気にしないで、心拍のメカニズムに関連して、WebSocket接続を維持するために使用されます.
class WebSocketClass {
    /**
     * @description:        ,    
     * @param {String} url ws   
     * @param {Function} msgCallback               
     * @param {String} name         ws,  debugger
     */
    constructor(url, msgCallback, name = 'default') {
        this.url = url;
        this.msgCallback = msgCallback;
        this.name = name;
        this.ws = null;  // websocket  
        this.status = null; // websocket    
    }
    /**
     * @description:       websocket   webSocket   
     * @param {*}          
     */
    connect(data) {
        //    WebSocket   
        this.ws = new WebSocket(this.url);
        this.ws.onopen = e => {
            //   ws    
            this.status = 'open';
            console.log(`${this.name}    `, e)
            // this.heartCheck();
            if (data !== undefined) {
                //       ,     
                return this.ws.send(data);
            }
        }
        //            
        this.ws.onmessage = e => {
            //          ,     
            // if (e.data === 'pong') {
            //     this.pingPong = 'pong'; //       pong,  pingPong   
            // }
            return this.msgCallback(e.data);
        }
        // ws    
        this.ws.onclose = e => {
            this.closeHandle(e); //       
        }
        // ws    
        this.onerror = e => {
            this.closeHandle(e); //       
        }
    }
    // heartCheck() {
    //     //                 
    //     this.pingPong = 'ping'; // ws        
    //     this.pingInterval = setInterval(() => {
    //         if (this.ws.readyState === 1) {
    //             //   ws          
    //             this.ws.send('ping'); //      ping
    //         }
    //     }, 10000)
    //     this.pongInterval = setInterval(() => {
    //         this.pingPong = false;
    //         if (this.pingPong === 'ping') {
    //             this.closeHandle('pingPong     pong'); //     pong   webSocket
    //         }
    //         //    ping      ping        pong    (pingPong    pong),   
    //         console.log('  pong')
    //         this.pingPong = 'ping'
    //     }, 20000)
    // }
    //         
    sendHandle(data) {
        console.log(`${this.name}        :`, data)
        return this.ws.send(data);
    }
    closeHandle(e = 'err') {
        //   webSocket    ,        ( closeMyself  ),     
        if (this.status !== 'close') {
            console.log(`${this.name}  ,  websocket`, e)
            // if (this.pingInterval !== undefined && this.pongInterval !== undefined) {
            //     //      
            //     clearInterval(this.pingInterval);
            //     clearInterval(this.pongInterval);
            // }
            this.connect(); //   
        } else {
            console.log(`${this.name}websocket    `)
        }
    }
    //     WebSocket
    closeMyself() {
        console.log(`  ${this.name}`)
        this.status = 'close';
        return this.ws.close();
    }
}
function someFn(data) {
    console.log('          :', data);
}
// const wsValue = new WebSocketClass('ws://121.40.165.18:8800', someFn, 'wsName'); //             50 
const wsValue = new WebSocketClass('wss://echo.websocket.org', someFn, 'wsName'); //          
wsValue.connect('        '); //      
// setTimeout(() => {
//     wsValue.sendHandle('       ')
// }, 1000);
// setTimeout(() => {
//     wsValue.closeMyself(); //   ws
// }, 10000)

栗の中に私は直接一緒に書いて、classを1つのjsファイルの中に置いて、exportを出して、それから必要な場所でimportを入れて、パラメータを入れて使えます.
WebSocket不安定
WebSocketは安定していません.しばらく使用すると、接続が切断される可能性があります.なぜ接続が切断されるのかという公論は今までにないようです.WebSocketを接続状態に保つ必要があります.ここでは2つの方法をお勧めします.
WebSocketは変数を設定し、手動で接続を閉じるかどうかを判断します.classクラスでは、変数を設定し、webSocketのクローズ/エラーのコールバックで、手動でクローズしたかどうかを判断し、そうでなければ再接続するメリットとデメリットは以下の通りです.
  • の利点:要求が少なく(心拍接続に対して)、設定しやすい.
  • の欠点:データが失われる可能性があり、再接続が切断された間、ちょうど双方が通信しています.

  • WebSocket心拍数メカニズム:
    第1のスキームの欠点のため、ErrorイベントまたはCloseイベントをトリガせずに接続を切断する他の不明な状況が発生する可能性がある.これにより、実際の接続が切断され、クライアントとサービス側は知らず、メッセージを待っていた.
    そして賢いプログラム猿たちは心拍メカニズムという解決策を考え出しました
    クライアントは心臓の鼓動のように一定の時間ごとにpingを送信して、サーバーに教えて、私はまだ生きていて、サーバーもpongに戻って、クライアントに教えて、サーバーはまだ生きています.
    具体的な実装方法は、上記のclassの注釈において、これを開くと効果が見られる.
    WebSocketについて
    最初から文字的な内容が多すぎて、皆さんを驚かせてしまったのではないかと心配していましたが、今はもう使えます.WebSocketの他の知識点を振り返ってみましょう.
    WebSocketの現在のステータス:WebSocket.readyState次はWebSocket.readyStateの4つの値(4つの状態)です.
  • 0:接続中であることを示す
  • 1:接続が成功したことを示し、
  • を通信することができる.
  • 2:接続が閉じていることを示す
  • .
  • 3:接続がオフになっているか、接続が開いていない
  • を示します.
    WebSocketリンクが成功した後、クライアントがpingを送信することを許可するなど、現在の状態を利用していくつかのことをすることができます.
    if (this.ws.readyState === 1) {
        //   ws          
        this.ws.send('ping'); //      ping
    }
    WebSocketはまた、バイナリデータの送信/受信も可能である
    ここで私も試したことがありません.私はチェン一峰先生のWebSocketチュートリアルを見て、このようなものがあることを知っています.興味があれば、グーグルに行ってもいいです.みんな知っていればいいです.
    バイナリデータには、blobオブジェクトとArraybufferオブジェクトが含まれているので、別々に処理する必要があります.
        //     
    ws.onmessage = function(event){
        if(event.data instanceof ArrayBuffer){
            //    ArrayBuffer   
        }
        
        if(event.data instanceof Blob){
            //    Blob   
        }
    }
    
    //    Blob      
    let file = document.querySelector('input[type="file"]').files[0];
    ws.send(file);
    
    //    ArrayBuffer      
    var img = canvas_context.getImageData(0, 0, 400, 320);
    var binary = new Uint8Array(img.data.length);
    for (var i = 0; i < img.data.length; i++) {
        binary[i] = img.data[i];
    }
    ws.send(binary.buffer);

    もしあなたが送信するバイナリデータが大きい場合、どのように送信が完了したかを判断します.webSocket.bufferedAmountプロパティは、あと何バイトのバイナリデータが送信されていないかを示します.
    var data = new ArrayBuffer(10000000);
    socket.send(data);
    if (socket.bufferedAmount === 0) {
        //     
    } else {
        //       
    }

    上記の栗はチェン一峰先生のWebSocket教程から出ています.
    WebSocketのメリット:
    最後にもう1回
  • 双方向通信(最初は言ったが、最も重要な点でもある).
  • データフォーマットは比較的軽量で、性能オーバーヘッドが小さく、通信効率の高いプロトコル制御のパケットヘッダが小さいが、HTTPプロトコルは通信のたびに完全なヘッダ
  • を携帯する必要がある.
  • より良いバイナリサポート
  • は同源の制限がなく、クライアントは任意のサーバと通信することができる
  • .
  • はHTTPプロトコルと良好な互換性を持っている.デフォルトポートも80と443であり、握手段階ではHTTPプロトコルを採用するため、握手時にマスクすることが容易ではなく、各種HTTPプロキシサーバ
  • を通過することができる.
    締めくくり
    本文を読んで、まだ少しぼんやりしているなら、必ず文の中の2つの栗を、新しいhtmlファイルを作って走って、自分でいじってみましょう.さもなくばどれだけのブログ/教程を読んでも役に立たないで、実践してやっと本当の知識が出て、決して紙の上で兵を語らないでください.
    见终わった友达が好き/関心を持つことができることを望んで、あなたの支持は私に対する最大の励ましです.
    ブログ、フロントエンド蓄積ドキュメント、公衆番号、GitHub
    以上2018.10.22
    参考資料:
    WebSocketチュートリアル
    WebSocketの心拍数と再接続メカニズムを理解する
    WebSocketプロトコル:入門から精通まで5分