Websocketプローブ


従来はflashやjava appletなどのブラウザ側プラグインを使用してサーバとソケット通信を確立していたが、これらのプラグイン技術はウェブチャットやウェブゲームに広く応用されており、html 5が提供するwebsocketがこれらのプラグインに取って代わる傾向にある.
Websocketの前に、実装サーバがブラウザにメッセージをプッシュするには、ajaxポーリングとcomet長ポーリングの2つの方法があります.
  • ajaxポーリング(polling):ブラウザ側がサーバに要求を続け、「新しいデータはありますか?」と尋ねると、データがあるかどうかにかかわらず返されます.この方法はクライアントにとってもサーバにとっても大きな圧力です.
  • cometテクノロジー(long-polling):ブラウザは、データが来るまでブラウザに返信しないようにサーバに長い接続を確立する要求を開始します.1つのリクエストが終了すると、ブラウザはすぐに別のリクエストを開始します.このテクノロジーの欠点は、サーバのメンテナンスを必要とするリクエストの数が多いことです.同時に多くのリクエストが発生していることに相当します.この技術は依然として流行している.

  • 一、Javaのwebsocketライブラリ
    websocketはjava標準ライブラリの一部であり、javaxパッケージの下にありますが、いくつかのインタフェースを定義しているだけです.Websocketには、Tomcat、jetty、Spring、TooTallNate組織が発表したjava-websocketライブラリ、atmosphereライブラリ、socket.ioというjavaバージョンなど、異なる実装があります.
  • socket.io:https://github.com/socketio/socket.io-client-java、このライブラリはクライアントにすぎず、server実装は提供されていません.
  • ToolTallNateライブラリ公式サイト:http://java-websocket.org/、このライブラリはbareboneと呼ばれています(骨と皮で、非常にコンパクトです).スローガンはA barebones WebSocket client and server implementation written in 100%Java.
  • Atmosphere: The Asynchronous WebSocket/Comet Framework.Atmosphere transparently supports WebSockets, Server Sent Events (SSE), Long-Polling, HTTP Streaming (Forever frame) and JSONP.

  • 二、Pythonのwebsocketライブラリ
    Websocketプロトコル自体は複雑ではなく、100行のPythonコードで簡単なwebsocketプロトコルを実現できます.Pythonの最も基本的なwebsocketライブラリはgevent.websocketです.Flaskを使用している人たちは、flask-socketsというライブラリをカプセル化して使いやすくしました.パッケージが重いライブラリflask-socketioもあります.しかし、flask-socketioとflask-socketsの2つのライブラリを実行できませんでした.gevent-websocketは正常に実行されました.
    JSには各バージョンのブラウザと互換性のあるライブラリsocketioがあり、websocketのパッケージであり、Web側でこのライブラリを使用するのが最適な選択であるはずです.
    三、旧版tomcatのwebsocket
    Javax.websocketインタフェースが出る前にtomcat 7はwebsocketをサポートしていました.そこでjavax.websocketが出てきた後、tomcat 8はtomcat 7で定義されたwebsocketを廃棄し始め、tomcat 7のwebsocketに関するパッケージはorg.apache.catalina.websocketにある.
    パッケージorg.apache.catalina.websocketのこれらのクラスはWebSocket開発サービス側にサポートされています.これらのクラスの主な機能は以下の通りです.
    1、Constants:パッケージorg.apache.catalina.websocketで使用される定数定義このクラスでは、静的定数定義のみが含まれ、論理的実装はありません.2、MessageInbound:メッセージベースのWebSocket実装クラス(イントラメッセージ付き)であり、アプリケーションはこのクラスを拡張し、その抽象的な方法onBinaryMessageとonTextMessageを実装しなければならない.3、StreamInbound:ストリームベースのWebSocket実装クラス(イントラストリーム付き)であり、アプリケーションはこのクラスを拡張し、その抽象的な方法onBinaryDataとonTextDataを実装しなければならない.4、WebSocketServicelet:RFC 6455のWebSocket接続に従うServicelet基本実装を提供する.クライアントがWebSocket接続サービスを使用する場合は、WebSocketServiceのサブクラスを接続ポートとして使用する必要があります.同時に、このサブクラスは、inboundインスタンス(MessageInboundまたはStreamInbound)を作成するために、WebSocketServiceの抽象的なメソッドcreateWebSocketInboundを実装する必要があります.5、WsFrame:完全なWebSocketフレームワークを表します.6、WsHttpServletRequestWrapper:パッケージされたHttpServletRequestオブジェクト.7、WsInputStream:WebSocketフレームの下部にあるsocketに基づく入力ストリーム.8、WsOutbound:クライアントにメッセージを送る機能を提供する.クライアントへの書き込み方法はすべて同期されており、マルチスレッドがクライアントに同時にデータを書き込むことを防止できます.
    その典型的な書き方は以下の通りです.
    public class ChatWebSocketServlet extends WebSocketServlet {  
      
        private static final long serialVersionUID = 1L;  
      
        private static final String GUEST_PREFIX = "Guest";  
      
        private final AtomicInteger connectionIds = new AtomicInteger(0);  
        private final Set connections =  
                new CopyOnWriteArraySet();  
        //   Inbound  ,WebSocketServlet           
        @Override  
        protected StreamInbound createWebSocketInbound(String subProtocol,  
                HttpServletRequest request) {  
            return new ChatMessageInbound(connectionIds.incrementAndGet());  
        }  
        // MessageInbound  ,    WebSocket          
        private final class ChatMessageInbound extends MessageInbound {  
      
            private final String nickname;  
      
            private ChatMessageInbound(int id) {  
                this.nickname = GUEST_PREFIX + id;  
            }  
            // Open    
            @Override  
            protected void onOpen(WsOutbound outbound) {  
                connections.add(this);  
                String message = String.format("* %s %s",  
                        nickname, "has joined.");  
                broadcast(message);  
            }  
            // Close    
            @Override  
            protected void onClose(int status) {  
                connections.remove(this);  
                String message = String.format("* %s %s",  
                        nickname, "has disconnected.");  
                broadcast(message);  
            }  
            //          
            @Override  
            protected void onBinaryMessage(ByteBuffer message) throws IOException {  
                throw new UnsupportedOperationException(  
                        "Binary message not supported.");  
            }  
            //         
            @Override  
            protected void onTextMessage(CharBuffer message) throws IOException {  
                // Never trust the client  
                String filteredMessage = String.format("%s: %s",  
                        nickname, HTMLFilter.filter(message.toString()));  
                broadcast(filteredMessage);  
            }  
            //                 (  )  
            private void broadcast(String message) {  
                for (ChatMessageInbound connection : connections) {  
                    try {  
                        CharBuffer buffer = CharBuffer.wrap(message);  
                        connection.getWsOutbound().writeTextMessage(buffer);  
                    } catch (IOException ignore) {  
                        // Ignore  
                    }  
                }  
            }  
        }  

    四、javax.websocket定義の関数パラメータ
    IllegalArgumentException
    No payload parameter present on the method[message]

    あるべきパラメータがないという意味です.例えば
  • onError()にはThrowableパラメータ
  • が必要です.
  • onMessage()メッセージ
  • を受け入れるには、String messageパラメータまたはByteBufferタイプのパラメータが必要です.
    この異常を放出する異常スタックに沿ってソースコードを1つずつ開くと、コンテナ初期化サーバEndPointの各詳細と、その関数の解析が表示されます.onOpen(EndpointConfig)onClose(CloseReason)onError(Throwable)onMessage(PhongMessage|InputStream|byte[]|ByteBuffer|Reader|String,boolean isLastMessage)
    これらは、onMessageがReader(テキストを受け入れる)であってもInputStream(バイナリ)であってもよいデータ型のデータを受け入れなければならないパラメータであり、PhongMessageはping情報を処理する.byte[]とByteBufferがInputStreamを読み込んだものである.StringはReaderを読み取ります.OnOpenとOnError関数にはStringタイプのパラメータはありません.これらは上記のタイプのパラメータしか含まれません.OnOpenとOnErrorにStringタイプのパラメータがある場合は、@PathParam注記のStringタイプのパラメータしかありません.そうしないと、A parameter of type [class java.lang.String] was found on method[error] of class [java.lang.reflect.Method] that did not have a @PathParam annotationエラーが発生します.
    五、TooTallNate-java-websocket
    このライブラリは100%Javaで実現され、nioに基づいています.WebsocketサーバとWebsocketクライアントが含まれています.公式倉庫には豊富なコード例が含まれています.このライブラリはjavax.websocketインタフェースに合致せず、純粋に民間のwebsocket実装である.サーバ側はWebSocketServerというクラスをインスタンス化し、onOpen、onMessageなどの関数を上書きする必要があります.クライアントは、WebページのほかにJavaであってもよい.Javaでwebsocketクライアントを実装するには、WebSocketClientというクラスをインスタンス化する必要があります.
    Tomcatのwebsocket実装は、8080ポートを共有できるように、websocketおよびwebアプリケーションのように、webアプリケーション全体とうまく一体化することができる.TooTallNate-java-websocketを使用する場合は、2つのポートを使用する必要があります.
    転載先:https://www.cnblogs.com/weiyinfu/p/6287117.html