WebSocket学习

一、简介

WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。
这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数 Web 应用程序将通过频繁的异步 AJAX 请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

二、HTTP和websocket图

http协议:
websocket协议:
在这里插入图片描述

三、websocket协议

本协议有两部分:握手和数据传输。

握手是基于http协议的。

来自客户端的握手看起来像如下形式:

GET ws://localhost/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Version: 13

来自服务器的握手看起来像如下形式:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Extensions: permessage-deflate

字段说明:

头名称说明
Connection:Upgrade标识该HTTP请求是一个协议升级请求
Upgrade: WebSocket协议升级为WebSocket协议
Sec-WebSocket-Version: 13客户端支持WebSocket的版本
Sec-WebSocket-Key:客户端采用base64编码的24位随机字符序列,服务器接受客户端HTTP协议升级的证明。要求服务端响应一个对应加密的Sec-WebSocket-Accept头信息作为应答
Sec-WebSocket-Extensions协议扩展类型

四、客户端(浏览器)实现

4.1 websocket对象

实现 WebSockets 的 Web 浏览器将通过 WebSocket 对象公开所有必需的客户端功能(主要指支持 Html5 的浏览器)。

以下 API 用于创建 WebSocket 对象:

var ws = new WebSocket(url);

参数url格式说明: ws://ip地址:端口号/资源名称

4.2 websocket事件

WebSocket 对象的相关事件

事件事件处理程序描述
openwebsocket对象.onopen连接建立时触发
messagewebsocket对象.onmessage客户端接收服务端数据时触发
errorwebsocket对象.onerror通信发生错误时触发
closewebsocket对象.onclose连接关闭时触发
4.3 WebSocket方法

WebSocket 对象的相关方法:

方法描述
send()使用连接发送数据

五、服务端实现

Tomcat的7.0.5 版本开始支持WebSocket,并且实现了Java WebSocket规范(JSR356)。

Java WebSocket应用由一系列的WebSocketEndpoint组成。Endpoint 是一个java对象,代表WebSocket链接的一端,对于服务端,我们可以视为处理具体WebSocket消息的接口, 就像Servlet之与http请求一样。

我们可以通过两种方式定义Endpoint:

  • 第一种是编程式, 即继承类 javax.websocket.Endpoint并实现其方法。
  • 第二种是注解式, 即定义一个POJO, 并添加 @ServerEndpoint相关注解。

Endpoint实例在WebSocket握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭时结束。在Endpoint接口中明确定义了与其生命周期相关的方法, 规范实现者确保生命周期的各个阶段调用实例的相关方法。生命周期方法如下:

方法含义描述注解
onClose当会话关闭时调用。@OnClose
onOpen当开启一个新的会话时调用, 该方法是客户端与服务端握手成功后调用的方法。@OnOpen
onError当连接过程中异常时调用。@OnError

服务端如何接收客户端发送的数据呢?

通过为 Session 添加 MessageHandler 消息处理器来接收消息,当采用注解方式定义Endpoint时,我们还可以通过 @OnMessage 注解指定接收消息的方法。

服务端如何推送数据给客户端呢?

发送消息则由 RemoteEndpoint 完成, 其实例由 Session 维护, 根据使用情况, 我们可以通过Session.getBasicRemote 获取同步消息发送的实例 , 然后调用其 sendXxx()方法就可以发送消息, 可以通过Session.getAsyncRemote 获取异步消息发送实例。

服务端代码:

@ServerEndpoint("/robin")
public class ChatEndPoint {

    private static Set<ChatEndPoint> webSocketSet = new HashSet<>();

    private Session session;

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        System.out.println("接收的消息是:" + message);
        System.out.println(session);
        //将消息发送给其他的用户
        for (Chat chat : webSocketSet) {
            if(chat != this) {
                chat.session.getBasicRemote().sendText(message);
            }
        }
    }

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);
    }

    @OnClose
    public void onClose(Session seesion) {
        System.out.println("连接关闭了。。。");
    }

    @OnError
    public void onError(Session session,Throwable error) {
        System.out.println("出错了。。。。" + error.getMessage());
    }
}

结束!!!!

声明:本笔记来源黑马的B站教学笔记,文章仅用于学习。


					鱼找鱼,虾找虾,乌龟找王八。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值