[Java規格支援機能]websocket

ウェブアプリケーション開発において、双方向通信を行う場合、通信規格であるwebsocketを使用します。

NimbusではJavaEEサーバ上で動作するwebsocketアプリケーション開発を支援する機能を提供します。 JSR356

サーバサイドのwebsocketアプリケーションを作成するためのServerEndpointのデフォルト実装がDefaultEndpointServiceです。

ServerEndpointを生成するためのConfiguratorのデフォルト実装がDefaultConfiguratorServiceです。

websocketアプリケーションを作成するには、AbstractMessageHandlerFactoryServiceAbstractMessageHandlerServiceを継承したクラスを作成する必要があります。

また、websocketの事前認証用ServletがWebSocketAuthServletです。

関連するパッケージは、以下です。

ServerEndpointのデフォルト実装 DefaultEndpointService

javax.websocket.Endpointを継承したサービスクラスです。

メッセージハンドラ(MessageHandlerSessionMessageHandler)を複数登録することができます。

セッション開始時に認証を行うためのAuthenticatorを登録することができます。

また、セッション開始時、セッション終了時、エラー発生時にメッセージハンドラの該当処理を呼び出します。

Configuratorのデフォルト実装 DefaultConfiguratorService

javax.websocket.server.ServerEndpointConfig.Configuratorを継承したサービスクラスです。

ServerEndpointのインスタンスを生成するためのConfiguratorです。

生成するEndpointを登録することができます。

メッセージハンドラを生成するためのFactory AbstractMessageHandlerFactoryService と メッセージハンドラ AbstractMessageHandlerService

DefaultEndpointServiceに登録するメッセージハンドラとそのメッセージハンドラを生成するためのFactoryサービスです。

それぞれの抽象クラスを継承し、websocketアプリケーションを生成します。

AbstractMessageHandlerFactoryServiceAbstractMessageHandlerService の簡単な実装例を示します。

  1. import java.io.IOException;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. import java.util.Set;
  5. import javax.websocket.CloseReason;
  6. import javax.websocket.EndpointConfig;
  7. import javax.websocket.Session;
  8. import jp.ossc.nimbus.core.Service;
  9. public class SampleMessageHandlerFactoryService extends AbstractMessageHandlerFactoryService
  10. implements SampleMessageHandlerFactoryServiceMBean {
  11. protected Set sessionSet;
  12. public void createService() throws Exception {
  13. sessionSet = new HashSet();
  14. }
  15. protected Service createServiceInstance() throws Exception {
  16. return new SampleMessageHandlerService();
  17. }
  18. public void sendMessage(String message) {
  19. Iterator itr = sessionSet.iterator();
  20. while(itr.hasNext()) {
  21. Session session = (Session)itr.next();
  22. if(session.isOpen()) {
  23. try {
  24. session.getBasicRemote().sendText(message);
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }
  30. }
  31. public class SampleMessageHandlerService extends AbstractMessageHandlerService {
  32. @Override
  33. protected void onOpenProcess(Session session, EndpointConfig config) {
  34. if(!sessionSet.contains(session)) {
  35. sessionSet.add(session);
  36. }
  37. SessionProperties prop = SessionProperties.getSessionProperty(session);
  38. String message = "open session id=" + prop.getId() + " sessionId=" + session.getId();
  39. // メンバーが増えたことを全員に通知
  40. sendMessage(message);
  41. }
  42. @Override
  43. protected void onCloseProcess(Session session, CloseReason closeReason) {
  44. if(sessionSet.contains(session)) {
  45. sessionSet.remove(session);
  46. }
  47. SessionProperties prop = SessionProperties.getSessionProperty(session);
  48. String message = "close session id=" + prop.getId() + " sessionId=" + session.getId();
  49. // メンバーが減ったことを全員に通知
  50. sendMessage(message);
  51. }
  52. @Override
  53. protected void onErrorProcess(Session session, Throwable thr) {
  54. thr.printStackTrace();
  55. }
  56. @Override
  57. protected void onMessageProcess(String message) {
  58. SessionProperties prop = SessionProperties.getSessionProperty(session);
  59. message = "message recieve from session id=" + prop.getId() + " sessionId=" + session.getId() + " message is \"" + message + "\"";
  60. // 受信したメッセージを全員に通知
  61. sendMessage(message);
  62. }
  63. }
  64. }

Websoket事前認証Servlet WebSocketAuthServlet

通常のWebsocketアプリケーションはEndpointのセッション開始(OnOpen)時に認証処理を行うことが多いと思われるが、Nimbusでは事前にServletで認証を行える仕組みを提供している。

WebSocketAuthServlet には認証を行うためのAuthenticatorを設定することができる。

Authenticatorは、認証チケットを生成し、WebSocketAuthServletはその認証チケットをクライアントに返却する。

クライアントはWebsocketのセッション開始時のリクエストパラメータに認証チケットを含める。

ServerEndpointでは、セッション開始時にパラメータの認証チケットのチェックを行う。



サンプルは、以下。