Red Hat Training

A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform

17.2. WebSocket アプリケーションを作成する

WebSocket アプリケーションには以下のコンポーネントと設定変更が必要です。
  • Javaクライアントまたは WebSocket が有効になっている HTML クライアント。次の場所で HTML クライアントブラウザーのサポートを確認できます。 http://caniuse.com/websockets
  • WebSocket サーバーエンドポイントクラス。
  • WebSocket を有効にするように設定された jboss-web.xml ファイル。
  • WebSocket API で依存関係を宣言するために設定されたプロジェクト依存関係。
  • Red Hat JBoss Enterprise Application Platform サーバー設定ファイルの Web サブシステムで NIO2 コネクターを有効にします。
注記
WebSocket アプリケーションには、JavaRuntimeEnvironment バージョン 7 以降が必要です。そうしないと、WebSocket が有効になりません。

手順17.1 WebSocket アプリケーションの作成

以下は、WebSocket アプリケーションの簡単な例です。接続を開き、メッセージを送信し、接続を閉じるためのボタンを提供します。他の機能を実装したり、実際のアプリケーションで必要となるエラー処理を含むことはありません。
  1. JavaScript HTML クライアントを作成します。

    以下は WebSocket クライアントの例になります。この例には 3 つの JavaScript 関数が含まれています。
    • connect(): この関数は WebSocket URI を渡す WebSocket 接続を作成します。リソースの場所は、サーバーエンドポイントクラスに定義されたリソースと一致します。この関数は、WebSocket をインターセプトして処理しますonopenonmessageonerror、とonclose
    • sendMessage(): この関数はフォームに入力された名前を取得し、メッセージを作成します。 さらに、WebSocket.send() コマンドを使用してメッセージを送信します。
    • disconnect(): この関数は WebSocket.close () コマンドを発行します。
    • displayMessage(): この関数は、ページ上の表示メッセージを WebSocket エンドポイントメソッドによって返された値に設定します。
    • displayStatus(): この関数は、WebSocket 接続ステータスを表示します。
    l
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
        <head>
            <title>WebSocket: Say Hello</title>
            <link rel="stylesheet" type="text/css" href="resources/css/hello.css" />
            <script type="text/javascript">
                var websocket = null;
    
                function connect() {
                    var wsURI = 'ws://' + window.location.host + '/jboss-websocket-hello/websocket/helloName';
                    websocket = new WebSocket(wsURI);
    
                    websocket.onopen = function() {
                        displayStatus('Open');
                        document.getElementById('sayHello').disabled = false;
                        displayMessage('Connection is now open. Type a name and click Say Hello to send a message.');
                    };
                    websocket.onmessage = function(event) {
                        // log the event                
                        displayMessage('The response was received! ' + event.data, 'success');
                    };
                    websocket.onerror = function(event) {
                        // log the event
                        displayMessage('Error! ' + event.data, 'error');
                    };
                    websocket.onclose = function() {
                        displayStatus('Closed');
                        displayMessage('The connection was closed or timed out. Please click the Open Connection button to reconnect.');
                        document.getElementById('sayHello').disabled = true;
                    };
                }
    
                function disconnect() {
                    if (websocket !== null) {
                        websocket.close();
                        websocket = null;
                    }
                    message.setAttribute("class", "message");
                    message.value = 'WebSocket closed.';
                    // log the event
                }
    
                function sendMessage() {
                    if (websocket !== null) {
                        var content = document.getElementById('name').value;
                        websocket.send(content);
                    } else {
                        displayMessage('WebSocket connection is not established. Please click the Open Connection button.', 'error');
                    }
                }
    
                function displayMessage(data, style) {
                    var message = document.getElementById('hellomessage');
                    message.setAttribute("class", style);
                    message.value = data;
                }
    
                function displayStatus(status) {
                    var currentStatus = document.getElementById('currentstatus');
                    currentStatus.value = status;
                }
    
            </script>
        </head>
        <body>
    
            <div>
                <h1>Welcome to JBoss!</h1>
                <div>This is a simple example of a WebSocket implementation.</div>
                <div id="connect-container">
                    <div>
                        <fieldset>
                            <legend>Connect or disconnect using WebSocket :</legend>
                            <input type="button" id="connect" onclick="connect();" value="Open Connection" />
                            <input type="button" id="disconnect" onclick="disconnect();" value="Close Connection" />
                        </fieldset>
                    </div>
                    <div>
                        <fieldset>
                            <legend>Type your name below. then click the `Say Hello` button :</legend>
                            <input id="name" type="text" size="40" style="width: 40%"/>
                            <input type="button" id="sayHello" onclick="sendMessage();" value="Say Hello" disabled="disabled"/>
                        </fieldset>
                    </div>
                    <div>Current WebSocket Connection Status: <output id="currentstatus" class="message">Closed</output></div>
                    <div>
                        <output id="hellomessage" />
                    </div>
                </div>
            </div>
        </body>
    </html>
  2. WebSocket サーバーエンドポイントを作成します。

    以下の方法のいずれかを使用して WebSocket サーバーエンドポイントを作成できます。
    • Programmatic Endpoint: エンドポイントは Endpoint クラスを拡張します。
    • Annotated Endpoint: エンドポイントクラスはアノテーションを使用して WebSocket イベントと対話します。これは、プログラム的なエンドポイントよりも簡単にコーディングできます。
    以下のコード例では、アノテーション付きエンドポイントが使用され、以下のイベントが処理されます。
    • The@ServerEndpointアノテーションは、このクラスを WebSocket サーバーエンドポイントとして識別し、パスを指定します。
    • WebSocket 接続が開かれると @OnOpen アノテーションがトリガーされます。
    • The@OnMessageメッセージが WebSocket 接続に送信されると、注釈がトリガーされます。
    • WebSocket 接続が閉じられると、@OnClose アノテーションがトリガーされます。
    package org.jboss.as.quickstarts.websocket_hello;
    
    import javax.websocket.CloseReason;
    import javax.websocket.OnClose;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.ServerEndpoint;
    
    @ServerEndpoint("/websocket/helloName")
    public class HelloName {
    
        @OnMessage
        public String sayHello(String name) {
            System.out.println("Say hello to '" + name + "'");
            return ("Hello" + name);    
        }
    
        @OnOpen
        public void helloOnOpen(Session session) {
            System.out.println("WebSocket opened: " + session.getId());
        }
        
        @OnClose
        public void helloOnClose(CloseReason reason) {
            System.out.println("Closing a WebSocket due to " + reason.getReasonPhrase());
        }
    }
    
  3. jboss-web.xml ファイルを設定します。

    を作成する必要があります<enable-websockets>アプリケーション WEB-INF/jboss-web.xml の要素を作成し、true に設定します。
    <?xml version="1.0" encoding="UTF-8"?>
    <!--Enable WebSockets -->
    <jboss-web>
       <enable-websockets>true</enable-websockets>
    </jboss-web>
  4. プロジェクト POM ファイルで WebSocket API の依存関係を宣言します。

    Maven を使用する場合は、プロジェクト pom.xml ファイルに以下の依存関係を追加します。
    <dependency>
      <groupId>org.jboss.spec.javax.websocket</groupId>
      <artifactId>jboss-websocket-api_1.0_spec</artifactId>
      <version>1.0.0.Final</version>
      <scope>provided</scope>
    </dependency>
    
  5. JBoss EAP サーバーを設定します。

    http を設定します<connector>サーバー設定ファイルの Web サブシステムで、NIO2 プロトコルを使用します。
    1. JBoss EAP サーバーを起動します。
    2. ご使用のオペレーティングシステム向けのコマンドを使用して、管理 CLI を起動します。
      Linux の場合
      EAP_HOME/bin/jboss-cli.sh --connect
      Windows の場合:
      EAP_HOME\bin\jboss-cli.bat --connect
    3. JBoss EAP サーバー設定ファイルの Web サブシステムでノンブロッキング JavaNIO2 コネクタープロトコルを有効にするには、次のコマンドを入力します。
      /subsystem=web/connector=http/:write-attribute(name=protocol,value=org.apache.coyote.http11.Http11NioProtocol)
      どちらのコマンドでも、次の結果が表示されます。
      {
          "outcome" => "success",
          "response-headers" => {
              "operation-requires-reload" => true,
              "process-state" => "reload-required"
          }
      }
    4. 設定を再ロードするようにサーバーに通知します。
      reload
      以下の結果が表示されるはずです。
      {
          "outcome" => "success",
          "result" => undefined
      }
      
    5. JBoss EAP サーバー設定ファイルへの変更を確認します。これで、Web サブシステムに http 用の次の XML が含まれるはずです。<connector>
      <subsystem xmlns="urn:jboss:domain:web:2.1" default-virtual-server="default-host" native="false">
          <connector name="http" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="http" socket-binding="http"/>
          <virtual-server name="default-host" enable-welcome-root="true">
          <alias name="localhost"/>
              <alias name="example.com"/>
          </virtual-server>
      </subsystem>