7 Using Encoders and Decoders

本文详细介绍了Java Websocket中消息的编码与解码机制,包括如何实现自定义编码器和解码器,将Java对象转换为可传输的Websocket消息,以及如何在服务器端解码接收到的消息,将消息还原为Java对象。同时,提供了实例代码演示整个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




            官网英文参考:
                     http://docs.oracle.com/javaee/7/tutorial/doc/websocket007.htm                    


            中文解析:
            
                    Websocket的Java API提供提供转码和反转码的功能实现 Websocket Message和 Java类型相互转化。转码是指 利用Java对象转化为一个可以传输的Websocket Message(其格式有json,xml,二进制)。反转码实现相反的功能,即读消息,转化为Java对象。
                    这个机制使得编写Websocket应用更加容易,因为他将业务逻辑从序列化和反序列化中分离出来。
                    

                    7.1 Implementing Encoders to Convert Java Objects into WebSocket Messages

                        endpoint端点实现和使用编码过程如下:                            
                        1. 实现下面任意一个接口:
  • Encoder.Text<T> for text messages

  • Encoder.Binary<T> for binary messages

                            这些接口指定了转码方法,可以为你想发送的每一个Java类型定义一个转码类。
                        2. 将你实现的转码类添加到注解的ServerEndpoint 中作为encoders一个可选参数。
                        3. 用RemoteEndpoint.Basic 或者是RemoteEndpoint.Async接口的sendObject(Object data)方法发送转码的消息。容器将会去寻找你所传Java类型一致的转码类,并将其转码为Websocket Message。
    
                        下面是一个例子:假如有MessageA和MessageB两个Java 类,你想将其转化为文本消息,如下所示实现Encoder.Text<MessageA>和Encoder.text<MessageB>两个接口:
public class MessageATextEncoder implements Encoder.Text<MessageA> {
   @Override
   public void init(EndpointConfig ec) { }
   @Override
   public void destroy() { }
   @Override
   public String encode(MessageA msgA) throws EncodeException {
      // Access msgA's properties and convert to JSON text...
      return msgAJsonString;
   }
}
实现MessageB同上。
                        然后就是将其添加到ServerEndPoint 的encoders 参数中:
@ServerEndpoint(
   value = "/myendpoint",
   encoders = { MessageATextEncoder.class, MessageBTextEncoder.class }
)
public class EncEndpoint { ... }
                       现在你可以如下图所示,利用sendObject方法发送MessageA和MessageB两个Java对象了。
MessageA msgA = new MessageA(...);
MessageB msgB = new MessageB(...);
session.getBasicRemote.sendObject(msgA);
session.getBasicRemote.sendObject(msgB);
                       如上面提到的例子,你可以实现多个转码为文本,或者是转码为二进制的类。像endpoint一样,转码对象也只会有且关联一个Websocket连接,任何时刻也只会有一个线程在执行转码代码。                     

                   7.2 Implementing Decoders to Convert WebSocket Messages into Java Objects

                    server端点解码的过程如下:
                        1.实现下面任意一个接口
  • Decoder.Text<T> for text messages

  • Decoder.Binary<T> for binary messages

                        这些接口指定了两个 decode和willDecode方法。

Note:

Unlike with encoders, you can specify at most one decoder for binary messages and one decoder for text messages.

 注意不像是编码(转码),你最多实现一个二进制消息解码类和最多一个文本消息解码类                         
                        2. 将解码类的名字添加到ServerEndPoint类中作为decoders的一个可选参数。
                        3. 在endpoint中注解OnMessage方法,从而指定一个方法将Java类型作为一个参数。但server端点收到一个消息,就会利用你指定的其中一个解码类解码,而容器就会调用注解OnMessage 并且有Java类型作为参数的方法 。

                        下面是一个例子,你有两种Java类( MessageA  and  MessageB),你想通过文本消息的格式发送和接收。首先你需要定义个父类Message,让 MessageA  and  MessageB继承,因为你只能定义一个解码文本消息的解码类。实现如下所示:
