Hatena::¥Ö¥í¥°(Diary)

IT-Walker on hatena ¤³¤Î¥Ú¡¼¥¸¤ò¥¢¥ó¥Æ¥Ê¤ËÄɲà RSS¥Õ¥£¡¼¥É

2006-11-21 Ajax+Java¥¢¡¼¥­¥Æ¥¯¥Á¥ã¹½ÃÛµ­Âè»Í²ó

¢£

¤µ¤Æ¤µ¤Æ¡¢¤Á¤ç¤Ã¤È´Ö¤¬¶õ¤¤¤Æ¤·¤Þ¤¤¤Þ¤·¤¿¤¬¡¢º£²ó¤ÏÁ°²ó¤Îͽ¹ð¤É¤ª¤êCometd¤Ë¤Ä¤¤¤Æ¤â¤¦¾¯¤·¿¼¤¯·¡¤ê²¼¤²¤Æ¸«¤Æ¤¤¤­¤¿¤¤¤È»×¤¤¤Þ¤¹¡£

ËÜÂê¤ËÆþ¤ëÁ°¤Ë

Á°²ó¤ªÏä·¤¿¤È¤ª¤ê¡¢Cometd¤ÏComet¤Î¼ÂÁõ¤Ç¤¹¡£

Comet¤È¤¤¤¦¹Í¤¨Êý¤Î¤É¤³¤Ë²ÁÃͤ¬¤¢¤ë¤«¤È¤¤¤¦¤È¡¢¤ä¤Ï¤ê¥ê¥¢¥ë¥¿¥¤¥àÀ­¤Ç¤¹¤è¤Í¡£¥¤¥ó¥¿¡¼¥Í¥Ã¥È¤ò¶´¤ó¤À¡¢¥ê¥â¡¼¥È¤ÇȯÀ¸¤·¤¿¥¤¥Ù¥ó¥È¤¬¿ï»þ¸¡ÃΤµ¤ì¤Æ¥Ö¥é¥¦¥¶¤Îɽ¼¨¤¬¤É¤ó¤É¤ó¹¹¿·¤µ¤ì¤Æ¤¤¤¯¡¢¤½¤¦¤¤¤¦µ¡Ç½¤¬½ÅÍפʾì¹ç¤ËºÎÍѤ·¤¿¤¤¥Æ¥¯¥Î¥í¥¸¤Ê¤ï¤±¤Ç¤¹¡£

¤Ç¡¢¤³¤³¤Ç°ì¤Ä¹Í¤¨¤¿¤¤¤Î¤¬¡¢¤½¤¦¤¤¤¦¥ê¥¢¥ë¥¿¥¤¥àÀ­¤òµá¤á¤é¤ì¤ëWeb¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë¤â¤¤¤¯¤Ä¤«¥Ñ¥¿¡¼¥ó¤¬¤¢¤ë¤È¤¤¤¦¤³¤È¡£Ëͤ¬¹Í¤¨¤ë¤Î¤Ï°Ê²¼¤ÎÆó¤Ä¤Ç¤¹¡£

  • ¾ðÊó¶¦Í­·¿¡¦¡¦¡¦¥Á¥ã¥Ã¥È¤È¤«¡¢¥³¥ó¥Æ¥ó¥Ä¶¦Í­¥¢¥×¥ê¤È¤«¡¢¡Ö狼¡×¤¬¹Ô¤Ã¤¿Êѹ¹¤¬¼«Ê¬¤Î¼ê¸µ¤Ë¤âÆÏ¤¯¤È¤¤¤¦¥¿¥¤¥×¡£
  • ¾ðÊóÇÛ¿®·¿¡¦¡¦¡¦³ô²Á¥Á¥ã¡¼¥È¤È¤«¡¢°ÙÂØ²Á³Ê¥Ü¡¼¥É¤È¤«¡¢¥µ¡¼¥Ð¤«¤é¥¯¥é¥¤¥¢¥ó¥È¤ËÂФ·¤Æ°ìÊýŪ¤Ë¡¢Æ±°ì¤Î¾ðÊó¤òÇÛ¿®¤¹¤ë¤È¤¤¤¦¥¿¥¤¥×¡£

Cometd¤Ï¡¢¤³¤Î¤É¤Á¤é¤â¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£¥¹¥Ð¥é¥·¥¤¡£

¤³¤Î¤É¤Á¤é¤ò¼è¤ê°·¤¦¤Î¤«¤Ç¿¾¯¥×¥í¥°¥é¥ß¥ó¥°¥¹¥¿¥¤¥ë¤¬ÊѤï¤ê¤Þ¤¹¡£

¤Ç¡¢º£²ó¤Ï¾ðÊóÇÛ¿®·¿¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥óºîÀ®¤òÂêºà¤Ë¡¢Cometd¤Î°·¤¤Êý¤ò¤·¤Ã¤«¤ê³Ø¤ó¤Ç¤¤¤­¤¿¤¤¤È»×¤¤¤Þ¤¹¡£

