HTTP简述:

  • http 1.x

    1,http/1.0 支撑POST HEAD等恳求办法,浏览器每次恳求都需求与服务器树立一个TCP衔接,恳求处理完后立即断开TCP衔接。

    2,http/1.1支撑PUT、DELETE等恳求办法,采用耐久衔接,多个恳求能够共用同一个TCP衔接。

  • http2.0

    1,在运用层与传输层之间,增加了一个二进制分帧层。

    2,多路复用,能够完成并行发送多个恳求。http 1.x版别是长衔接,但多个恳求发送是串行。

    3,能够对浏览器等候的要害的数据流设置优先级,对数据流能够采用不同的优先级战略。

    4,更多细节…

  • https http的安全版,运行在安全套接字协议(SSL)或传输层安全协议(TLS)之上,树立了一个信息安全通道,所有的TCP中传输的内容都需求经过加密,保证了数据安全。衔接端口是443。TLS后文有简述。

  • tcp传输操控协议:是全双工通讯。

    1,首部至少20个字节;UDP首部只要8个字节(源端口号+目的端口号+UDP长度+UDP校验和 均是16位)。

    2,可靠传输(ARQ:超时自动重传恳求;滑动窗口协议,是点对点的通讯操控)

    3,流量操控(根据接纳方窗口缓冲区操控发送方的发送速率)

    4,拥塞操控(举例:慢开端:指数增加;拥塞防止:加法线性增加;快康复+快重传:当发现带宽网络拥塞时,将ssthresh阈值减为拥塞峰值的一半,然后进行快康复且运用加法增大传输数据包。 ps:经过wireshark抓包一个TCP衔接的数据展现如图:

这一路:从HTTP到WebRTC音视频通话

  • tcp三次握手之后TLS握手:(三次握手四次挥手略,老生常谈)

    1,客户端会发送一个ClientHello恳求,内容包括支撑的TLS版别、加密套件以及一个随机数。

    2,服务器收到后会呼应ServerHello(会包括一个随机数)、下发服务器自己的证书(客户端可根据证书列表check服务器是否可信)和ServerKeyExchange(包括服务器随机生成的一对密钥中的公钥pubkey),然后呼应ServerHelloDone。

    3,客户端进行ClientKeyChange操作,向服务器发送的内容中,包括公钥pubkey加密后的第三个随机数(预主密钥),以及Change Cipher Spec奉告服务器用商定好的算法和密钥进行加密,然后奉告服务器Encrypted Handshake message。

    4,服务器收到后用私钥解密获取到预主密钥并呼应Encrypted Handshake message 。

    5,根据上述通讯,客户端和服务器都具有了相同的两个随机数和预主密钥,然后经过约定好的算法生成最终的会话密钥,此后经过对称暗码进行数据传输。

  • 数字证书(数字签名):私钥加密公钥解密,文章内容会经过哈希算法参加其间,因而可验证文件完整性。

    数字签名的进程:

    1,用户将主体信息(包括一串随机数后面作为私钥privatekey)发给CA,CA会利用主体信息生成主体文件的公钥而且进行签名,签完名的文件便是数字证书,回来给用户。 2,用户将文件经过单向散列函数生成128位的摘要,然后用privatekey私钥对此摘要进行加密。

    3,当用户将文件,加密的摘要,公钥publickey发送其他用户时。他人能够对文件进行同样的单向散列函数发生的摘要h1和用publicekey对加密后的摘要解密生成的摘要h2进行比对。假如相等,则文件合法未被篡。

    客户端端拿到服务器下发的证书时,会对文件信息进行hash算法得到一个数字指纹h1,以及经过用ca公钥(本地保存的)解密签名会得到一个数字指纹h2,假如h1和h2共同,则证书合法。假如是客户端拿到服务器发送的签名证书,则会向CA验证证书的合法性。一般浏览器出厂时会内置了诸多CA机构的数字证书校验办法。 拓宽:在区块链的实际运用上,币买卖时,input买方需求拿到output卖方的公钥。

客户端与服务器的交互

  • JWT:json web token

    1,普通的token:服务端验证token信息要进行数据的查询操作;而JWT验证token信息并不用,在服务端运用密钥校验就能够,无需查询数据库。

    2,组成:Header头部(base64后)+Playload负载(base64后)+signature签名

    3,作业流程

这一路:从HTTP到WebRTC音视频通话

  • 跨域: 服务器呼应头设置Cors,在header中装备”Access-Control-Allow-Origin”,表明答应访问者能够跨域访问,而且指定答应的域。 客户端恳求头header中”Origin”字段,表明建议一个针对跨域资源共享的恳求。
  • cookie与session :Cookie是根据客户端存储数据到本地,服务端能够回来Cookie交给客户端存储。Session是根据服务器存储数据。 客户端初次向服务端建议树立网络恳求后,服务端会树立一个Session,在呼应头中装备”SetCookie:JSESSIONID=xxx”以及domain等。客户端收到后会设置Cookie保存JSESSIONID。在Cookie有效期后,在今后的request恳求中,都会带上此JSESSIONID,服务端接纳到此恳求后,会找到之前现已树立的SESSION。

socket与WebSocket

  • socket:并非协议,是根据TCP/IP网络封装的API,为了方便TCP或UDP而抽象出来的一层,是坐落运用和传输操控层之间的一组接口,socket利用TCP/IP协议树立TCP衔接,进行依靠于底层的IP协议,更深层次依靠于数据链路层。 保持长链接。

socket的树立进程如图:

这一路:从HTTP到WebRTC音视频通话

代码演示:

    //客户端:
    public static final int PORT = 8080;
    public static final String HOST = "127.0.0.1";
    Socket socket = new Socket(HOST, PORT);
    OutputStream os = socket.getOutputStream();
    InputStream is = socket.getInputStream();
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    os.write("向服务端写数据");
    socket.shutdownOutput();
// 读取服务器发送的数据
    byte[] buffer = new byte[8192];
    int len;
    while ((len = is.read(buffer)) != -1) {
        outStream.write(buffer, 0, len);
    }
    //服务端:
    //创立ServerSocket的接口
    public ServerSocket(int port) throws IOException {
        this(port, 50, null);
    }
    ServerSocket(int port, int backlog, InetAddress bindAddr);
    public InetSocketAddress(InetAddress addr, int port) {
        holder = new InetSocketAddressHolder(
                        null,
                        addr == null ? InetAddress.anyLocalAddress() : addr,
                        checkPort(port));
    }
    ServerSocket server = ServerSocket(PORT);
    Socket sk = server.accept();
    //读写数据,代码 类上
  • webSocket:HTTP、WebSocket等运用层协议,都是根据TCP协议来传输数据的。有必要依靠HTTP协议进行一次握手,握手成功后,数据就直接从TCP通讯传输,与HTTP无关了。WebSocket API是HTML5规范的一部分,完成了客户端与服务端全双工通讯,而HTTP是单向通讯。 代码演示:
//代码描摹于某大神,有逻辑改动
//server.js
//终端安装websocket库:npm install websocket
var websocket = require('websocket').server
var http = require('http')
const HOST = 'http://127.0.0.1:8080';
const PORT = 8080;
var httpServer = http.createServer().listen(PORT, function(){
    console.log(HOST)
})
var wsServer = new websocket({
    httpServer: httpServer,
    autoAcceptConnections: false,
})
wsServer.on('request', function (request) {
    var connect = request.accept()
    connect.on('message', function (message) {
        console.log(Date.now());
        message.fromServer = 1;
        console.log(message)
        connect.send(message.utf8Data)
   })
    //监听封闭衔接操作
    connection.on("close", function (code, reason) {    
        var message = {}
        message.type = "leave"
        message.data =  "脱离了"
        connect.send(JSON.stringify(message))
    })
    //过错处理
    connection.on("error", function (err) {
        console.log(err)
    })
})
//浏览器端:经过<script>的方法运用WebSocket功用。
<script>
    const hostPort = 'ws://127.0.0.1:8080'
    var webSocket = new WebSocket(hostPort) 
    /*readyState总共四种状况
    0: 链接还没有树立,正在树立链接
    1:链接树立
    2:链接正在封闭
    3:链接现已封闭
    */
    webSocket.onopen = function(){
        console.log(webSocket.readyState)
    }
    function send(){
        var text = document.getElementById('text').value
        webSocket.send(text)
    } 
    webSocket.onclose = function () {
        console.log("websocket close")
    }
    //实时监听服务器推送到客户端的事情
    webSocket.onmessage = function (msg) {
        console.log(Date.now());
        showMessage(msg.data, msg.type)
    }
    //在页面中现实谈天内容
    function showMessage(str, type) {
        var div = document.createElement('div')
        div.innerHTML = str;
        if (type == "enter") {
            div.style.color = "blue";
        } else if(type == "leave") {
            div.style.color = "red"
        } else if(type == "message") {
            div.style.color = "black"
        }
        document.body.appendChild(div)
    }
    </script>

WebRTC技术是H5规范之一,它经过简单的API为浏览器和移动端运用程序供给了实时通讯的功用

  • WebRTC结构

这一路:从HTTP到WebRTC音视频通话

  • WebRTC通话原理:

1,媒体洽谈:简而言之,便是对通讯两头能够支撑的编解码格局取交集,例如A端支撑VP8、H264,B端支撑H264,H265,那么为保证AB两头通讯正常,则选H264…。SDP(Session Description Protocol)用于描绘上述这类信息。视频通讯双方有必要先交换SDP信息,这个进程叫媒体洽谈。

2,网络洽谈:通讯两头要了解对方的网络状况,以保证找到一条彼此通讯的链路。抱负的场景是两头都是私有公网IP,能够直接peer2Peer衔接。但真实的状况,终端都是在局域网中,需求NAT(Network Address Translation:网络地址转化)。为处理WebRTC这些问题,引出了STUN和TURN。

(1)STUN(Session Traversal Utilities for NAT, NAT会话穿越运用程序)是一种网络协议,它答应坐落NAT后的客户端找出自己的公网地址,查出自己坐落哪种类型的NAT之后,以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间创立UDP通讯。这样就能给无法在公网环境下的视频通讯设备分配公网IP以树立通话衔接。简而言之:STUN是奉告我对方的公网IP地址+端口。

媒体流传输依照P2P的方法,STUN并不是每次都能成功地为需求NAT的通讯端分配IP地址,P2P地方法在多人视频通话中,更是严重依靠本地的带宽。TURN能够很好的处理这个问题。

(2)TURN(Traversal Using Relays around NAT)是STUN/RFC5389的一个拓宽。首要添加了Relay功用。假如终端在NAT之后,那么在特定的状况下,有可能使得终端无法和其对等端进行直接的通讯,这时就需求公网的服务器作为一个中继,对来往的数据进行转发,这个转发协议就被界说为TURN。这种方法的带块由服务器端处理。

(3)在WebRTC中用来描绘网络信息的术语叫candidate,也叫网络洽谈。

3,信令体系(信令服务端)

(1)信令服务端包括交互媒体信息sdp和网络信息candidate,以及房间办理和人员进出等;

(2)信令发送进程:

这一路:从HTTP到WebRTC音视频通话

    //信令集合
    //自动加入房间
    const SIGNAL_TYPE_JOIN = "join"
    //奉告加入者对方是谁
    const SIGNAL_TYPE_RESP_JOIN = "resp-join"
    //自动脱离房间
    const SIGNAL_TYPE_LEAVE = "leave"
    //有人加入房间 告诉现已在房间的人
    const SIGNAL_TYPE_NEW_PEER = "new-peer"
    //有人脱离房间 告诉现已在房间的人
    const SIGNAL_TYPE_PEER_LEAVE = "peer-leave"
    //发送offer给对端peer
    const SIGNAL_TYPE_OFFER  = "offer"
    //发送offer给对端peer
    const SIGNAL_TYPE_ANSWER = "answer"
    //发送candidate给对端peer
    const SIGNAL_TYPE_CANDIDATE = "candidate"
     // 初始化本地媒体流:  
    navigator.mediaDevices.getUserMedia({  
        audio:true,  
        video:true  
    })
     // 打开本地媒体流  
     varlocalVideo=document.querySelector('#localVideo');  
     localVideo.srcObject=stream;//显现画面  
     localStream=stream;//保存本地流的句柄
    //DoOffer:  
    1,创立RTCPeerConnecttion对象并设置onicecandidate监听事情。监听事情中会触发 candidate信令。见下一代码块
    2,写入本地session描绘 
    3,发送offer信令  
    //handleRemoteOffer:  
    1,写入远端session描绘
    //DoAnswer:
    1,写入本地session描绘,并发送answer信令。
    //HandleRemoteAnswer:  
    写入本地session描绘

RTCPeerConnection音视频通话的中心类

//描摹代码拿来主义(建议整个信令体系描摹一遍,细节印象更深入)
functioncreatePeerConnection(){  
vardefaultConfiguration={  
bundlePolicy:"max-bundle",  
rtcpMuxPolicy:"require",  
iceTransportPolicy:"all",//relay或许  
//修正ice数组测试作用,需求进行封装  
iceServers:[  
{  
"urls":[  
"turn:![]()192.168.0.1:61313?transport=udp",  
"turn:![]()192.168.0.1:61313?transport=tcp"//能够插入多个进行备选  
],  
"username":"kinno_CN",  
"credential":"There will be more surprises here, Beyond foresight"  
},  
{  
"urls":[  
"stun:![]()192.168.0.1:61313"  
]  
}  
]  
};  
pc=newRTCPeerConnection(defaultConfiguration); 
pc.onicecandidate=handleIceCandidate;  
pc.ontrack=handleRemoteStreamAdd;  
pc.onconnectionstatechange=handleConnectionStateChange;  
pc.oniceconnectionstatechange=handleIceConnectionStateChange  
localStream.getTracks().forEach((track)=>pc.addTrack(track,localStream));//把本地流设置给RTCPeerConnection  
}
function handleRemoteStreamAdd(event) {
    remoteStream = event.streams[0]
    remoteVideo.srcObject = remoteStream;
}

ps:在运用模仿服务器软件XShell(最新版)时,会提示安装过错,需求修正注册表,修正后重启会ok。