一步步學WebSocket(1)聲明式WebSocket

本節描述聲明式WebSocket編程,能夠與後一篇編程式WebSocket做對比學習:javascript

首先上服務端:java

@ServerEndpoint("/chat")
public class DeclarativeServer {
    @OnOpen  
    public void onOpen(Session session) {  
        System.out.println("Somebody is coming!");
     }  
  
    @OnClose  
    public void onClose() {  
    }  
  
    @OnMessage  
    public void onMessage(String message, Session session) throws IOException {
      System.out.println(message); 
      session.getBasicRemote().sendText("it is sickening");
    }  
  

    @OnError  
    public void onError(Session session, Throwable error) {  
        error.printStackTrace();  
    }  
}

經過ServerEndpoint註解將一個POJO聲明爲WebSocket Server端點(Endpoint和web service的概念endpoint類同)。web

ServerEndpoint註解聲明以下:編程

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ServerEndpoint {

    /**
     * URI or URI-template that the annotated class should be mapped to.
     * @return The URI or URI-template that the annotated class should be mapped
     *         to.
     */
    String value();

    String[] subprotocols() default {};

    Class<? extends Decoder>[] decoders() default {};

    Class<? extends Encoder>[] encoders() default {};

    public Class<? extends ServerEndpointConfig.Configurator> configurator()
            default ServerEndpointConfig.Configurator.class;
}

通常狀況下,咱們只須要用爲ServerEndpoint註解配置value屬性,表示該端點映射的URL路徑。websocket

subprotocols協議用於配websocket的子協議,好比superchat等,這一階段咱們先不理會它。session

decoders,encoders用於定義編×××,後面的文章咱們會詳細討論他。app

configurator屬性,對於聲明式編程的Server端點,能夠不配值,會採用默認值ServerEndpointConfig.Configurator便可。socket

(有默認值,通常說明該屬性不可或缺,在編程式WebSocketk中時,咱們會看到Configurator的更多細節).ide


DeclarativeServer實現四個方法,分別帶有註解 @OnOpen,@OnClose,@OnMessage , @OnError標示。函數

@OnOpen代表當有客戶端鏈接到該端點,則回調@OnOpen標記的方法。

@OnClose當客戶端斷開鏈接時,即服務端收到鏈接斷開指定,則回調@OnClose的方法。

@OnMessage當服務端接收到清息時,則回調該方法。

@OnError當服務端發現異常狀況時,好比協議錯誤,則回調該方法。Error不表明鏈接須要關閉,不少錯誤是可恢復的。


將該類打入war包,部署到Tomcat上,一個WebSocket服務端就OK了。


本次咱們不用javascript做爲Client端點,而是採用胖客戶端模式訪問,即Java Application。

首先定義Client端點:

@ClientEndpoint
public class DeclarativeClient {
    @OnOpen  
    public void onOpen(Session session) {  
       System.out.println("I was accpeted by her!");
    }  
  
    @OnClose  
    public void onClose() {  
    }  
  
    @OnMessage  
    public void onMessage(String message, Session session) { 
        System.out.println("she say: " + message); 
    }  
  

    @OnError  
    public void onError(Session session, Throwable error) {  
        error.printStackTrace();  
    }  
}

經過ClientEndpoint註解表示這是一個WebSocket的Client端點。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ClientEndpoint {
    String[] subprotocols() default {};
    Class<? extends Decoder>[] decoders() default {};
    Class<? extends Encoder>[] encoders() default {};
    public Class<? extends Configurator> configurator()
            default Configurator.class;
}

與上面的ServerEndpoint只差一個value屬性,不用講你們也知道爲何了。

各個方法註解與Server同樣,再也不重述。主函數:

public class Client {
    public static void main(String[] args) throws DeploymentException, IOException, InterruptedException {
         WebSocketContainer ws = ContainerProvider.getWebSocketContainer();
         String url = "ws://localhost:8080/ChatWeb/chat";
         Session session =  ws.connectToServer(DeclarativeClient.class, URI.create(url)); 
         session.getBasicRemote().sendText("Hello,chick!");
         Thread.currentThread().sleep(10000);
    }
}

運行Client以前,須要將Tomcat相關包導入,這裏你能夠所有導入,再也不細說,有興趣可自已研究。


ContainerProvider使有ServiceLoader機制加載ContainerProvider的實現類。並提供WebSocketContainer實例,

在Tomcat上,這個實例爲WSWebSocketContainer類。

經過session.getBasicRemote()方法獲取RemoteEndpoint.Basic實例來發送消息。

一個簡單的WebSocket通訊息就完成了。

相關文章
相關標籤/搜索