WebSocket初识及在VUE中的使用

612 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

WebSocket

一、什么是websocket

· WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)

· 它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的

· Websocket是一个持久化的协议

二、websocket的原理

    websocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp的连接,从而方便它们之间的通信

    在websocket出现之前,web交互一般是基于http协议的短连接或者长连接,

websocket是一种全新的协议,不属于http无状态协议,协议名为"ws"

三、websocket与http的关系

图片.png

相同点:

1. 都是基于tcp的,都是可靠性传输协议

2. 都是应用层协议

不同点:

1. WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息 HTTP是单向的

2. WebSocket是需要浏览器和服务器握手进行建立连接的

3. 而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接

联系:

WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的

总结:

    首先,客户端发起http请求,经过3次握手后,建立起TCP连接;http请求里存放WebSocket支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;

    然后,服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据;

    最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信。

4、websocket的改进

一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。在客户端断开WebSocket连接或Server端中断连接前,不需要客户端和服务端重新发起连接请求。在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实现了“真·长链接”,实时性优势明显。

图片.png

WebSocket有以下特点:

      是真正的全双工方式,建立连接后客户端与服务器端是完全平等的,可以互相主动请求。而HTTP长连接基于HTTP,是传统的客户端对服务器发起请求的模式。

HTTP长连接中,每次数据交换除了真正的数据部分外,服务器和客户端还要大量交换HTTP header,信息交换效率很低。Websocket协议通过第一个request建立了TCP连接之后,之后交换的数据都不需要发送 HTTP header就能交换数据,这显然和原有的HTTP协议有区别所以它需要对服务器和客户端都进行升级才能实现(主流浏览器都已支持HTML5)

 

5、websocket的功能

(1)通知功能:

保持一个长连接,当服务端游新的消息,能够实时的推送到使用方。像知乎的点赞通知、评论等,都可以使用WebSocket通信。

某些使用H5的客户端,为了简化开发,也会使用WebSocket进行消息的通知,由于它是实时推送的,会有更好的用户体验。

(2)数据收集:

一些次优级别的数据,比如行为日志、trace、异常执栈收集等,都可以开辟专门的WebSocket通道进行传输。这能够增加信息的集中度,并能及时的针对用户的行为进行合适的配置推送。由于大多数浏览器内核都支持,它将使客户端APM编程模型变得简单。

(3)加密 && 认证:

虽然使用Fiddler、Charles等能够抓到很多WebSocket包。但如果同时开启SSL,传输加密后的二进制数据,会大幅增加破解的成本,会安全的多。

(4)反向控制钩子:

由于是双工长连接,服务端完全可以推送一些钩子命令,甚至直接是代码,在客户端进行执行。

6、websocket支持的浏览器

webSocket是基于h5规范的组成部分之一,在2011年的时候正式成为标准,目前chromefirefoxOperasafari等主流的浏览器都支持,ie浏览器是从ie10之后也开始支持。我们知道WebSocket是一种在服务器与客户端双向通讯的技术,使用原生的WebSocket可以最小化 服务器资源的使用并且为两者提供了一种统一的通信方式。

图片.png

7、websocket的事件

一共有 4 个事件:

· open —— 连接已建立

· message —— 接收到数据

· error —— WebSocket 错误

· close —— 连接已关闭

8、websocket数据传输格式

WebSocket 通信由 “frames”(即数据片段)组成,可以从任何一方发送,并且有以下几种类型:

      “text frames” —— 包含各方发送给彼此的文本数据。

    “binary data frames” —— 包含各方发送给彼此的二进制数据。

    “ping/pong frames” 被用于检查从服务器发送的连接,浏览器会自动响应它们。

    还有 “connection close frame” 以及其他服务 frames。

在浏览器里,我们仅直接使用文本或二进制 frames

 

9、websocket在vue中的应用

App.vue中

1.初始化参数

data() {

        return {
            //服务器的ip

            url"ws://192.168.1.69:8080/websocket/user6",

            wsnull,

            lockReconnectfalse,

            websocketTimernull,

        }

    },

 

2. 初始化页面

created() {
        //增加时间戳,是每一个用户的都不相同

        let time = new Date().getTime()

        this.url = this.url + time

        this.initWebSocket()

    }

 

3. 初始化方法

// websocket 初始化

        initWebSocket() {

            if (typeof WebSocket === "undefined") {

                this.$message.error("您的浏览器不支持WebSocket")

            } else {

                this.ws = new WebSocket(this.url)

                this.ws.onopen = this.wsOpen

                this.ws.onclose = this.wsClose

                this.ws.onerror = this.wsError

                this.ws.onmessage = this.wsMessage

                this.$ws.setWs(this.ws)

            }

        },

 

4. 打开websocket

wsOpen(e) {

            this.ws.send("websocket开始连接")

            console.log(this.$ws)

        },

 

5. 发送消息

 

wsMessage(e) {

            console.log("message", e)

            console.log(e.data)

        },

 

6. 报错

 

wsError(e) {

            // console.log("error", e)

            console.log("websocket出现错误")

            this.reconnect()

        },

 

7. 重新连接

reconnect() {

            //重新连接

            console.log("开始重连WebSocket")

            if (this.lockReconnect) {

                return

            }

            this.lockReconnect = true

            //避免没连接上会一直重连

            this.websocketTimer && clearTimeout(this.websocketTimer)

            this.websocketTimer = setTimeout(() => {

                this.initWebSocket()

                this.lockReconnect = false

            }, 5000)

        }

 

8. 关闭

wsClose(e) {

            console.log("websocket已经关闭")

        },

在你需要用到的vue页面中

created() {

        // 打开webSocKet

        this.wsMsg()

    },
// methods中

        wsMsg() {

            let that = this

            that.$ws.ws.onmessage = function (e) {

                if (!e.data) {

                    return

                }
                //判断数据中是否包含task_type这个参数,具体看后台给你传的数据

                if (e.data.indexOf("task_type") == -1) {

                    return

                }

                // console.log(e.data)

                let data = JSON.parse(e.data)

                const ExecutorResult = ["releaseType"]
                //判断数据是否是自己所需的数据

                if (ExecutorResult.includes(data.task_type)) {

                    console.log(data.data)

                }

            }

        },