Websocket簡明チュートリアル(nodejs-websocketライブラリ、socket.ioライブラリ実装Webチャットルーム)


ソースアドレス:github推奨読書時間:1 hourはwebsocketを勉強して、大量の中国語と英語の資料を調べて、ここで成果をみんなに分かち合いますか?
Websocket
Websocket公式サイト:websocket公式サイト
1.websocketの概要:
 WebSocketは、HTML 5が提供し始めた単一のTCP接続上でフルデュプレクス通信を行うプロトコルである.Websocketは、クライアントとサーバ間のデータ交換をより簡単にし、サービス側がクライアントにデータを積極的にプッシュできるようにします.WebSocket APIでは、ブラウザとサーバが握手を1回完了するだけで、両者の間に永続的なリンクを直接作成し、双方向のデータ転送を行うことができます.
Webサイトのプッシュテクノロジー:
 Ajaxポーリングは、特定の時間間隔で、ブラウザによってサーバに対してHTTP要求を発行し、その後、サービス側によって最新のデータをクライアントのブラウザに返す.(欠点はブラウザがサーバに絶えず要求を出す必要があることであり、HTTP要求には長いヘッダが含まれている可能性があり、その中で本当に有効なデータはほんの一部であり、多くの帯域幅などのリソースを浪費する可能性がある)
websocket document:
mozilla websockets mozilla websocket
Websocketの利点:
 HTML 5で定義されたWebSocketプロトコルは、サーバリソースと帯域幅をよりよく節約し、通信の最初の握手をよりリアルタイムで行うにはhttpリクエストにより完了する必要があります.HTTPプロトコルは接続を確立する際にのみ使用され、接続を確立した後にTCPプロトコルで伝送され、HTTPプロトコルは不要です.WebSocketの長い接続により、クライアントとサービス側は、関連するパフォーマンスの問題をもたらすことなく、大量のデータ転送を行うことができ、Web側に大きな機能強化をもたらします. 現在Web側ではWebSocketを用いてIM関連機能の開発やリアルタイム連携などサーバとの大量のデータインタラクションを必要とする機能を実現することが可能であるとともに、以前のように長いポーリングのHack方式を用いて ブラウザがjavascriptを介してサーバにWebSocket接続の確立を要求することを実現する必要がなく、接続が確立すると、クライアントとサービス側はTCP接続で直接データを交換することができる.WebSocket接続を取得するとsend()メソッドでサーバにデータを送信し、onmessageイベントでサーバから返されたデータを受信できます.