Á°²ó¤Ç¥Ó¥ë¥É¤È¡¢¥Á¥ã¥Ã¥È¥Ç¥â¤òưºî¤µ¤»¤ë¤È¤³¤í¤Þ¤Ç³Ø¤Ó¤Þ¤·¤¿¤Î¤Ç¡¢º£²ó¤Ï¼«Ê¬¤ÇCometd¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤òºîÀ®¤¹¤ë¤¿¤á¤Ë¤Ï¤É¤¦¤·¤Æ¤¤¤±¤ÐÎɤ¤¤«¤ò³Ø¤Ó¤Þ¤¹¡£

Cometd¤Î¥»¥Ã¥È¥¢¥Ã¥×

¤Þ¤º¤Ï¥µ¡¼¥Ð¦¤Î¥»¥Ã¥È¥¢¥Ã¥×ÊýË¡¤«¤é¡£¤³¤ÎÉôʬ¤Ë´Ø¤·¤Æ¤Ï¡¢¾ðÊó¶¦Í­·¿¤Ç¤â¾ðÊóÇÛ¿®·¿¤Ç¤âÊѤï¤ê¤Þ¤»¤ó

CometdËÜÂΤÏCometdServlet¤È¤¤¤¦¥µ¡¼¥Ö¥ì¥Ã¥È¤Ê¤Î¤Ç¡¢web.xml¤Ë¥µ¡¼¥Ö¥ì¥Ã¥È¤ÎÅÐÏ¿¤ò¤·¤Þ¤¹¡£

  <!-- ¥µ¡¼¥Ö¥ì¥Ã¥È¤ÎÅÐÏ¿ -->
  <servlet>
    <servlet-name>cometd</servlet-name>
    <servlet-class>org.mortbay.cometd.CometdServlet</servlet-class>
    <init-param>
      <param-name>filters</param-name>
      <param-value>/WEB-INF/filters.json</param-value>
    </init-param>
    <init-param>
      <param-name>timeout</param-name>
      <param-value>15000</param-value>
    </init-param>
    <init-param>
      <param-name>multi-timeout</param-name>
      <param-value>1500</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <!-- ¥µ¡¼¥Ö¥ì¥Ã¥È¤ÈURL¤Î¥Þ¥Ã¥Ô¥ó¥°»ØÄê -->
  <servlet-mapping>
    <servlet-name>cometd</servlet-name>
    <url-pattern>/cometd/*</url-pattern>
  </servlet-mapping>

¤¢¤Þ¤ê½ÅÍפʥե¡¥¯¥¿¡¼¤Ç¤Ï¤Ê¤¤¤Ç¤¹¤¬¡¢¥µ¡¼¥Ö¥ì¥Ã¥È¤Î½é´ü²½¥Ñ¥é¥á¡¼¥¿(init-param)¤Ç»ØÄꤵ¤ì¤Æ¤¤¤ëÃͤˤĤ¤¤Æ¤Ï°Ê²¼¡£

¥Ñ¥é¥á¡¼¥¿Ì¾ÀâÌÀ
filters¥¯¥é¥¤¥¢¥ó¥È¤ËÊֵѤ¹¤ëJSON¥Ç¡¼¥¿¤ËÂФ¹¤ë¥Õ¥£¥ë¥¿
timeout¥Ý¡¼¥ê¥ó¥°¤Î¥¿¥¤¥à¥¢¥¦¥È¡£¤³¤Î¿ôÃͤòÂ礭¤¯¤¹¤ë¤Û¤É¥Í¥Ã¥È¥ï¡¼¥¯¤Î¥È¥é¥Õ¥£¥Ã¥¯¤¬¸º¤ê¤Þ¤¹
multi-timeoutƱ¤¸¥Ö¥é¥¦¥¶¤«¤éÍ褿¥ê¥¯¥¨¥¹¥È¤òÊ£¿ô¥Ý¡¼¥ê¥ó¥°¤·¤Æ¤¤¤ë¤È¤­¤Ë»ÈÍѤ¹¤ë¥¿¥¤¥à¥¢¥¦¥È

filters¥Ñ¥é¥á¡¼¥¿¤ËÂФ·¤Æ¤Ï¡¢Cometd¤¬À¸À®¤¹¤ëJSON¥Ç¡¼¥¿¤ËÂФ·¤ÆÊ¸»úÎó¥Õ¥£¥ë¥¿¥ê¥ó¥°¤ò¤«¤±¤ë»ö¤¬²Äǽ¤Ç¤¹¡£Cometd¤Ë¤è¤ë¼ÂÁõ¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤Ê¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡£

¥Õ¥£¥ë¥¿¤Î¥¯¥é¥¹Ì¾ÀâÌÀ
org.mortbay.cometd.filter.NoMarkupFilter"<"¤È">"¤òÁ´¤Æ"<"¤È">"¤ËÊÑ´¹¤·¤Þ¤¹¡£
org.mortbay.cometd.filter.NoScriptsFilter<script>¥¿¥°¤òÁ´¤Æ<span>¥¿¥°¤ËÃÖ´¹¤·¤Þ¤¹¡£
org.mortbay.cometd.filter.RegexFilter½é´ü²½¥Õ¥¡¥¤¥ë¤Ç»ØÄꤵ¤ì¤¿Àµµ¬É½¸½¤Ë¥Þ¥Ã¥Á¤¹¤ëʸ»úÎó¤òÁ´¤ÆÃÖ¤­´¹¤¨¤Þ¤¹¡£

¸½¾õ¤Îcometd¤Ç¤Ï¡¢filters.json¤Ë¤è¤Ã¤ÆRegexFilter¤¬»ØÄꤵ¤ì¤Æ¤ª¤ê¡¢Microsoft¤òMicro$oft¤ËÊÑ´¹¤·¤¿¤ê¡¢Tomcat¤È¸À¤¦Ê¸»úÎ󤬯þ¤Ã¤Æ¤¤¤ë¤ÈÁ´¤Æ¶õʸ»úÎó¤ËÊÑ´¹¤·¤¿¤ê(¾Ð)¤È¡¢¤Ê¤«¤Ê¤«¶¯Îõ¤Ç¤¹¡£

°Ê¾å¤ÎÀßÄê¤òÀµ¤·¤¯¹Ô¤¨¤Ð¡¢¤â¤¦Cometd¤Ë¤è¤ëPushÇÛ¿®¤Ï½àÈ÷´°Î»¤Ç¤¹¡£

¤¢¤È¤Ï¡¢Cometd¤¬Ä󶡤¹¤ëJavaScript´Ø¿ô¤òÍѤ¤¤ÆPushÇÛ¿®¤ò¹ØÆÉ(subscribe)¤¹¤ë¤è¤¦¥×¥í¥°¥é¥ß¥ó¥°¤¹¤ì¤ÐOK¤Ç¤¹¡£

Cometd¤¬Ä󶡤¹¤ëJavaScript API

Cometd¤¬Ä󶡤¹¤ëJavaScript´Ø¿ô¤Î¤¦¤Á¡¢º£²óÂоݤȤ·¤Æ¤¤¤ë¾ðÊóÇÛ¿®·¿¤ÎAjax¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ËɬÍפʤâ¤Î¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¹¡£

/**
 * cometd¤Î½é´ü²½¤ò¹Ô¤¤¤Þ¤¹¡£
 * @param message ¸½ºß¹ØÆÉÃæ¤Î¥¯¥é¥¤¥¢¥ó¥È¤ËÇÛ¿®¤¹¤ë¥á¥Ã¥»¡¼¥¸¡£¶õ¤Ç¤è¤¤
 * @param root cometd¥µ¡¼¥Ö¥ì¥Ã¥È¤ÎURL¤ò»ØÄê¡£
 *  ¾Êά»þ¤Ï¡¢Dojo¥Õ¥ì¡¼¥à¥ï¡¼¥¯¤Î½é´ü²½¥Ñ¥é¥á¡¼¥¿"cometdRoot"¤Ç»ØÄꤵ¤ì¤¿Ãͤ¬»ÈÍѤµ¤ì¤ë
 * @param additionalParameter ¤µ¤é¤ËÄɲäǻØÄꤹ¤ë¥ê¥¯¥¨¥¹¥È¥Ñ¥é¥á¡¼¥¿¡£¾Êά²Äǽ
 */
