code up

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Atmosphere検証中

AtmosphereというWeb非同期通信のフレームワークを検証中。

とあるWebページで定期的な画面更新が必要で、最初はsetIntervalで定期的に更新していた。でもアクセス数が徐々に増えてきたため、Cometを使って更新することにした。

Servlet API 3.0のasyncSupportedだけでシンプルに作っても良かったんだけど、せっかくなのでAtmosphereフレームワークでできないかな、と検証中。

別ベンダーに構築して頂いたJ2SE6 + Tomcat7 + Seasar2 + SAStruts + S2Axis2という既に食い合わせの悪そうな環境にAtmosphereを追加した。

まだサンプルを動かした程度で本格的なハンドラは登録してないけど、今のところ他のアプリケーションの邪魔をすることなく動作しているみたい。

以下は備忘録。

バージョンは最新版のMaven Repoから取れた1.1.0beta1を使う
色々な組み合わせがサポートされているが、基本Long-Polling(aka Comet)を使う。WebSocketはIE10からのようだし
既存のサーブレットなどを活かしたいというのと、axis2のjsr311とコンフリクトを起こしそうなのでjerseyは導入せずにMeteorを使うことにした
Picking the right Atmosphere APIを読む限り、インタフェースベースのAtmosphereHandlerよりもサーブレットベースのMeteorの方が既存のシステムに組み込みやすそうなのでMeteorで構築することに
SAStruts(=Strutsベース)なので実際はどちらでも良さそうだけど
URLを呼び出すとorg.atmosphere.cpr.AtmosphereMappingException: No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @AtmosphereHandlerServiceという例外が起きた
eu.infomas/annotation-detectorのライブラリが抜けていただけ。未検証だけどweb.xmlのweb-appタグでmetadata-complete="true"としてもダメかもしれない
ivyで管理しているのだが、依存するjarは取ってこないようにしていたのが原因だった(ivy.xmlは最終的に下記に)
<!-- Comet -->
<dependency org="org.slf4j" name="slf4j-api" rev="${org.slf4j.slf4j-api}" transitive="false" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="${org.slf4j.slf4j-log4j12}" transitive="false" />
<dependency org="org.atmosphere" name="atmosphere-runtime" rev="${org.atmosphere.atmosphere-runtime}" transitive="false" />
<dependency org="org.atmosphere" name="atmosphere-compat-jbossweb" rev="${org.atmosphere.atmosphere-compat-jbossweb}" transitive="false" />
<dependency org="org.atmosphere" name="atmosphere-compat-tomcat" rev="${org.atmosphere.atmosphere-compat-tomcat}" transitive="false" />
<!-- これがないとAnnotationが見つからない -->
<dependency org="eu.infomas" name="annotation-detector" rev="${eu.infomas.annotation-detector}" transitive="false" />
annotation-detectorを使わない場合はweb.xmlにorg.atmosphere.servletのinit-paramを与えればいい
<servlet>
	<description>MeteorServlet</description>
	<servlet-name>MeteorServlet</servlet-name>
	<servlet-class>org.atmosphere.cpr.MeteorServlet</servlet-class>

	<init-param>
		<param-name>org.atmosphere.servlet</param-name>
		<param-value>foo.bar.MyMeteor</param-value>
	</init-param>
	<load-on-startup>0</load-on-startup>
</servlet>
Failed using comet support: org.atmosphere.container.Tomcat7AsyncSupportWithWebSocket, error: Tomcat failed to detect this is a Comet application because context.xml is missing or the Http11NioProtocol Connector is not enabled. If that's not the case, you can also remove META-INF/context.xml and WEB-INF/lib/atmosphere-compat-tomcat.jar Is the Nio or Apr Connector enabled?という警告
Tomcatのデフォルトの8080ポートのコネクタを利用時に発生した警告。server.xmlでHttp11NioProtocolを使うようにしたら消えた
<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443"/>
サンプルはブロードキャスト(チャットのように全員に配信するもの)ばかりだけど、サーバーとクライアントの1対1の通信もできる。その場合はdoGet()で接続を確立して、doPost()で応答を返すような構成となる模様
コメットの問題点

気づいたことなど

1.1.0beta1のMeteorServletだとWebSocketで通信した際、NullPointerExceptionが発生、streamingでは発生しなかった。1.0.4にすると直った。

2012/11/11 21:59:48 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler process
致命的: Error reading request, ignored
java.lang.NullPointerException
        at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:339)
        at org.atmosphere.container.TomcatWebSocketHandler.onTextData(TomcatWebSocketHandler.java:83)
        at org.apache.catalina.websocket.StreamInbound.doOnTextData(StreamInbound.java:186)
        at org.apache.catalina.websocket.StreamInbound.onData(StreamInbound.java:134)
        at org.apache.coyote.http11.upgrade.UpgradeProcessor.upgradeDispatch(UpgradeProcessor.java:83)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:583)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1653)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
        at java.lang.Thread.run(Thread.java:679)
関連記事
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。