Tomcat 8.x + Wicket8 で WebSocket native

Tomcat 8.x + Wicket8 で WebSocket native がなかなかうまくできず苦労していたのだが、
やっと解った。。

Tomcat 7.x + Wicket7 では、WebSocketFilter と WicketFilter を web.xml で2つ書いてURL
による切り分けをしてたのですが、
Tomcat 8.x + Wicket8 では、できません。これが長い間、苦戦した原因だった。

よって、org.apache.wicket.protocol.http.WicketFilter と、
Wicket8 から、
  org.apache.wicket.protocol.ws.tomcat7.Tomcat7WebSocketFilter ではなく、
org.apache.wicket.protocol.ws.javax.JavaxWebSocketFilter

WicketFilter と JavaxWebSocketFilter の2つフィルタの宣言はダメなのである。

<filter-name>WebFilter</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class><filter-name>WebSocketFilter</filter-name>
<filter-class>org.apache.wicket.protocol.ws.javax.JavaxWebSocketFilterr</filter-class>
<filter-mapping>
   <filter-name>WebFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
   <filter-name>WebSocketFilter</filter-name>
   <url-pattern>/wicket/*</url-pattern>
</filter-mapping>

というのは、成立しないのである。


JavaxWebSocketFilter だけにしなければならない。。

<filter>
   <filter-name>WebFilter</filter-name>
   <filter-class>org.apache.wicket.protocol.ws.javax.JavaxWebSocketFilter</filter-class>
   <init-param>
      <param-name>applicationClassName</param-name>
      <param-value>org.sample.SampleApplication</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>WebFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

私は、細かく分類、分岐させるWebSocket までは必要なくブロードキャストで充分なので、

https://ci.apache.org/projects/wicket/guide/6.x/guide/nativewebsockets.html

にあるような、WebApplication でWebSocketResourceを登録、、
  getSharedResources().add("someName", new MyWebSocketResource());
ここまでは実行しない。どうもこのキー名を登録した後の、キーに限定させた
WebSocket 通信方法がよくわからない。
でも、ブロードキャストは成功した。
また、上のガイドのページでは、
 page.add(new BaseWebSocketBehavior("someName"));
と書いてあるこれが役にたたない。

pom.xml も、

Tomcat 7.x + Wicket7 では、、

<dependency>
   <groupId>org.apache.wicket</groupId>
   <artifactId>wicket-native-websocket-tomcat</artifactId>
   <version>7.6.0</version>
</dependency>
<dependency>
   <groupId>org.apache.wicket</groupId>
   <artifactId>wicket-native-websocket-javax</artifactId>
   <version>7.6.0</version>
</dependency>


Tomcat 8.x + Wicket8 の pom.xml

<dependency>
   <groupId>org.apache.wicket</groupId>
   <artifactId>wicket-native-websocket-javax</artifactId>
   <version>8.0.0-M6</version>
</dependency>

wicket-native-websocket-javaxだけにする。


受信側 WebPage の記述。。。。

コンストラクタで、WebSocketBehaviorを追加

add(new WebSocketBehavior(){
   @Override
   protected void onConnect(ConnectedMessage message){
      super.onConnect(message);
   }
   @Override
   protected void onMessage(WebSocketRequestHandler handler, TextMessage message){
   }
   @Override
   public void onException(Component component, RuntimeException exception){
      logger.warn(exception.getMessage(), exception);
   }
});

add(new WebSocketBehavior(){} ); でも良いのだが、onConnect、 onException ぐらいは捕捉したい。
受信してもこのビヘビアのonMessage で捕捉できるわけではない!!

受信は、Webページに onEvent メソッドオーバーライドで捕捉する。

@Override
public void onEvent(IEvent<?> event){
   if (event.getPayload() instanceof WebSocketPushPayload){
      WebSocketPushPayload wsEvent = (WebSocketPushPayload)event.getPayload();
      WebSocketRequestHandler handler = wsEvent.getHandler();

      // FeedMessage という任意の受信データを受け取る
      FeedMessage feed = (FeedMessage)wsEvent.getMessage();

      // 任意の処理。。。

      // ページに書いたコンテナ更新
      receive_container.modelChanged();
      handler.add(receive_container);
      handler.appendJavaScript("receiveContainer();");
   }
}

WebSocketRequestHandler#getMessage() で受信データを参照する。
event.getType().name() でイベント種別も確認できる。


クライアント側。。。。

JavaScript ではなく、送信用のページのフォーム送信で、以下のように書く、

WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(getApplication());
WebSocketPushBroadcaster broadcaster = new WebSocketPushBroadcaster(webSocketSettings.getConnectionRegistry());
broadcaster.broadcastAll(getApplication(), message);