现在的位置: 首页 > 综合 > 正文

11 The dukeetf2 Example Application

2019年09月24日 ⁄ 综合 ⁄ 共 4453字 ⁄ 字号 评论关闭
                参考来源:    英文官网原址

            中文解析:

                    dukeetf2 例子
                    dukeetf2 的例子在tut-install/examples/web/websocket/dukeetf2/ 目录下,这个例子将告诉你用Websocket
endpoint 去向连接客户端更新数据。这个例子模拟周期更新交易价格和电子交易基金交易量

                    11.1 Architecture of the dukeetf2 Sample Application

                             dukeetf2 例子包含一个Websocket endpoint,一个ben ,一个HTML页面。
                            endpoint接收客户端的连接,如果有新的价格数据或者交易量,就会更新到客户端。
                            bean 每秒更新一次价格和数据。
                            HTML页面用javascript代码连接Websocket,解析收到的消息,而且通过不重新加载页面的方式更新价格和交易量。
                        11.1.1 The
Endpoint
                                  Websocket endpoint 在ETFEndpoint 类中实现,这个类也存储了所有连接Session(存取在一个队列中),同事还提供一个方法,在新的消息被发送之后就会调用
(The WebSocket endpoint is implemented in the ETFEndpoint class, which stores all connected sessions in a queue and provides a method that the enterprise bean calls when there is new information
available to send:)
@ServerEndpoint("/dukeetf")
public class ETFEndpoint {
   private static final Logger logger = Logger.getLogger("ETFEndpoint");
   /* Queue for all open WebSocket sessions */
   static Queue<Session> queue = new ConcurrentLinkedQueue<>();

   /* PriceVolumeBean calls this method to send updates */
   public static void send(double price, int volume) {
      String msg = String.format("%.2f, %d", price, volume);
      try {
         /* Send updates to all open WebSocket sessions */
         for (Session session : queue) {
            session.getBasicRemote().sendText(msg);
            logger.log(Level.INFO, "Sent: {0}", msg);
         }
      } catch (IOException e) {
         logger.log(Level.INFO, e.toString());
      }
    }
    ...
}
在endpoint 控制生命周期的方法中 从队列中添加和移除队列。
@ServerEndpoint("/dukeetf")
public class ETFEndpoint {
   ...
   @OnOpen
   public void openConnection(Session session) {
      /* Register this connection in the queue */
      queue.add(session);
      logger.log(Level.INFO, "Connection opened.");
   }

   @OnClose
   public void closedConnection(Session session) {
      /* Remove this connection from the queue */
      queue.remove(session);
      logger.log(Level.INFO, "Connection closed.");
   }

   @OnError
   public void error(Session session, Throwable t) {
      /* Remove this connection from the queue */
      queue.remove(session);
      logger.log(Level.INFO, t.toString());
      logger.log(Level.INFO, "Connection error.");
   }
}

                        11.1.2 The
Enterprise Bean

                                bean 使用了一个timer 控制器每秒都产生新的价格和交易数据
@Startup
@Singleton
public class PriceVolumeBean {
   /* Use the container's timer service */
   @Resource TimerService tservice;
   private Random random;
   private volatile double price = 100.0;
   private volatile int volume = 300000;
   private static final Logger logger = Logger.getLogger("PriceVolumeBean");
   
   @PostConstruct
   public void init() {
       /* Initialize the EJB and create a timer */
       logger.log(Level.INFO, "Initializing EJB.");
       random = new Random();
       tservice.createIntervalTimer(1000, 1000, new TimerConfig());
   }
   
   @Timeout
   public void timeout() {
       /* Adjust price and volume and send updates */
       price += 1.0*(random.nextInt(100)-50)/100.0;
       volume += random.nextInt(5000) - 2500;
       ETFEndpoint.send(price, volume);
   }
}
bean 的timeout方法将会调用endpoint 的send方法,更多信息可以查看:
See Using
the Timer Service
 in Chapter
34, "Running the Enterprise Bean Examples"
 for more information on the timer service.

                        11.1.3 The
HTML Page
                                HTML页面由一个table和一些javascript代码组成,table中有连个熟悉,将在javascript代码中用到。
<!DOCTYPE html>
<html>
<head>...</head>
<body>
  ...
  <table>
    ...
    <td id="price">--.--</td>
    ...
    <td id="volume">--</td>
    ...
  </table>
</body>
</html>
                            javascript代码用到Websocket API 连接endpoint server。然后为返回消息指定一个回调函数。回调函数将负责更新数据到页面。
var wsocket;
function connect() {
   wsocket = new WebSocket("ws://localhost:8080/dukeetf2/dukeetf");
   wsocket.onmessage = onMessage;
}
function onMessage(evt) {
   var arraypv = evt.data.split(",");
   document.getElementById("price").innerHTML = arraypv[0];
   document.getElementById("volume").innerHTML = arraypv[1];
}
window.addEventListener("load", connect, false);
                            Websocket API已经被很多浏览器支持了,也广泛的用在HTML5中应用中。

                        11.2 Running the dukeetf2 Example Application

                            下面这个章节将会描述如何运行dukeetf2 应用(使用NetBeans 开发工具,或者是命令行启动)

                        11.2.1 To
Run the dukeetf2 Example Application Using NetBeans IDE
                                1. 确认 GlassFish已经启动了(see Starting
and Stopping GlassFish Server
                                2. 选择File -> Open Project
                                3. 地位到tut-install/examples/web/websocket 
                                4. 选择dukeetf2 目录
                                5. 点击 Open Project 按钮
                                6. 在项目 dukeetf2 右键 选择RUN
                                    这个命令将会build 然后将应用打包为War,可以再target/ 目录下找到,部署到服务器中,打开浏览器,输入URL:http://localhost:8080/dukeetf2/
                                    打开一个不同的浏览器,输入统一的URL,开是不是同时在更新价格和数据?


                        11.2.2 To
Run the dukeetf2 Example Application Using Maven
                                1. 确认 GlassFish已经启动了(see Starting
and Stopping GlassFish Server
                                2. cmd 地位到 tut-install/examples/web/websocket/dukeetf2/
                                3. 输入如下命令: mvn install (前提要下载maven,配置环境变量)
                                4. 打开浏览器输入:http://localhost:8080/dukeetf2/
                                    打开一个不同的浏览器,输入统一的URL,开是不是同时在更新价格和数据?

抱歉!评论已关闭.