websocket API
var socket = new WebSocket(url, [protocol]);
url:      URL
protocol:    ,          ```

WebSocket  
open	Socket.onopen	       
message	Socket.onmessage	             
error	Socket.onerror	         
close	Socket.onclose	       

WebSocket  
Socket.send()	        
Socket.close()	    

2.websocketの初歩的な使用
jsスクリプトを使用してwebsocket接続を確立し、インタラクティブなデータを作成します.サービス側は公式サイトのアドレスを使用しています.ここではクライアントdemo 1:index.html公式サイトの例を簡単に実現します.websocket公式サイトの例です.

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Websockettitle>
head>
<body>
    <h1>Echo Testh1>
    <input type="text" id="sendTxt">
    <button id="sendBtn">  button>
    <div id="recv">div>
    <script>
        //      websocket server  
        var websocket = new WebSocket("ws://echo.websocket.org/");
        // Socket.onopen           
        websocket.onopen = function() {
            console.log('websocket open');
            document.getElementById('recv').innerHTML = "Connected";
        }
        //        
        websocket.onclose = function() {
            console.log('websocket close');
        }
        //               e MessageEvent
        websocket.onmessage = function(e) {
            console.log(e.data);
            document.getElementById("recv").innerHTML = e.data;
        }
        document.getElementById("sendBtn").onclick = function() {
            var txt = document.getElementById("sendTxt").value;
            websocket.send(txt);
        }
    script>
body>
html>

3.nodeを使用する.js独自のwebsocket serverサーバの構築
バックエンド言語が非常に多いことを知っています.websocketでサポートされているサーバは次のようにたくさんあります.
php - http://code.google.com/p/phpwebsocket/
jetty - http://jetty.codehaus.org/jetty/(  7    websocket)
netty - http://www.jboss.org/netty
ruby - http://github.com/gimite/web-socket-ruby
Kaazing - https://web.archive.org/web/20100923224709/http://www.kaazing.org/confluence/display/KAAZING/Home
Tomcat - http://tomcat.apache.org/(7.0.27  websocket,   tomcat8,7.0.27        )
WebLogic - http://www.oracle.com/us/products/middleware/cloud-app-foundation/weblogic/overview/index.html(12.1.2    )
node.js - https://github.com/Worlize/WebSocket-Node
node.js - http://socket.io
nginx - http://nginx.com/
mojolicious - http://mojolicio.us/
python - https://github.com/abourget/gevent-socketio
Django - https://github.com/stephenmcd/django-socketio
erlang - https://github.com/ninenines/cowboy.git

Node.js概要
 Node.jsはChrome V 8エンジンベースのJavaScript実行環境です.イベント駆動、非ブロックI/Oモデルを使用し、軽量で効率的です.nodejsを使用してwebsocketサーバを構築できます
 開発環境:ubuntu linux(windows公式サイトで自分でダウンロード)とnodejs-websocketモジュールを使用しています
ドキュメントのアドレス:
公式サイト:official website参考ドキュメント:nodejs github nodejs-websocket-a node.js module for websocket server and client公式ドキュメント翻訳の中国語ブログ
ubuntuインストールnodejs、npm、およびnodejs-websocket注意:Ubuntu apt-getを使用してnodejsをインストールします.バージョンが低すぎます.ソースコードを使用してインストールするか、ソースリファレンスブログを交換することをお勧めします.
 Github   Node.js  :
$ sudo git clone https://github.com/nodejs/node.git
Cloning into 'node'...
      : 
$ sudo chmod -R 755 node
  ./configure      :
$ cd node
$ sudo ./configure
$ sudo make
$ sudo make install
  node  :
$ node --version
v12.0.0-pre
  nodejs-websocket  
npm install nodejs-websocket 
  wsServer.js  ,   node      (pkill node、tskill node): 
$ node wsServer.js

4.簡単なチャットルームを実現し、最適化する
demo 2:wsServer.js以下
var ws = require("nodejs-websocket");

// Scream server example : "hi" -> "HI!!!"                         
const hostname = 'xxx.xxx.xxx.xxx';
const port = 8001;

// Scream server example : "hi" -> "HI!!!"
var server = ws.createServer(function(conn) {
    console.log('Server running at ws://%s:%d/', hostname, port);
    conn.on("text", function(str) {
        console.log("Received" + str);
        conn.sendText(str.toUpperCase() + "!!!");
    });
    conn.on("close", function(code, reason) {
        console.log("Connection closed");
    });
    conn.on("error", function(err) {
        console.log("handle err");
        console.log(err);
    });
}).listen(port);

ブラウザを開き、クライアントのindexを開きます.htmlのurlは自分のサーバーを交換して、テストは成功しました
websocketは簡単なチャット機能を実現します:チャットルームの構想はクライアントがデータをサーバーに送信して、それからサーバーはすべてのチャットルームの中の接続を遍歴して、メッセージを放送して、ブラウザを通じてdom構造を変えて、放送テキストを呈します.demo3: wsServer.js
var ws = require("nodejs-websocket");

const hostname = 'xxx.xxx.xxx.xxx';
const port = 8001;

//       
var clientCount = 0;

// Scream server example : "hi" -> "HI!!!"
//     server  , ws   nodejs-websocket      
var server = ws.createServer(function(conn) {
    console.log("New connection");
    clientCount++;
    conn.nickname = 'user' + clientCount; 
    broadcast(conn.nickname + " comes in");

    //        ,str         
    conn.on("text", function(str) {
        console.log("Received" + str);
        broadcast(str);
    });
    //        
    conn.on("close", function(code, reason) {
        console.log("Connection closed");
        broadcast(conn.nickname + ' left');
    });
    //        ,      ,      
    conn.on("error", function(err) {
        console.log("handle err");
        console.log(err);
    });
}).listen(port);

console.log("websocket server listening on port: " + port + ", on hostname: " + hostname);

// server.connections      connection   ,          
//      
function broadcast(msg) {
    server.connections.forEach(function(conn) {
        conn.sendText(msg);
    });
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Websocket</title>
</head>
<body>
    <h1>Chat Room</h1>
    <input type="text" id="sendTxt">
    <button id="sendBtn">  </button>
    <script>
        function showMessage(str) {
            var div = document.createElement("div");
            div.innerHTML = str;
            document.body.appendChild(div);
        }

        var websocket = new WebSocket("ws://xxx.xxx.xxx.xxx:8001/");
        // Socket.onopen           
        websocket.onopen = function() {
            console.log("websocket open");
            document.getElementById("sendBtn").onclick = function() {
                var txt = document.getElementById("sendTxt").value;
                if(txt) {
                    websocket.send(txt);
                }
            }
        }
        //        
        websocket.onclose = function() {
            console.log('websocket close');
        }
        //               e MessageEvent
        websocket.onmessage = function(e) {
            console.log(e.data);
            showMessage(e.data);
        }
    </script>
</body>
</html>

単純チャット機能最適化:demo 4注:クライアントとサービス側の通信データを対象とし、JSON文字列に変換することによってindex.htmlを伝達するにすぎない

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Websockettitle>
head>
<body>
    <h1>Chat Roomh1>
    <input type="text" id="sendTxt">
    <button id="sendBtn">  button>
    <script>
        function showMessage(str, type) {
            var div = document.createElement("div");
            div.innerHTML = str;
            if(type == "enter") {
                div.style.color = "blue";
            } else if(type == "leave") {
                div.style.color = "red";
            }
            document.body.appendChild(div);
        }

        var websocket = new WebSocket("ws://xxx.xxx.xxx.xxx:8001/");
        // Socket.onopen           
        websocket.onopen = function() {
            console.log("websocket open");
            document.getElementById("sendBtn").onclick = function() {
                var txt = document.getElementById("sendTxt").value;
                if(txt) {
                    websocket.send(txt);
                }
            }
        }
        //        
        websocket.onclose = function() {
            console.log('websocket close');
        }
        //               e MessageEvent
        websocket.onmessage = function(e) {
            console.log(e.data);
            var mes = JSON.parse(e.data);
            showMessage(mes.data, mes.type);
        }
    script>
body>
html>
wsServer.js
var ws = require("nodejs-websocket");

const hostname = 'xxx.xxx.xxx.xxx';
const port = 8001;

//       
var clientCount = 0;

// Scream server example : "hi" -> "HI!!!"
//     server  , ws   nodejs-websocket      
var server = ws.createServer(function(conn) {
    console.log("New connection");
    clientCount++;
    conn.nickname = 'user' + clientCount; 
    //             sendText()      ,      
    // JSON.stringify()   JavaScript        
    var mes = {};
    mes.type = "enter";
    mes.data = conn.nickname + " comes in";
    broadcast(JSON.stringify(mes));

    //        ,str         
    conn.on("text", function(str) {
        console.log("Received " + str);
        var mes = {};
        mes.type = "message";
        mes.data = conn.nickname + ' says: ' + str;
        broadcast(JSON.stringify(mes));
    });
    //        
    conn.on("close", function(code, reason) {
        console.log("Connection closed");
        var mes = {};
        mes.type = "leave";
        mes.data = conn.nickname + " left";
        broadcast(JSON.stringify(mes));
    });
    //        ,      ,      
    conn.on("error", function(err) {
        console.log("handle err");
        console.log(err);
    });
}).listen(port);

console.log("websocket server listening on port: " + port + ", on hostname: " + hostname);

// server.connections      connection   ,          
//      
function broadcast(msg) {
    server.connections.forEach(function(conn) {
        conn.sendText(msg);
    });
}

5.使いやすいライブラリSocket.IO上記チャットルーム機能を実現
Nodejs+Socketを使用IO Webオンラインチャットルームの構築:より便利で迅速なためにSocketを使用します.IOライブラリは上述の機能文書アドレスを実現する:
公式サイト:Socket.IO公式文書中国語文書:Socket.IO中国語ドキュメント中国語ブログ:Socket.IO blog
インストール:Server:npm install --save socket.io javascript client:1. index.html [cdn](https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js) 2. 3. socket.io node_modules/socket.io-client/dist/socket.io.js, (A standalone build of the client is exposed by default by the server at /socket.io/socket.io.js)Socket.ioの概要:
 はWebSocketライブラリであり、クライアントのjsとサーバ側のnodejsを含み、リアルタイムで双方向のイベントベースの通信メカニズムを実現している.その目的は、異なるブラウザやモバイルデバイスで使用可能なリアルタイムアプリケーションの構築である.Websocket、AJAXロングポーリング、lframeストリームなどの様々な方法からブラウザが最適な方法を選択することによって、ネットワークのリアルタイムアプリケーションが自動的に実現されます.
demo 5サービス側は3000ポートを傍受し、クライアント接続を傍受し、接続後にクライアント{hello:‘world’}データに送信し、クライアントから送信されたメッセージwsServer.jsを傍受する.
var app = require('http').createServer();
// new Server(httpServer[,options]) httpServer: the server to bind to.
var io = require('socket.io')(app); 

app.listen(3000);
// io.on('connection', function(socket))        ,            socket
io.on('connection', function(socket){
    // socket.emit(eventName[, ...args][, ack])   socket        
    socket.emit('news', {hello : 'world'});

    // socket.on(eventName, callback) Register a new handler for the given event.
    //           
    socket.on('my other event', function(data) {
        console.log(data);
    })
});
index.html
     socket  ,          news    ,         

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>websockettitle>
    <script src="socket.io.js">script>
head>
<body>
    <script>
        //     socket   io('http://xxx.xxx.xxx.xxx:3000')      websocket     ,   io('ws://xxx.xxx.xxx.xxx:3000')
         var socket = io('http://xxx.xxx.xxx.xxx:3000');
         //            string      emit       
         socket.on('news', function(data) {
             console.log(data);
             socket.emit('my other event', {my : 'data'}); //         
         })
    script>
body>
html>

socket.io改造チャット機能wsServer.js
var app = require("http").createServer();
var io = require('socket.io')(app);

const hostname = 'xxx.xxx.xxx.xxx';
const port = 3000;

app.listen(port);

//       
var clientCount = 0;

io.on('connection', function(socket) {
    clientCount ++;
    socket.nickname = 'user' + clientCount;
    // namespace.emit(eventName [, ...args])              
    io.emit('enter', socket.nickname + ' comes in');

    socket.on('message', function(str) {
        io.emit('mes', socket.nickname + ' says: ' + str);
    });
    
    // disconnect         
    socket.on('disconnect', function(){
        io.emit('leave', socket.nickname + ' left');
    });
});

console.log("websocket server listening on port: " + port + ", on hostname: " + hostname);
index.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Websockettitle>
    <script src="socket.io.js">script>
head>
<body>
    <h1>Chat Roomh1>
    <input type="text" id="sendTxt">
    <button id="sendBtn">  button>
    <script>
        function showMessage(str, type) {
            var div = document.createElement("div");
            div.innerHTML = str;
            if(type == "enter") {
                div.style.color = "blue";
            } else if(type == "leave") {
                div.style.color = "red";
            }
            document.body.appendChild(div);
        }

        var socket = io("ws://xxx.xxx.xxx.xxx:3000/");

        document.getElementById("sendBtn").onclick = function() {
            var txt = document.getElementById("sendTxt").value;
            if(txt) {
                socket.emit('message', txt);
            }
        };

        // socket.on('String', function(data));           
        socket.on('enter', function(data){
            showMessage(data, 'enter');
        });

        socket.on('leave', function(data){
            showMessage(data, 'leave');
        } );

        socket.on('mes', function(data){
            showMessage(data, 'message');
        })
       
    script>
body>
html>

まとめ:
 websocketは、ブラウザとサーバが永続的な接続を確立することを可能にする HTML 5のwebsocket APIioライブラリ実装websocket(送信データは直列化可能なオブジェクトを直接送信し、メッセージをカスタマイズし、イベント文字列を利用して異なるメッセージを区別することができる)