WebSocket的总结

作者: 蓝瘦额香菇 | 来源:发表于2017-02-17 11:09 被阅读470次

    最近做的几个项目都用到了HTML5的WebSocket技术,并且在一些公司的面试中该内容也会被问到,为此有必要将WebSocket方面的知识整理一下。

    WebSocket概述

    HTTP协议是一种无状态的协议,要实现有状态的会话必须借助一些外部机制如session和cookie,这或多或少会带来一些不便,尤其是服务端和客户端需要实时交换数据的时候(监控,聊天),这个问题更加明显。WebSocket就是在这种大环境下应运而生。
    WebSocket允许服务器和客户端进行全双工通信,传统的HTTP是单双工通信,它只能允许客户端向服务器发出请求,服务端被动返回数据,而不能主动向客户端传递数据。
    WebSocket可以完全取代Ajax,用来向服务器传递字符串,二进制等多种类型的数据,而且还不存在跨域问题。
    WebSocket不使用HTTP协议,而是使用自己的协议。浏览器发出的WebSocket请求类似下面这种:

    websocket-request.png

    下面我们来分析一下这个请求头部

    • Accept-Encoding:浏览器可以接受的数据的压缩类型。
    • Accept-Language:浏览器可以接受的语言类型。
    • Cache-Control:no-cache不使用强缓存。
    • Connection:Upgrade 通知服务器通信协议提升。
    • Host:主机名。
    • Origin:用于验证浏览器域名是否在服务器许可范围内。
    • Pragma:no-cache HTTP/1.0定义的不使用本地缓存。
    • Upgrade:websocket 使用websocket协议进行传输数据,而不使用HTTP/1.1。
    • User-Agent:用户代理字符串。
    • Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
    • Sec-WebSocket-Key:lb69kw8CsB4CrSk9tKa3+g== 握手协议密钥,base64编码的16字节的随机字符串。
    • Sec-WebSocket-Version:13 版本号。

    服务器接收到客户端的请求并返回如下:

    websocket-response.png

    我们来分析一下服务器返回的头部信息:

    • Connection:Upgrade 通信协议提升。
    • Upgrade: websocket 传输协议升级为websocket。
    • Sec-WebSocket-Extensions:permessage-deflate
    • Sec-WebSocket-Accept:q9g5u1WfIWaAjNgMmjlTQTqkS/k= 将Sec-WebSocket-Key的值进行一定的运算和该值进行比较来判断是否是目标服务器响应了WebSocket请求。

    WebSocket协议用ws表示,此外还有wss表示加密的WebSocket协议,类似https。
    现在大部分浏览器都支持WebSocket(包括IE10+),服务器端(node)需要安装模块,目前比较流行的是socket.io和ws,我个人喜欢用ws。

    客户端该怎么用WebSocket

    这里我所指的客户端通常是指浏览器,而且都支持WebSocket API。你也可以通过window.WebSocket来判断你的浏览器是否支持WebSocket。废话不多说,我们先来一段代码,然后通过代码来学习如何在客户端使用WebSocket。

    let ws  = new WebSocket('ws://10.11.10.66:3000');
    ws.addEventListener('open', event => {
            console.log(ws.readyState);
            ws.addEventListener('message', (event, flags) => {
              console.log(event.data);
                  ws.send('ssss');
        });
        ws.addEventListener('close', event => {
                console.log('client notified websocket has closed', event.data);
        });
    });
    ws.addEventListener('error', event => {
            console.log('error', event.data);
    });
    

    接下来我们重点说一下怎么使用浏览器WebSocketAPI。首先我们要创建一个WebSocket的实例即new WebSocket(url); 然后我们需要绑定四个事件open,message,error,close看他们的
    的名字我们就知道他们表示什么意思了。发送数据使用send方法,该方法除了可以发送字符串以外还可以发送blob和二进制数据,具体怎么使用,等到大家想用的时候再去找。哦,还有一个我们创建好的ws对象有一个readyState属性,它的取值有0,1,2,3分别表示正在连接,连接成功,正在关闭,连接关闭。

    服务器端该怎么使用WebSocket

    服务器端使用WebSocket需引入相关的模块,目前比较流行的是socket.io和ws。由于本人在项目中都是使用的ws模块,下面只给出ws模块的使用方法,socket.io模块的使用方法大家可以去网上找。

    var express = require('express');
    var http = require('http');
    var WebSocket = require('ws');
    
    var app = express();
    app.get('/', function(req, res, next){
            res.sendFile(__dirname + '/index.html');
    });
    var server = http.createServer(app);
    var wss = new WebSocket.Server({ server });
    wss.on('connection', function(ws){
            ws.on('message', function(message, flag){
                    if (ws.readyState === WebSocket.OPEN){
                            //你的操作
                    }
            });
            ws.send('something');
    });
    server.listen(3000, function(){
            console.log('listening on port:3000');
    });
    

    下面简单说明一下,搭配上述服务器我还引入了express模块,其实ws模块是可以单独工作的,只不过我的项目都是建立在express开发框架上的,express怎么使用网上教程也蛮多的,大家想知道具体用法可自行百度。上面的代码可以称作模板式的代码,以后大家想搭建一个WebSocket服务的话,只需复制一下,然后修改对应的参数即可,相信有一定开发经验的同学都看得懂其中的含义。

    WebSocket和Socket的区别

    WebSocket和Socket有什么区别或者联系?说到这个我不得不用这句话来回答你:就像Java和JavaScript的关系一样,两者没有丝毫的联系。


    Java和JavaScript

    首先说一下Socket,这个东西我在大学时上java 课网络编程的时候就接触过,套接字,它是为了方便我们开发人员使用TCP/IP或者UDP来构建服务而抽象出来的一个概念,它也有自己的一套API,说实话它是和网络中的运输层打交道的,如果你的项目是基于HTTP来构建服务的话可以不用理会它。
    WebSocket则是一种新的通信协议,是为了解决实时传递数据而开发的一种全双工的通信协议,它也有自己的一套编程接口,作为开发人员我们知道这些就足够了,毕竟我们不是搞科学研究的,点到为止。

    WebSocket和HTTP的比较

    相同点:

    • 都属于应用层的协议。
    • 都使用Request/Response模型进行连接的建立。
    • 都可以在网络中传输数据。

    不同点:

    • ws使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用。
    • ws连接建立之后,通信双方都可以在任何时刻向另一方发送数据。
    • ws连接建立之后,数据的传输使用帧来传递,不再需要Request消息。
    • ws的数据帧有序。

    相关文章

      网友评论

        本文标题:WebSocket的总结

        本文链接:https://www.haomeiwen.com/subject/djchwttx.html