WebSocket転載

18729 ワード

概要
WebSocketって何?
WebSocketはネットワーク通信プロトコルです.RFC 6455は、その通信規格を定義する.
WebSocketは、HTML 5が提供し始めた単一のTCP接続上でフルデュプレクス通信を行うプロトコルである.
なぜWebSocketが必要なの?
コンピュータネットワークプロトコルを知っている人は、HTTPプロトコルが無状態、無接続、一方向のアプリケーション層プロトコルであることを知っているはずです.リクエスト/レスポンスモデルを採用しています.通信要求はクライアントからのみ開始され,サービス側は要求に対して応答処理を行う.
この通信モデルには、HTTPプロトコルでは、サーバがクライアントに積極的にメッセージを送信することができないという弊害がある.
このような一方向要求の特徴は,サーバが連続的に状態が変化すると,クライアントが知るのは非常に面倒であることに決まっている.ほとんどのWebアプリケーションでは、頻繁な非同期JavaScriptとXML(AJAX)リクエストによって長いポーリングが実現されます.ポーリングの効率が低く、リソースが非常に浪費されます(接続を停止しないか、HTTP接続を常に開く必要があるため).
そのため、エンジニアたちはもっと良い方法があるかどうかを考えています.WebSocketはこのように発明された.WebSocket接続を使用すると、クライアントとサーバの間でフルデュプレクス通信が可能になり、どちらも確立された接続によってデータを他端にプッシュできます.WebSocketは1回の接続を確立するだけで、接続状態を維持することができます.これは、ポーリング方式による接続の継続的な確立に比べて、明らかに効率が大幅に向上します.
WebSocketはどのように働いていますか?
Webブラウザとサーバは、接続の確立と維持のためにWebSocketsプロトコルを実装する必要があります.WebSockets接続は長期にわたって存在するため、典型的なHTTP接続とは異なり、サーバに重要な影響を及ぼす.
マルチスレッドまたはマルチプロセスベースのサーバは、接続を開き、要求をできるだけ迅速に処理し、接続を閉じることを目的としているため、WebSocketsには適用できません.実際のWebSocketsサーバ側の実装には、非同期サーバが必要です.
WebSocketクライアント
クライアントでは、WebSockets用にJavaScriptライブラリを使用する必要はありません.WebSocketsを実装するWebブラウザは、WebSocketsオブジェクトを介して必要なすべてのクライアント機能を公開します(主にHtml 5をサポートするブラウザを指します).
クライアントAPI
次のAPIは、WebSocketオブジェクトを作成するために使用されます.
var Socket = new WebSocket(url, [protocol] );

上記のコードの最初のパラメータurlは、接続するURLを指定します.2番目のパラメータprotocolはオプションで、許容可能なサブプロトコルを指定します.
WebSocketプロパティ
WebSocketオブジェクトのプロパティを以下に示します.上記のコードを使用してSocketオブジェクトを作成したとします.
ツールバーの
説明
Socket.readyState
読み取り専用プロパティreadyStateは接続ステータスを表し、0-接続が確立されていないことを示します.1-接続が確立され、通信可能であることを示します.2-接続が閉じられていることを示します.3-接続が閉じているか、接続が開かないことを示します.
Socket.bufferedAmount
読み取り専用プロパティbufferedAmountはsend()によってキューに入れられて転送を待っていますが、まだ発行されていないUTF-8テキストバイト数です.
WebSocketイベント
以下はWebSocketオブジェクトに関するイベントです.上記のコードを使用してSocketオブジェクトを作成したとします.
≪イベント|Events|ldap≫
イベントハンドラ
説明
open
Socket.onopen
接続確立時にトリガー
message
Socket.onmessage
クライアントがサービス側データを受信するとトリガーされます
error
Socket.onerror
通信エラー発生時にトリガー
close
Socket.onclose
接続クローズ時にトリガー
WebSocketメソッド
WebSocketオブジェクトに関するメソッドを以下に示します.上記のコードを使用してSocketオブジェクトを作成したとします.
方法
説明
Socket.send()
接続を使用したデータの送信
Socket.close()
接続を閉じる
//       WebSocket   
var ws = new WebSocket('ws://localhost:9998/echo');