function init(message,root,additionalParameter)

/**
 * »ØÄꤷ¤¿¥Á¥ã¥Í¥ë¤ÎPushÇÛ¿®¥Ç¡¼¥¿¹ØÆÉ¤ò³«»Ï¤¹¤ë
 * @param channel ¹ØÆÉ¤¹¤ë¥Á¥ã¥Í¥ë(¸å½Ò) dojo.event.topic.subscribe()´Ø¿ô¤ÎÂè°ì°ú¿ô¤È¤Ê¤ë
 * @param isGlobal ¥Á¥ã¥Í¥ë¤Ç»ØÄꤷ¤¿¥Á¥ã¥Í¥ëID¤¬¥°¥í¡¼¥Ð¥ë¤«¤É¤¦¤«¡£
 *  true¤ò»ØÄꤷ¤¿¾ì¹ç¡¢¥Á¥ã¥Í¥ëID¤Ï"/cometd" + channel¤È¤¤¤¦Ê¸»úÎó¤Ë¤Ê¤ë¡£
 * @param srcObj funcName¤Ç»ØÄꤵ¤ì¤¿´Ø¿ô¤¬½ê°¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¡£null¤ò»ØÄꤹ¤ë¤Èwindow¥ª¥Ö¥¸¥§¥¯¥È¤È¤Ê¤ë¡£
 * @param funcName ÇÛ¿®¤µ¤ì¤¿¥á¥Ã¥»¡¼¥¸¤ò¼õ¤±¼è¤ë¥Ï¥ó¥É¥é¤È¤Ê¤ë´Ø¿ô¤Î̾¾Î¤òʸ»úÎó¤Ç»ØÄꤹ¤ë¡£
 */