public class MessageTextDecoder implements Decoder.Text<Message> {
   @Override
   public void init(EndpointConfig ec) { }
   @Override
   public void destroy() { }
   @Override
   public Message decode(String string) throws DecodeException {
      // Read message...
      if ( /* message is an A message */ )
         return new MessageA(...);
      else if ( /* message is a B message */ )
         return new MessageB(...);
   }
   @Override
   public boolean willDecode(String string) {
      // Determine if the message can be converted into either a
      // MessageA object or a MessageB object...
      return canDecode;
   }
}
                        然后就是其添加到ServerEndPoint 对应的decoders 参数中。如下所示:
@ServerEndpoint(
   value = "/myendpoint",
   encoders = { MessageATextEncoder.class, MessageBTextEncoder.class },
   decoders = { MessageTextDecoder.class }
)
public class EncDecEndpoint { ... }
                        现在去endpoint类中定义一个方法,用来接收 MessageA  and  MessageB消息
@OnMessage
public void message(Session session, Message msg) {
   if (msg instanceof MessageA) {
      // We received a MessageA object...
   } else if (msg instanceof MessageB) {
      // We received a MessageB object...
   }
}
                    像endpoint一样,解码对象也有且只会关联一个Websocket 连接,所以任何时候,都已有一个线程在执行解码代码。



### 腾讯iOA私有化部署成本分析 腾讯iOA作为国内领先的零信任安全解决方案之一,支持SaaS、私有化及混合部署模式。在企业对数据安全性要求较高的场景下,私有化部署成为首选方案。以下从硬件投入、软件授权、运维服务等方面进行综合成本分析。 #### 硬件投入成本 私有化部署需要本地服务器资源来承载控制中心、网关和终端管理模块。根据典型中型企业需求,建议采用双节点高可用架构,每台服务器配置不低于8核CPU、32GB内存、1TB SSD存储空间,以保障策略计算、身份认证与访问控制的稳定运行[^2]。若采用物理服务器采购方式,两台设备成本约在10~15万元区间;若已有虚拟化平台,则可通过分配资源池降低硬件支[^1]。 #### 软件授权与服务费用 腾讯iOA私有化版本按用户数或终端数量进行授权计费,具体价格因功能模块组合而异。基础版包含零信任SDP(软件定义边界)与CWPP(云工作负载保护平台)能力,适用于远程办公与应用访问控制场景,年费约为每位用户300元起[^2]。对于500人规模的企业,年度授权成本约15万元。此外,首次部署需支付一次性实施服务费,涵盖系统集成、策略配置与接口对接等,通常为5~8万元[^3]。 #### 运维与扩展成本 私有化部署后需配备专业IT团队负责日常维护、日志审计与策略优化。若企业内部缺乏相应技术储备,可选择厂商提供的年度运维服务包,费用约为软件授权金额的20%~30%。随着业务增长,新增用户或功能模块扩展将产生额外成本,例如增加DLP(数据防泄漏)模块后,整体预算需上浮10%~15%。 #### 总体预算估算 综合上述因素,一个中型企业在完成腾讯iOA私有化部署后的首年总成本包括: - 硬件投入:10~15万元 - 软件授权:15万元(500用户规模) - 实施服务费:5~8万元 - 年度运维服务费:3~5万元 总计约33~41万元,略超30万元预算上限。若希望压缩至30万元以内,可通过精简功能模块(如仅启用SDP与基础身份认证)、复用现有服务器资源或延长付款周期等方式实现初步部署[^3]。 ```python # 成本估算示例代码 def estimate_cost(users=500, license_per_user=300, setup_fee=60000, maintenance_rate=0.25): hardware_cost = 120000 # 假设复用部分资源,取中间值 license_cost = users * license_per_user total_initial_cost = hardware_cost + license_cost + setup_fee annual_maintenance = (license_cost + setup_fee) * maintenance_rate total_first_year = total_initial_cost + annual_maintenance return { "Initial Hardware Cost": hardware_cost, "License Cost": license_cost, "Setup Service Fee": setup_fee, "Annual Maintenance": annual_maintenance, "Total First Year": total_first_year } estimate_cost() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值