//    web socket         
ws.onopen = function() {
  //    send()       
  ws.send('    ');
  alert('     ...');
};

//             
ws.onmessage = function(evt) {
  var received_msg = evt.data;
  alert('     ...');
};

//    web socket         
ws.onclose = function() {
  alert('     ...');
};

WebSocketサービス
WebSocketはサービス側での実現が非常に豊富です.Node.js、Java、C++、Pythonなど多くの言語に独自のソリューションがあります.
以下では、WebSocketの学習中に接触したWebSocketサービス・エンド・ソリューションについて説明します.
Node.js
一般的なノード実装には以下の3つがある.
  • µWebSockets
  • Socket.IO
  • WebSocket-Node

  • Java
    Javaのwebは一般的にservletコンテナに依存している.
    私が使ったservlet容器は、Tomcat、Jetty、Resinです.このうち、Tomcat 7、Jetty 7およびそれ以上のバージョンではWebSocketがサポートされ始めています(バージョンが変更されるにつれてWebSocketのサポートが変更される可能性があるため、新しいバージョンを推奨します).
    また、SpringフレームワークはWebSocketにもサポートされています.
    ただし,以上のアプリケーションはWebSocketに対してそれぞれ実装されている.しかし、それらはいずれもRFC 6455の通信規格に従い、Java APIはJSR 356−JavaTM API for WebSocket規格に統一的に従う.したがって,実際の符号化ではAPIの差は大きくない.
    Spring
    SpringのWebSocketのサポートは、次のjarパッケージに基づいています.
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-websocketartifactId>
      <version>${spring.version}version>
    dependency>

    SpringでWebSocketサーバを実装するには、次の手順に従います.
    WebSocketプロセッサの作成TextWebSocketHandlerまたはBinaryWebSocketHandlerを拡張すると、指定した方法を上書きできます.Spring WebSocketイベントを受信すると、イベントに対応するメソッドが自動的に呼び出されます.
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.WebSocketSession;
    import org.springframework.web.socket.TextMessage;
    
    public class MyHandler extends TextWebSocketHandler {
    
        @Override
        public void handleTextMessage(WebSocketSession session, TextMessage message) {
            // ...
        }
    
    }
    WebSocketHandlerのソースコードは次のとおりです.これは、プロセッサがどのWebSocketイベントを処理できるかを意味します.
    public interface WebSocketHandler {
    
       /**
        *           
        */
       void afterConnectionEstablished(WebSocketSession session) throws Exception;
    
       /**
        *           
        */
       void handleMessage(WebSocketSession session, WebSocketMessage> message) throws Exception;
    
       /**
        *             
        */
       void handleTransportError(WebSocketSession session, Throwable exception) throws Exception;
    
       /**
        *           
        */
       void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception;
    
       /**
        *         
        */
       boolean supportsPartialMessages();
    
    }

    WebSocketの構成
    構成には、注釈とxmlの2つの方法があります.WebSocketプロセッサをレジストリセンターに追加する役割を果たします.
  • WebSocketConfigurer
  • を実現する.
    import org.springframework.web.socket.config.annotation.EnableWebSocket;
    import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
    import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
    
    @Configuration
    @EnableWebSocket
    public class WebSocketConfig implements WebSocketConfigurer {
    
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            registry.addHandler(myHandler(), "/myHandler");
        }
    
        @Bean
        public WebSocketHandler myHandler() {
            return new MyHandler();
        }
    
    }
  • xml方式
  • <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:websocket="http://www.springframework.org/schema/websocket"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/websocket
            http://www.springframework.org/schema/websocket/spring-websocket.xsd">
    
        <websocket:handlers>
            <websocket:mapping path="/myHandler" handler="myHandler"/>
        websocket:handlers>
    
        <bean id="myHandler" class="org.springframework.samples.MyHandler"/>
    
    beans>

    詳細は、Spring WebSocketドキュメントを参照してください.
    javax.websocket
    SpringフレームワークのWebSocket APIを使用したくない場合は、基本的なjavaxを選択することもできます.websocket.
    まず、API jarパッケージを導入する必要があります.
    
    <dependency>
      <groupId>javax.websocketgroupId>
      <artifactId>javax.websocket-apiartifactId>
      <version>1.0version>
    dependency>

    埋め込みjettyを使用する場合は、実装パッケージを導入する必要があります.
    
    <dependency>
      <groupId>org.eclipse.jetty.websocketgroupId>
      <artifactId>javax-websocket-server-implartifactId>
      <version>${jetty-version}version>
    dependency>
    
    <dependency>
      <groupId>org.eclipse.jetty.websocketgroupId>
      <artifactId>javax-websocket-client-implartifactId>
      <version>${jetty-version}version>
    dependency>

    @ServerEndpoint
    この注記は、クラスがWebSocketのプロセッサであることをマークするために使用されます.
    次に、このクラスで次の注釈を使用して、修飾された方法がイベントのコールバックをトリガーすることを示すことができます.
    //         
    @OnMessage
    public void onMessage(String message, Session session) throws IOException, InterruptedException {
        ...
    }
    
    //         
    @OnOpen
    public void onOpen(Session session, EndpointConfig config, @PathParam("id") String id) {
        ...
    }
    
    //         
    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        ...
    }
    
    //           
    @OnError
    public void onError(Throwable error) {
        ...
    }

    ServerEndpointConfig.Configurator
    プロセッサの作成が完了したら、Server EndpointConfigを拡張する必要があります.コンフィギュレータクラスの構成が完了しました:
    public class WebSocketServerConfigurator extends ServerEndpointConfig.Configurator {
        @Override
        public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
            HttpSession httpSession = (HttpSession) request.getHttpSession();
            sec.getUserProperties().put(HttpSession.class.getName(), httpSession);
        }
    }

    それからそれがなくて、こんなに簡単です.
    WebSocketエージェント
    WebSocketの通信を電話接続と見なすと、Nginxの役割は電話交換員のように、電話接続を開始した電話を指定されたカスタマーサービスに転送することを担当します.
    Nginxは1.3版からWebSocketエージェントを正式にサポートしている.WebアプリケーションでプロキシサーバNginxを使用している場合は、WebSocketプロキシ機能をオンにするようにNginxの構成も必要です.
    以下は参照構成です.
    server {
      # this section is specific to the WebSockets proxying
      location /socket.io {
        proxy_pass http://app_server_wsgiapp/socket.io;
        proxy_redirect off;
    
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 600;
      }
    }

    詳細については、Nginx公式のwebsocketドキュメントを参照してください.
    FAQ
    HTTPはWebSocketと何の関係がありますか?
    Websocketは実は新しいプロトコルで、HTTPプロトコルとは基本的に関係なく、既存のブラウザの握手規範を互換化するためだけに、つまりHTTPプロトコルの補完である.
    HtmlはHTTPと何の関係がありますか?
    Htmlはハイパーテキストタグ言語であり、ウェブページを作成するための標準タグ言語である.これは技術基準です.Html 5はその最新バージョンです.
    Httpはネットワーク通信プロトコルである.それ自体はHtmlと直接関係がない.
    完全な例
    完全なサンプルコードが必要な場合は、Githubコードを参照してください.
  • SpringがWebSocketに対してサポートする例
  • 埋め込みJettyサーバのWebSocket例
  • Spring-websocketとjetty 9.3バージョンは互換性に問題があるようで、Tomcatは木に問題があります.
    何度も試したが、解決策が見つからず、Jetty公式の埋め込み例を使ってJettyでWebSocketを使うしかなかった.
    資料
  • 高票の答えを知っています.WebSocketはどんな原理ですか.WebSocketの原理の説明は分かりやすいです.
  • WebSocketチュートリアル-チェン一峰大神の科学普及はいつものように分かりやすい.
  • WebSockets - by fullstackpython
  • Nginx公式websocketドキュメント
  • Spring WebSocketドキュメント
  • Tomcat 7 WebSocketドキュメント
  • Jetty WebSocketドキュメント
  • 作者:静かに虚空でいかなる形式の転載を歓迎して、しかし必ず出典を明記してください.本人のレベルに限り、文章やコードに不適切な点があれば、教えてください.
    転載先:https://www.cnblogs.com/LJing21/p/11597677.html