function subscribe(channel,isGlobal,srcObj,funcName)

º£²ó¤Ï¤³¤ÎÆó¤Ä¤Î´Ø¿ô¤ò¾Ò²ð¤¹¤ë¤Ëα¤á¤Æ¤ª¤­¤Þ¤¹¡£

¤Ç¡¢º£²ó¤Î½ÅÍץȥԥ寤Ǥ¢¤ë¥Á¥ã¥Í¥ë¤È¸À¤¦¸ÀÍÕ¤¬½Ð¤Æ¤­¤Þ¤·¤¿¤Í¡£¤³¤ì¤Ë¤Ä¤¤¤Æ¤Ï°Ê²¼¤Ë²òÀ⤷¤Þ¤¹¡£

¥Á¥ã¥Í¥ë¤È¥¯¥é¥¤¥¢¥ó¥È

¥Á¥ã¥Í¥ë¤È¸À¤¦¸ÀÍÕ¤¬¤¹¤Ç¤Ë½Ð¤Æ¤­¤Æ¤¤¤Þ¤¹¤¬¡¢¤³¤ì¤¬ÇÛ¿®ÂоݤȤʤ륯¥é¥¤¥¢¥ó¥È¤Î½¸¹ç¤òɽ¤¹³µÇ°¤Ç¤¹¡£

¥Á¥ã¥Í¥ë¤Ï¥¹¥é¥Ã¥·¥å("/")¤Ç»Ï¤Þ¤ëʸ»úÎó¤Ç¹½À®¤µ¤ì¤ë¤³¤È¤¬¿ä¾©¤µ¤ì¤Æ¤ª¤ê¡¢¤½¤Î̾Á°¤ÏǤ°Õ¤Ë·è¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£(Î㤨¤Ð¡¢cometd-demo¤Ë´Þ¤Þ¤ì¤ë¥Á¥ã¥Ã¥È¥Ç¥â¤Ç¤Ï"/chat/demo"¤È¤¤¤¦Ê¸»úÎ󤬻ÈÍѤµ¤ì¤Æ¤¤¤Þ¤¹)¡£¤Ä¤Þ¤ê¡¢°ì¤Ä¤Î¥Á¥ã¥Í¥ë¤Î²¼¤ËÊ£¿ô¤Î¥¯¥é¥¤¥¢¥ó¥È¤¬É³¤Å¤¤¤Æ¤¤¤ë¥¤¥á¡¼¥¸¡£¤¢¤ó¤Þ¤êÎɤ¤¿Þ¤Ç¤Ï¤Ê¤¤¤Ç¤¹¤¬°Ê²¼¤Î¤è¤¦¤Ê´¶¤¸¡£

Channel(/chat/demo)
    ¢ªClient(clientId=XXXX)
    ¢ªClient(clientId=YYYY)
Channel(/another)
    ¢ªClient(clientId=XXXX)
    ¢ªClient(clientId=ZZZZ)

¥¯¥é¥¤¥¢¥ó¥È¤ÏÊ£¿ô¤Î¥Á¥ã¥Í¥ë¤ËƱ»þ¤Ë½ê°¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹(¾å¤Î³¨¤Ç¤Ï¡¢clientId=XXXX¤Î¥¯¥é¥¤¥¢¥ó¥È)¡£¤Þ¤¿¡¢¥¯¥é¥¤¥¢¥ó¥ÈID¤È¤¤¤¦¥¯¥é¥¤¥¢¥ó¥È¤ò°ì°Õ¤ËÆÃÄꤹ¤ëʸ»úÎ󤬯âÉôŪ¤Ë»ÈÍѤµ¤ì¤Þ¤¹¤¬¡¢¤½¤ì¤ÏÁ´¤ÆCometd¤ÎAPI¤¬±£Ê䷤Ƥ¯¤ì¤Þ¤¹¤Î¤ÇÉáÄ̤ϰռ±¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤»¤ó¡£

¤Ç¤Ï¡¢¤³¤³¤Þ¤Ç¤ÎÃμ±¤Ç½½Ê¬Cometd¤ò°·¤¨¤Þ¤¹¤Î¤Ç¡¢º£²ó¤ÎÄù¤á¤È¤·¤Æ¡¢¥é¥ó¥À¥à¤Ê¿ôÃͤòPushÇÛ¿®¤·¡¢¥Ö¥é¥¦¥¶¾å¤Ç¤½¤ì¤ò¥ê¥¢¥ë¥¿¥¤¥à¤Ëɽ¼¨¤¹¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤òºîÀ®¤·¤Æ¤ß¤Þ¤¹¡£


¤Ç¤Ï¡¢¥é¥ó¥À¥à¤Ê¿ôÃÍ(³ô²Á¤ß¤¿¤¤¤Ê¡£)¤òPushÇÛ¿®¤¹¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤òºîÀ®¤·¤Þ¤¹¡£

CometdServlet¤Î¥»¥Ã¥È¥¢¥Ã¥×¤Ï½ª¤ï¤Ã¤Æ¤¤¤ë¤È¤¤¤¦Á°Äó¤Ç¡¢º£²óºîÀ®¤¹¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÁ´ÂÎÁü¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¹¡£

  • PushÇÛ¿®¥Á¥ã¥Í¥ë¤ÎID¡¦¡¦¡¦/price
  • ¥é¥ó¥À¥à¤Ê²Á³Ê¤òÀ¸À®¤·¤Æ¥Á¥ã¥Í¥ë¤Ë¥Ç¡¼¥¿¤òÇÛ¿®¤¹¤ë¥µ¡¼¥Ö¥ì¥Ã¥È¡¦¡¦¡¦example.PriceServlet
  • ÇÛ¿®¤µ¤ì¤¿²Á³Ê¤òɽ¼¨¤¹¤ëHTML¡¦¡¦¡¦price.html

¤Ä¤Þ¤ê¡¢PriceServlet¤ÏCometdServlet¤è¤ê¤â¸å¤Ëµ¯Æ°¤·¡¢¥é¥ó¥À¥à¤Ê²Á³Ê¤ò·èÄꤷ¤¿¸å¡¢¤½¤ì¤ò¥Á¥ã¥Í¥ë¡Ö/price¡×¤ËÇÛ¿®¤·¤Þ¤¹¡£¤½¤ì¤òɽ¼¨¤¹¤ëprice.html¤ÏÁ°½Ò¤·¤¿Cometd¤ÎJavaScript API¤ò»ÈÍѤ·¤ÆÇÛ¿®¤µ¤ì¤¿²Á³Ê¤ò¼õ¤±¼è¤ê¡¢²èÌ̤òºÆÉÁ²è¤·¤Þ¤¹¡£

¤Ç¤Ï¤Þ¤ºPriceServlet¤Î¥³¡¼¥É¤«¤é¡£

import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.mortbay.cometd.Bayeux;
import org.mortbay.cometd.Channel;
import org.mortbay.cometd.CometdServlet;

public class PricePublisherServlet extends HttpServlet {
    // ¥Á¥ã¥Í¥ëID
    public static String PRICE_CHANNEL_ID = "/price";
    private Channel priceChannel;
    
    @Override
    public void init() throws ServletException {
        super.init();
        // Bayeux¥×¥í¥È¥³¥ë¥ª¥Ö¥¸¥§¥¯¥È¤ò¼èÆÀ¡¦¡¦¡¦­¡
        Bayeux bayeux = (Bayeux)getServletContext().getAttribute(CometdServlet.ORG_MORTBAY_BAYEUX);
        // ¥Á¥ã¥Í¥ë¤ÎÀ¸À®¡¦¡¦¡¦­¢
        priceChannel = bayeux.newChannel(PRICE_CHANNEL_ID);
        
        // ÇÛ¿®¥¹¥ì¥Ã¥É¥¹¥¿¡¼¥È
        Thread pricePublishThread = new Thread(new PricePublisher());
        pricePublishThread.start();
    }
 
    private final class PricePublisher implements Runnable {
        private int currentPrice = 100;
        
