一步步学WebSocket(1)声明式WebSocket

本节描述声明式WebSocket编程,可以与后一篇编程式WebSocket作对比学习:

首先上服务端:

@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类同)。

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路径。

subprotocols协议用于配websocket的子协议,比如superchat等,这一阶段我们先不理会它。

decoders,encoders用于定义编解码器,后面的文章我们会详细讨论他。

configurator属性,对于声明式编程的Server端点,可以不配值,会采用默认值ServerEndpointConfig.Configurator即可。

(有默认值,一般说明该属性不可或缺,在编程式WebSocketk中时,我们会看到Configurator的更多细节).

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通信息就完成了。

时间: 2024-11-06 12:19:48

一步步学WebSocket(1)声明式WebSocket的相关文章

一步步学WebSocket(2)编程式WebSocket

接上篇,这篇我们采用编程式WebSocket实现上篇的例子: 服务端Endpoint,不再使用ServerEndpoint注解: public class ProgramerServer extends Endpoint {     @Override     public void onOpen(Session session, EndpointConfig edc) {         System.out.println("Somebody is coming!");      

SpringCloud系列十:使用Feign实现声明式REST调用

1. 回顾 前文的示例中是使用RestTemplate实现REST API调用的,代码大致如下: @GetMapping("/user/{id}") public User findById(@PathVariable Long id) { return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class); } 由代码克制,我们是使用拼接字符串的方

Spring(四)-- JdbcTemplate、声明式事务

1.Spring提供的一个操作数据库的技术JdbcTemplate,是对Jdbc的封装.语法风格非常接近DBUtils. JdbcTemplate可以直接操作数据库,加快效率,而且学这个JdbcTemplate也是为声明式事务做准备,毕竟要对数据库中的数据进行操纵! JdbcTemplate中并没有提供一级缓存,以及类与类之间的关联关系!就像是spring提供的一个DBUtils. Spring对数据库的操作使用JdbcTemplate来封装JDBC,结合Spring的注入特性可以很方便的实现对

spring声明式事务管理

Spring 的声明式事务管理在底层是建立在 AOP 的基础之上的.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务. 声明式事务管理分为两种:1.配置文件   2.注解 1.配置文件(声明式事务管理)用法: 在applicationContext.xml配置文件中配置①事务管理器(事务管理者).②事务参数(事务通知).③AOP配置 如下: applicationContext.xml配置文件代码 1 <!-- 事务管理器(

【Spring】Spring使用XML配置声明式事务

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.事务介绍 事务简介: 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性 事务就是一系列的动作,它们被当作一个单独的工作单元.这些动作要么全部完成,要么全部不起作用. 事务的四个关键属性(ACID) ① 原子性(atomicity):事务室一个原子操作,有一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用② 一致性(consistency):一旦所

通过 React Hooks 声明式地使用 setInterval

本文由云+社区发表 作者:Dan Abramov 接触 React Hooks 一定时间的你,也许会碰到一个神奇的问题: setInterval 用起来没你想的简单. Ryan Florence 在他的推文里面说到: 不少朋友跟我提起,setInterval 和 hooks 一起用的时候,有种蛋蛋的忧伤. 老实说,这些朋友也不是胡扯.刚开始接触 Hooks 的时候,确实还挺让人疑惑的. 但我认为谈不上 Hooks 的毛病,而是 React 编程模型和 setInterval 之间的一种模式差异.

spring事物管理--声明式(AspectJ)(推荐使用)

1.表结构及数据 2.需引入的jar包: 3.业务层(Service).持久层(Dao)接口与实现类 Service接口: //转账案例业务层接口 public interface AccountService { /** * @param out :转出账号 * @param in :转入账号 * @param money :转账金额 */ public void transfer(String out,String in,Double money); } Service实现类: //转账案例

注解方式实现声明式事务管理

使用注解实现Spring的声明式事务管理,更加简单! 步骤: 1) 必须引入Aop相关的jar文件 2) bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类 3)在需要添加事务控制的地方,写上: @Transactional @Transactional注解: 1)应用事务的注解 2)定义到方法上: 当前方法应用spring的声明式事务 3)定义到类上:   当前类的所有的方法都应用Spring声明式事务管理; 4)定义到父类上: 当执行父类的方法时候应用事务. 修改bean

spring4声明式事务--01注解方式

1.在spring配置文件中引入 tx 命名空间 xmlns:tx="http://www.springframework.org/schema/tx" 2.配置事务管理器 <!-- 配置事物管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <p