在本文中,让我们探索谈论较少的Web Socket Client API,以及如何在Java EE 7容器本身中利用它。
Web套接字服务器API规则
JSR 356的服务器端API(Java的Web套接字API)最常用于构建Web套接字端点实现。 从客户端的角度来看,基于JavaScriptHTML5(浏览器)客户端经常利用标准JavaScript Web套接字API,这些客户端将自己附加到Web套接字服务器端点,并享受双向和全双工通信。 您将看到常见的示例,例如实时地图,股票行情自动收录器,游戏,屏幕共享等应用程序-所有这些用例都是Web套接字的完美选择,而Java EE 7是构建可扩展Web套接字驱动的后端的理想平台。
Web Socket客户端API呢?
Web套接字规范还包括客户端API,并且它对于所有JSR 356(例如Tyrus , Undertow等)实现都必须提供的API。 在相当多的用例中, 可能不需要面向浏览器/面向Web套接字客户端的最终用户。
例
考虑一种情况,您想连接到第三方Web Socket端点,使用其信息并将其保留以备后用? 也许有待进一步分析? 在这种情况下,利用Java EE容器本身内的客户端API很有用。
让我们通过一个简单的示例对此进行探讨。
(带注释)Web Socket Client
注意: @OnMessage的逻辑是有意排除的,并且已以不同的方式实现(稍后说明)
package blog.abhirockzz.wordpress.com;import javax.websocket.ClientEndpoint;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.Session;@ClientEndpoint
public class StockTickerClient {@OnClosepublic void closed(Session session) {System.out.println("Session " + session + " closed");}@OnErrorpublic void error(Throwable error) {System.out.println("Error: " + error.getMessage());}}
股票代码(信息)JPA实体
package blog.abhirockzz.wordpress.com;import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;@Entity
@Table(name = "STOCK_TICK")
public class StockTick implements Serializable {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;private String name;private String price;public StockTick(String name, String price) {this.name = name;this.price = price;}public StockTick() {//for JPA}//getters and setters omitted ...
}
无状态豆
- 处理股票行情信息的持久性
- 针对Java EE 7容器提供的默认JDBC数据源执行其操作( 约定优于配置 !)
package blog.abhirockzz.wordpress.com;import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;@Stateless
public class StockInfoPersistenceService {@PersistenceContextEntityManager em;public void save(String name, String price){em.persist(new StockTick(name, price));}
}
单例EJB
- 利用Web Socket ContainerProvider API
- 启动与Web套接字服务器的连接
- 注入StockInfoPersistenceService bean并在addMessageHandler实现中使用它
如前所述,这里包含了(持久性)逻辑,该逻辑可以嵌入在StockTickerClient类的@OnMessage注释方法中。 这是因为StockInfoPersistenceService (无状态)bean的注入失败,并且实例本身被解析为null。
package blog.abhirockzz.wordpress.com;import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;@Singleton
@Startup
public class StockServiceBootstrapBean {private final String WS_SERVER_URL = "ws://api.stocks/ticker"; //fictitiousprivate Session session = null;@InjectStockInfoPersistenceService tickRepo;@PostConstructpublic void bootstrap() {WebSocketContainer webSocketContainer = null;try {webSocketContainer = ContainerProvider.getWebSocketContainer();session = webSocketContainer.connectToServer(StockTickerClient.class, new URI(WS_SERVER_URL));System.out.println("Connected to WS endpoint " + WS_SERVER_URL);session.addMessageHandler(new MessageHandler.Whole<String>() {@Overridepublic void onMessage(String msg) {tickRepo.save(msg.split(":")[0], msg.split(":")[1]);}});} catch (DeploymentException | IOException | URISyntaxException ex) {Logger.getLogger(StockServiceBootstrapBean.class.getName()).log(Level.SEVERE, null, ex);}}@PreDestroypublic void destroy() {close();}private void close() {try {session.close();System.out.println("CLOSED Connection to WS endpoint " + WS_SERVER_URL);} catch (IOException ex) {Logger.getLogger(StockServiceBootstrapBean.class.getName()).log(Level.SEVERE, null, ex);}}
}
就是这样。 尽管这是一个相对简单的示例,但很难想象可以在Web套接字服务器终结点接收的信息上应用各种复杂的业务逻辑。 您可能还想考虑使用session.getAsyncRemote#sendAsync方法以异步方式向连接的客户端发送消息。
干杯!
翻译自: https://www.javacodegeeks.com/2015/07/websocket-client-api-in-java-ee-7.html