Java WebSocket实现(一)——基础知识

一、概述

        之前在工作中,遇到了一种情况:服务端数据变更后,需要实时推送到前端页面,页面的内容更新。最开始考虑使用轮询,但消耗很大,最后还是找到了一种后端向前端主动推送数据的方法。其实,WebSocket允许服务端主动向客户端推送数据,就可以用它来实现,但考虑到项目当时只有一个地方用到,且要求简单,所以便找了较为轻便的解决方案。 有不少网站为了实现数据推送,采用了轮询。

        目前论询采用的技术有Comet、dwr等。HTML定义了WebSocket协议,能更好的节省服务器资源和带宽,且能更实时的进行通讯。

 

二、基础概念

单工(Simplex Communication)

        指数据的传输是单向的。具体来讲,在通信双方中,一方固定为发送端,另一方为固定接收端,单工则是通讯时信息只能沿一个方向传输。比如从武汉到北京的高速公路,右边的车道只允许一个方向的车流行驶,从北京到武汉的车,必须走对面的车道。

半双工(Half Duplex)

        是数据传输时,数据可以在一个信号载体上进行两个方向的传输,但不能同时进行。还是说从武汉到北京的高速公路,从武汉到北京需走右边的车道,若交通规则改成靠左行驶,那从北京到武汉走的也是原来的车道,但这个车道不能让从武汉到北京的车与从北京到武汉的车同时走,这时就堵住了,谁也动不了。

全双工(Full Duplex)

        是指通信时允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合;可以同时(瞬时)进行信号的双向传输(A——>B且B——>A)。

轮询

       轮询是在特定的时间间隔(比如2秒)内,客户端向服务器发送请求,然后服务器端返回最新数据给客户端。其缺点是客户端需要不断的向服务器发送请求,请求中包含的真正有效的数据可能只有很小的一部分(比如请求头部可能会较长),浪费带宽;若间隔时间稍长则会有延时,若太短则请求会非常的频繁。

长连接

       指数据通讯的双方在较长的时间内保持连接不断开,然后在这个连接上可以连续发送多个数据包,在连接保持期间,若没有数据包发送,需要双方发链路检测包。由于当连接建立后,不会在很短时间内断开,下次处理时直接发送数据就可以了,不用再去建立新的连接,所以它稳定安全。但由于长时间保持连接,也会损耗很多资源。长连接多用于操作频繁、点对点的通讯。

短连接(short connnection)

        短连接是相对于长连接来讲的,是指在数据通讯过程中,只在需要发送数据时,才去建立一个连接,数据发送完成后,就断开连接,即每次连接只完成一项业务的发送。优点是不需要长期占用通道,在业务频率不高的场景下,能节省通道的使用。缺点是需要在每次发送业务时,都建立一个连接,这样以来连接建立的开销大。

 

三、WebSocket

3.1 WebSocket介绍        

        WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。它使客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

        在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以直接创建持久性的连接,并进行双向数据传输。为了创建WebSocket连接,需要通过客户端(如浏览器)发出请求,然后服务器进行回应,这个过程称为“握手”(handshaking)。WebSocket是独立的、创建在TCP协议上的,通过HTTP/1.1协议的101状态码进行握手。 

 

3.2 WebSocket的优点

       WebSocket有以下优点:

较少的控制开销

        在创建连接后,服务器与客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2到10字节(和数据包长度有关);对客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对HTTP请求每次都要携带完整的头部,此项开销就显著减少了。

更强的实时性

        由于协议是全双工的,所以服务器可以随时主动给客户端发送数据。相对于HTTP请求需要等待客户端发起请求服务器才能响应,延时明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次的传递数据。

保持连接状态

        与HTTP不同的,WebSocket需要先创建连接,这使其成为一种有状态的协议,之后通信可以省略部分状态信息,而HTTP请求可能需要在每个请求都携带状态信息(如身份证等)。

更好的二进制支持

        WebSocket定义了二进制帧,相对HTTP,可以更轻松的处理二进制内容。

支持扩展

        WebSocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。比如部分浏览器支持压缩等。

更好的压缩效果

       相对HTTP压缩,WebSocket在适当的扩展支持下,可沿用之前内容的上下文,在传递类似的数据时,可以显著的提高压缩率。

 

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java实现一对一聊天的 WebSocket 可以使用 Java API for WebSocket (JSR 356) 实现。以下是简单的实现步骤: 1. 创建一个 WebSocketServerEndpoint 类,继承 javax.websocket.Endpoint 类。 2. 在类中实现有 @OnOpen, @OnMessage, @OnClose 三个注解的方法,分别用于处理 WebSocket 的打开、消息接收和关闭事件。 3. 在 @OnOpen 中,使用 session.getBasicRemote().sendText() 方法向客户端发送欢迎消息。 4. 在 @OnMessage 中,使用 session.getId() 获取当前 session 的 id,然后遍历 sessionList,找到对应的接收端 session,使用接收端 session.getBasicRemote().sendText() 方法向接收端发送消息。 5. 在 @OnClose 中,从 sessionList 中删除当前关闭的 session。 以下是一个简单的示例: ```java import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/chat") public class WebSocketServerEndpoint { private static List<Session> sessionList = new ArrayList<>(); @OnOpen public void onOpen(Session session) throws IOException { sessionList.add(session); session.getBasicRemote().sendText("Welcome to chat!"); } @OnMessage public void onMessage(String message, Session session) throws IOException { String sessionId = session.getId(); for (Session s : sessionList) { if (s.getId().equals(sessionId)) { continue; } s.getBasicRemote().sendText(message); } } @OnClose public void onClose(Session session) { sessionList.remove(session); } } ``` 这是一个简单的实现,你可以根据需要进行改进。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值