谈谈websocket在Java项目中的应用

        最近,笔者在给公司的产品做一个在线用户聊天的功能,用到了websocket技术,这里做一下归纳和总结。

        在HTTP 协议中,所有的请求都是由客户端发起的,由服务端进行响应,服务端无法向客户 端推送消息,但是在一些需要即时通信的应用中,又不可避免地需要服务端向客户端推送消息,传 统的解决方案主要有如下几种。

        1、轮询:简单,弊端就是会服务器会处理大量的无效请求;

        2、长轮询:轮询的升级版,不同于传统轮询,在长轮询中,服务端不是每次都会立即响应客户端的请求,只 有在服务端有最新数据的时候才会立即响应客户端的请求,否则服务端会持有这个请求而不返回, 到有新数据时才返回 这种方式可以在 定程度上节省网络资源和服务器资源,但是也存在 问题,例如: • 如果浏览器在服务器响应之前有新数据要发送,就只能创建一个新的并发请求,或者先尝试 断掉当前请求,再创建新的请求。 • TCP HπP 规范中都有连接超时一说,所以所谓的长轮询并不能一直持续,服务端和客户 端的连接需要定期的连接和关闭再连接,这又增大了程序员的工作量,当然也有一些技术能 够延长每次连接的时间,但毕竟是非主流解决方案。

        3、Applet 和 Flash

        Applet Flash 都己经是明日黄花,不过在这两个技术存在的岁月里,除了可以让我们的 HTML 页面更加绚丽之外,还可以解决消息推送问题。开发者可以使用 pplet Flash 来模拟全双工通信, 通过创建 个只有 个像素点大小的透明的 pplet lash ,然后将之内嵌在网页中,再从 Applet 或者 Flash 的代码中创建 Socket 连接进行双向通信 这种连接方式消除了 HTTP 协议中的诸 限制,当服务器有消息发送到客户端的时候,开发者可以在 Applet 或者 Flash 中调用 JavaScript 数将数据显示在页面上,当浏览器有数据要发送给服务器时也 样,通过 Applet 或者 Flash 来传递 这种方式 正地实现了全双工通信,不过也有问题,说明如下: • 浏览器必须能够运行 Java 或者 Flash • 无论是 Applet 还是 Flash 都存在安全问题 • 随着 HTML 标准被各浏览器厂商广泛支持, Flash 下架已经被提上日程( Adobe 宣布 2020 年正式停止支持 Flash 其实,传统的解决方案不止这 种,但是无论哪种解决方案都有自身的缺陷,于是有了 WebSocket。

        WebSocket 种在单个 TCP 连接上进行全双工通信的协议,已被 W3C 定为标准。使用 WebSocket 可以使得客户端和服务器之间的数据交换变得更加简单,它允许服务端主动向客户端推 送数据 WebSocket 协议中,浏览器和服务器只需要完成一次握手,两者之间就可以直接创建 持久性的连接,并进行双向数据传输。

        WebSocket 使用了 HTTP 1.1 的协议升级特性, 一个WebSocket 请求首先使用非正常的 HTTP 请求以特定的模式访问 URL ,这个 URL 有两种模式,分别是 ws和wss ,对应 TTP 协议中 HTTP和HTTPS ,在请求头中有 Connection:Upgrade 字段,表示客户端想要对协议进行升级,另外还有一个 Upgrade:websocket 字段,表示客户端想要将请求协议升级为 WebSocket 协议。 这两个字段共同告诉服务器要将连接升级为 WebSocket 这样全双工协议,如果服务端同意协 议升级,那么在握手完成之后,文本消息或者其他 进制消息就可以同时在两个方向上进行发送, 而不需要关闭和重建连接。 此时的客户端和服务端关系是对等的,它们可以互相 向对方主动发送消 息。

        和传统的解决方案相比, WebSocket 主要有如下特点

        • WebSocket 使用时需要先创建连接,这使得 WebSocket 成为一种有状态的协议 在之后的 信过程中可以省略部分状态信息(例如身份认证等)

        • WebSocket 连接在端口 80 ( WS )或者 443 ( wss )上创建,与 HTTP 使用的端口相同,这样, 基本上所有的防火墙都不会阻 WebSocket

        • WebSocket 使用 HTTP 协议进行握手 因此它可以自 然地集成到网络浏览器和 HTTP 务器中,而不需要额外的成本

        • 心跳消息( ping pong )将被反复的发送,进而保持 WebSocket 连接一直处于活跃状态 • 使用该协议,当消息启动或者到达的时 克服务端和客户端都可以知道

        • WebSocket 连接关闭时将发送一个特殊的关闭消息

        • WebSocket 支持跨域,可以避免ajax的限制

        • http规范要求浏览器将并发连接数限制为每个主机名两个连接,但是当我们使用 WebSocket 的时候,当握手完成之后,该限制就不存在了,因为此时的连接已经不再是 HTTP 连接了

        • WebSocket 协议支持扩展,用户可以扩展协议,实现部分自定义的子协议

        • 更好的二进制支持以及更好的压缩效果。

        WebSocket 然具有这么多优势,使用场景当然 是非常广泛的 ,例如:

        • 在线股票网站

        • 即时聊天

        • 人在线游戏

        • 应用集群通信

        • 系统性能实时监控。

        与SpringBoot集成则需要

package net.cmcc.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import net.luculent.liems.LiemsApplication;

/**
 * <p>Title: WebSocket配置注册</p>
 * <p>Description: 框架支持websocket的必要配置,不配置,客户端连接404</p>
 * <p>Copyright: Copyright (c) 2019</p>
 */
@Configuration
public class WebSocketConfig {

    /**
     * serverEndpointExporter
     * @return ServerEndpointExporter
     */
    @Bean
    @Conditional(LiemsApplication.class)
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
@Component 
@ServerEndpoint("/websocket/st/{userid}") 
public class WebSocket { 

    @OnOpen 
    public void onOpen(@PathParam("userid") String userId, Session session) {}      
                   
    @OnMessage 
    public void onMessage(String message, Session session) {} 

    @OnClose 
    public void onClose(Session session, @PathParam("userid") String userId) {} 

    @OnError 
    public void onError(Session session, Throwable e) {} 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值