        public void run() {
            // ¥é¥ó¥À¥à¤Ç²Á³Ê¤ò·èÄꤷ¡¢¤½¤ì¤ò¥Á¥ã¥Í¥ë¤ËÇÛ¿®(publish)¤¹¤ë
            while (true) {
            	// ³ô²Á¤¬µÞ·ã¤ËÊѲ½¤·¤¹¤®¤Ê¤¤¤è¤¦¾å¸Â¡¢²¼¸Â¤òÀߤ±¤ë
                Random r = new Random();
                int price = r.nextInt((int) (currentPrice * 200));
                int priceMinLimit = (int) (currentPrice * 0.999);
                int priceMaxLimit = (int) (currentPrice * 1.01);
                if (priceMinLimit > price) {
                    price = priceMinLimit;
                } else if (priceMaxLimit < price) {
                    price = priceMaxLimit;
                }
                // ¥Á¥ã¥Í¥ë¤Ø¤Îpublish¡¦¡¦¡¦­£
                priceChannel.publish(new Integer(price), null);
                currentPrice = price;
                try {
                    // 1Éôֿ²¤ë
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

¥³¡¼¥É¼«ÂΤÏÈó¾ï¤ËȽ¤ê¤ä¤¹¤¤¤«¤È»×¤¤¤Þ¤¹¡£

¤¤¤¯¤Ä¤«¥Ý¥¤¥ó¥È¤¬¤¢¤ë¤Î¤Ç¡¢²òÀ⤷¤Þ¤¹¡£

­¡Bayeux¥×¥í¥È¥³¥ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¼èÆÀ

Cometd¤Ï¡¢PushÇÛ¿®¤ò¼Â¸½¤¹¤ë¤¿¤á¤Ë¡¢´Êñ¤Ê¼«Á°¤Î¥×¥í¥È¥³¥ë¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£¤½¤Î¥×¥í¥È¥³¥ë¤òÍѤ¤¤Æ¥Ö¥é¥¦¥¶¤È¥µ¡¼¥Ð´Ö¤Ç¤ä¤ê¼è¤ê¤¹¤ë¤ï¤±¤Ç¤¹¤Í¡£

Bayeux¥×¥í¥È¥³¥ë¤Ï¡¢CometdServlet¤¬½é´ü²½»þ¤ËServletContextÆâ¤ËCometdServlet.ORG_MORTBAY_BAYEUX¤È¤¤¤¦Ê¸»úÎóÄê¿ô¤ò¥­¡¼¤È¤·¤Æ³ÊǼ¤·¤Æ¤¯¤ì¤Þ¤¹¤Î¤Ç¡¢¼èÆÀ¤¹¤ë¾ì¹ç¤ÏServletContext#getAttribute()¤òÍѤ¤¤Þ¤¹¡£

­¢¥Á¥ã¥Í¥ë¤ÎÀ¸À®

­¡¤Ç¼èÆÀ¤·¤¿Bayeux¥×¥í¥È¥³¥ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¥á¥½¥Ã¥ÉnewChannel(String channelId)¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¿·¤·¤¯¥Á¥ã¥Í¥ë¤òÀ¸À®¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£À¸À®¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢¤¹¤Ç¤Ë¸ºß¤¹¤ë¥Á¥ã¥Í¥ë¤ò¼èÆÀ¤¹¤ë¾ì¹ç¤ÏBayeux#getChannel(String channelId)¤È¤¤¤¦¥á¥½¥Ã¥É¤ò»ÈÍѤ·¤Þ¤¹¡£

­£¥Á¥ã¥Í¥ë¤Ø¤Î¥Ç¡¼¥¿ÇÛ¿®

Channel#publish(Object data, Client from)¤ò»ÈÍѤ¹¤ì¤Ð¥Á¥ã¥Í¥ë¤Ø¤Î¥Ç¡¼¥¿ÇÛ¿®¤ò¹Ô¤¦¤³¤È¤¬²Äǽ¤Ç¤¹¡£Èó¾ï¤Ë´Êñ¤Ç¤¹¤Í¡£publish¥á¥½¥Ã¥É¤ÎÂèÆó°ú¿ô¤Ç¤¢¤ëClient from¤Ï¡¢¾ðÊó¶¦Í­·¿¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ç¡¢¥Ç¡¼¥¿¤ÎÇÛ¿®¸µ¤È¤Ê¤Ã¤¿¥¯¥é¥¤¥¢¥ó¥È¤òÅϤ·¤Þ¤¹¡£º£²ó¤Ï¥µ¡¼¥Ð¤«¤é°ìÊýŪ¤Ë¥Ç¡¼¥¿¤òÇÛ¿®¤¹¤ë¤À¤±¤Ç¤¹¤Î¤Ç¡¢null¤ÇOK¤Ç¤¹¡£

ºî¤Ã¤¿²Á³ÊÇÛ¿®¥µ¡¼¥Ö¥ì¥Ã¥È¤ò˺¤ì¤º¤Ëweb.xml¤ÇÅÐÏ¿¡£

<servlet>
    <servlet-name>pricePublisher</servlet-name>
    <servlet-class>pricepanel.PricePublisherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

load-on-startup¤ò»ÈÍѤ·¤Æ¡¢CometdServlet¤è¤ê¤â¸å¤Ë¥µ¡¼¥Ö¥ì¥Ã¥È¤¬µ¯Æ°¤¹¤ë¤è¤¦Ä´À°¤·¤Æ¤ª¤¯¤Î¤ò˺¤ì¤Ê¤¤¤³¤È¡ª

²Á³ÊÇÛ¿®Â¦¤Î¥µ¡¼¥Ö¥ì¥Ã¥È¤Ï´°À®¤·¤Þ¤·¤¿¤Î¤Ç¡¢¤¢¤È¤Ï¤½¤ì¤ò¼õ¤±¤È¤Ã¤Æ²èÌ̤Ëɽ¼¨¤¹¤ëHTML¤òºîÀ®¤¹¤ì¤Ð´°À®¤Ç¤¹¡£

¡¦¡¦¡¦¤ÎÁ°¤Ë¡£Cometd¤¬Ä󶡤¹¤ëJavaScript API¤Ç¤¹¤¬¡¢¸½»þÅÀ¤Ç¤Ï¡¢¥ê¥ê¡¼¥¹¥â¥¸¥å¡¼¥ëËÜÂΤǤϤʤ¯¡¢¥Ç¥â¥¢¥×¥ê(cometd-demo)¤Ë´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£

¤ª¤¤¤ª¤¤¡¦¡¦¡¦¤³¤ì¤Ã¤Æ¤â¤·¤«¤·¤Æ¡¢JavaScript API¤ÏCometd¤¬ÀÕǤ¤â¤Ã¤Æ¥ê¥ê¡¼¥¹¤¹¤ë¤â¤Î¤Ç¤Ï¤Ê¤¤¤Ã¤Æ»ö?

¤Þ¤¢¡¢¤½¤ó¤Ê»ö¤Ï¤Ê¤¤¤Ç¤·¤ç¤¦¤¬¡¦¡¦¡¦¤È¤¤¤¦¤³¤È¤Ç°Ê²¼¤ÎHTML¤ò½ñ¤¯ºÝ¤Ë¤Ï¡¢Subversion¤Ç¥Á¥§¥Ã¥¯¥¢¥¦¥È¤·¤¿¡¢cometd-demo¥â¥¸¥å¡¼¥ëÆâ¤Îsrc/main/webapp/dojo¥Ç¥£¥ì¥¯¥È¥ê¤ò¼«Ê¬¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥óÆâ¤Ë¥³¥Ô¡¼¤·¤Æ»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£

¤Ç¡¢price.html¤Î¥½¡¼¥¹¥³¡¼¥É¤Ï°Ê²¼¡£

<html>
<head>
<!-- cometd-demo¤Ë¤¢¤ë -->
<script type="text/javascript" src="dojo/dojo.js"></script>
<script type="text/javascript">

// ½é´ü²½¡¦¡¦¡¦­¡
cometd.init({}, "/pricepanel/cometd");

var checkCometdInitializedTimer = setInterval(checkCometdInitialized, 200);

// cometd¤Î½é´ü²½¤¬´°Î»¤¹¤ë¤Þ¤ÇÂÔµ¡¤·¤¿¸å¡¢cometd.subscribe¤ò¹Ô¤¦¡¦¡¦¡¦­¢
function checkCometdInitialized() {
	if (!cometd.initialized) {
		return;
	}
	clearInterval(checkCometdInitializedTimer);
	// ¥Á¥ã¥Í¥ë¡Ö/price¡×¤ò¹ØÆÉ¤·¡¢¥Ï¥ó¥É¥é¤Ë"pricePublished"¤ò»ØÄꡦ¡¦¡¦­£
	cometd.subscribe("/price", false, window, "pricePublished");
}

// ²Á³Ê¤¬ÇÛ¿®¤µ¤ì¤¿¤é²èÌ̤ò¹¹¿·¤¹¤ë
function pricePublished(message) {¡¦¡¦¡¦­¤
	var pricePanel = document.getElementById('pricePanel');
	pricePanel.innerHTML = message.data; // div¥¿¥°¤ÎÆâÍÆ¤ò¿·¤·¤¤²Á³Ê¤Ç¹¹¿·
}
</script>
</head>

<body>
<div id="pricePanel" style="width: 130px; height: 60px; font-weight: bold; font-size: 50px;">
</div>
</body>
</html>

°Ê²¼¡¢²òÀâ¡£

­¡cometd.init´Ø¿ô¤Ë¤è¤ëCometd¤Î½é´ü²½

½é´ü²½¤Ïcometd.init´Ø¿ô¤Ç¹Ô¤¤¤Þ¤¹¡£¤³¤³¤Ç¤ÏÂè°ì°ú¿ô¤Ï¶õ¤Î¥ª¥Ö¥¸¥§¥¯¥È¡¢ÂèÆó°ú¿ô¤ËCometdServlet¤Î¥Ñ¥¹¤ò»ØÄꤷ¤Þ¤¹¡£

­¢cometd.init´Ø¿ô¤Î¸Æ¤Ó½Ð¤·¤¬À®¸ù¤¹¤ë¤Þ¤ÇÂÔµ¡

cometd.init¤Î¸Æ¤Ó½Ð¤·¤¬À®¸ù¤·¤Æ¥µ¡¼¥Ð¤«¤é¥ì¥¹¥Ý¥ó¥¹¤¬Ìá¤ë¤Þ¤ÇÂÔµ¡¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥ì¥¹¥Ý¥ó¥¹¤¬Ìá¤Ã¤Æ½é´ü²½¤¬À®¸ù¤¹¤ë¤ÈÊÑ¿ôcometd.initialized¤¬true¤È¤Ê¤ê¤Þ¤¹¡£

­£cometd.subscribe¤Ë¤è¤ëPushÇÛ¿®¹ØÆÉ

cometd.subscribe¤Î¸Æ¤Ó½Ð¤·¤Ç¤¹¡£¥Á¥ã¥Í¥ë¤Ë/price¡¢¥Ï¥ó¥É¥é´Ø¿ô¤ËpricePublished¤ò»ØÄꤷ¤Æ¤¤¤Þ¤¹¡£

­¤¥Ï¥ó¥É¥é´Ø¿ô¤ÎÅÐÏ¿

PushÇÛ¿®¤ò¼õ¤±¼è¤Ã¤¿ºÝ¸Æ¤Ó½Ð¤µ¤ì¤ë¥Ï¥ó¥É¥é´Ø¿ô¤Ç¡¢°ú¿ômessage¤ò¼è¤ê¤Þ¤¹¡£message¤Ï°Ê²¼¤Î¤è¤¦¤Ê¹½Â¤¤ò»ý¤ÄJSON¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¹¡£¤³¤Î¹½Â¤¤ò¸«¤ì¤Ð¡¢ÇÛ¿®¥Ç¡¼¥¿¤Ïmessage.data¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤ë¤³¤È¤¬¤ï¤«¤ë¤Ç¤·¤ç¤¦¡£

ÇÛ¿®¥Ç¡¼¥¿¤Î¹½Â¤
[
	// ¥Ø¥Ã¥ÀÉô
    {
        "connectionId":"¥¯¥é¥¤¥¢¥ó¥È/¥µ¡¼¥Ð´Ö¤ÎÀܳ¤ò¼¨¤¹¥æ¥Ë¡¼¥¯¤ÊID",
        "timestamp":"¥á¥Ã¥»¡¼¥¸ÇÛ¿®»þ¤Î¥¿¥¤¥à¥¹¥¿¥ó¥×",
        "error":¥¨¥é¡¼¤À¤Ã¤¿¤«¤É¤¦¤«(true/false),
        "successful":Àµ¾ï½ªÎ»¤À¤Ã¤¿¤«¤É¤¦¤«(true/false),
        "channel":"Àܳ»þ¤Î¥Á¥ã¥Í¥ë"
    },
    // ¥Ç¡¼¥¿Éô
    {
        "data":¥Á¥ã¥Í¥ë¤ËÇÛ¿®¤µ¤ì¤¿¥Ç¡¼¥¿,
        "timestamp":"¥á¥Ã¥»¡¼¥¸ÇÛ¿®»þ¤Î¥¿¥¤¥à¥¹¥¿¥ó¥×",
        "channel":"ÇÛ¿®¥Ç¡¼¥¿¤Î¥Á¥ã¥Í¥ë",
        "id":"¥á¥Ã¥»¡¼¥¸¤Ë¿¶¤é¤ì¤¿ID"
    }
]

¼ÂºÝ¤Ë¤³¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤òư¤«¤¹¤È¡¢À䤨´Ö¤Ê¤¯¿·¤·¤¤²Á³Ê¤Ç²èÌ̤¬¹¹¿·¤µ¤ì¤Þ¤¹¡£

¥Ö¥é¥¦¥¶¤òÊ£¿ôΩ¤Á¾å¤²¤Æ¥¢¥¯¥»¥¹¤¹¤ë¤ÈÁ´¤Æ¤Î²èÌ̤¬¤Û¤ÜƱ»þ¤Ë¹¹¿·¤µ¤ì¤Þ¤¹¡£¤¤¤ä¡¼¡¢¤Á¤ç¤Ã¤È´¶Æ°¤·¤Þ¤¹¤Í¡£

º£²ó²òÀ⤷¤¿¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò³¨¤Ë¤¹¤ë¤È¢­¤Î¤è¤¦¤Ê´¶¤¸¤Ë¤Ê¤ê¤Þ¤¹¡£¥Á¥ã¥Í¥ë¤ËÇÛ¿®¤·¤¿¥Ç¡¼¥¿¤¬¥¯¥é¥¤¥¢¥ó¥È¤ËÆÏ¤¯¥¤¥á¡¼¥¸¤¬¤Ç¤­¤Þ¤·¤¿¤«¡©

f:id:Syunpei:20061122170323g:image

º£²ó¤Ï¤º¤¤¤Ö¤ó¿¤¯¤Î¤³¤È¤ò³Ø¤Ó¤Þ¤·¤¿¡£

Cometd¤Î¥»¥Ã¥È¥¢¥Ã¥×ÊýË¡¡¢¥Á¥ã¥Í¥ë¡¢JavaScript API¤Ë¤Ä¤¤¤Æ¡£

¼¡²ó¤Ï¡¢¾ðÊóÇÛ¿®·¿¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Îºî¤êÊý¡¢¤¢¤ÈCometd¤Îưºî¸¶Íý¤Ë¤Ä¤¤¤Æ²òÀ⤷¤¿¤¤¤È»×¤¤¤Þ¤¹¡£¤³¤¦¤´´üÂÔ¡£