分享

WebSocket使用

 印度阿三17 2019-05-12

文章目录

1.websocket的由来

  我们经常用的是HTTP协议,而HTTP协议是一种无状态的协议,要实现有状态的会话必须借助一些外部机制如session和cookie,这或多或少会带来一些不便,尤其是服务端和客户端需要实时交换数据的时候(监控,聊天),这个问题更加明显。为了适应这种环境,websocket就产生了。


2.什么是websocket

  是一种在单个TCP连接上进行全双工通信的持久化协议。


3.websocket的特点或作用

  1. 允许服务端主动向客户端推送数据(允许服务端主动向客户端推送数据)

  2. 在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。


4.应用的场景

  1. 聊天:比如我们常用的两天软件,就用到了websocket

  2. 监控:实时监控一个网站的在线

总之适用于:客户端与服务器段高频率低延迟交换事件。


5.使用websocket的优点

  1. 更强的实时性

  2. 保持连接状态,创建一次连接后,之后通信时可以省略部分状态信息

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


6.使用websocket的缺点

  1. 由于websocket使用的持久连接,与服务器一直保持连接,对服务器压力很大


7.websocket 的通信过程

  只需建立一次Request/Response消息对,之后都是TCP连接,避免了需要多次建立Request/Response消息对而产生的冗余头部信息。Request/Response需要三次w


8.如何用websocket


浏览器发送websocket请求头类似如下:
在这里插入图片描述
下面是对请求头部解释(比http协议多了Upgrade和Connection,是告诉服务器包协议设计为ws):

  • Accept-Encoding:浏览器可以接受的数据的压缩类型。

  • Accept-Language:浏览器可以接受的语言类型。

  • Cache-Control:no-cache不使用强缓存。

  • Connection:Upgrade 通知服务器通信协议提升。

  • Host:主机名。

  • Origin:用于验证浏览器域名是否在服务器许可范围内。

  • Pragma:no-cache HTTP/1.0定义的不使用本地缓存。

  • Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits

  • Sec-WebSocket-Key:lb69kw8CsB4CrSk9tKa3 g==
    握手协议密钥,base64编码的16字节的随机字符串。

  • Sec-WebSocket-Version:13 版本号。

  • Upgrade:websocket 使用websocket协议进行传输数据,而不使用HTTP/1.1。

  • User-Agent:用户代理字符串。


服务器接收到客户端请求后做出响应并返回如下:
在这里插入图片描述
下面是服务器返回的头部解释:

  • Connection:Upgrade 通信协议提升。

  • Date:通信时间

  • Upgrade: websocket 传输协议升级为websocket。

  • Sec-WebSocket-Extensions:permessage-deflate

  • Sec-WebSocket-Accept:q9g5u1WfIWaAjNgMmjlTQTqkS/k=
    将Sec-WebSocket-Key的值进行一定的运算和该值进行比较来判断是否是目标服务器响应了WebSocket请求。

  • Upgrade: 使用websocket协议进行数据传输


8.1 客户端如何用websocket

这里我所指的客户端通常是指浏览器,而且都支持WebSocket API。你也可以通过window.WebSocket来判断你的浏览器是否支持WebSocket,

var ws = null;
function connect(){

       // 1. 创建websocket实例  
		if ('WebSocket' in window){
           	ws = new WebSocket("ws://127.0.0.1:8086/socketServer/" $("#username").val());
		}    
	    else if ('MozWebSocket' in window){
	        ws = new MozWebSocket("ws://127.0.0.1:8086/socketServer/" $("#username").val());
	    }
	    else{
	        alert("该浏览器不支持websocket");    
	    }

	   // 2. 新建session,即创建连接时触发此方法
	    ws.onopen = function() {
           // 可以在此写创建会话后想实现的的逻辑
	    };  
	    
        // 3. 接受消息,evt 是接收到服务端返回给客户端的数据
	    ws.onmessage = function(evt) {
            // 可以在接受消息后想实现的的逻辑,比如修改页面上显示在线认数
	    };    
	        
	    // 4. 关闭连接
	    ws.onclose = function() {
            //  可以在此写会话关闭后想实现的的逻辑
	    };   

		// 5. 出现错误
        ws.onerror = function (e) {
              //  可以在此写出现错误后想实现的的逻辑
        };
}    

// 客户端给服务端发送消息时,调用此方法
function sendMsg() {    
    // 调用ws的send()事件
    ws.send(发送的内容);
}  

解释:

  • 首先要创建webSocket的实例,url一定是ws形式

  • 然后给ws绑定open,message,error,close四个事件

  • 发送数据使用send方法,该方法除了可以发送字符串以外还可以发送blob和二进制数据

  • 创建好的ws对象有一个readyState属性,它的取值有0,1,2,3分别表示正在连接,连接成功,正在关闭,连接关闭


8.2 服务端如何用websocket(以springboot项目为例)

  • 第一步:引依赖

     <dependency>
     		<groupId>org.springframework.boot</groupId>
     		<artifactId>spring-boot-starter-websocket</artifactId>
     </dependency>
     <-- 使用springboot的内置tomcat时,就不需要引入javaEE-api -->
     <dependency>
     	<groupId>javax.servlet</groupId>
     	<artifactId>javax.servlet-api</artifactId>
     </dependency>
  • 第二步:启用websocket的支持

     import org.springframework.context.annotation.Bean;
     import org.springframework.context.annotation.Configuration;
     import org.springframework.web.socket.server.standard.ServerEndpointExporter;
     
     @Configuration  
     public class WebSocketConfig {  
         @Bean  
         public ServerEndpointExporter serverEndpointExporter(){  
             return new ServerEndpointExporter();  
         }  
     }
  • 第三步:通信的具体实现:
    具体实现可以参照如下例子,实现了一个简单的聊天功能:链接:https://pan.baidu.com/s/1iTjETNwQrICfHyDDh5yicg 提取码:0el5 ,可以参考下面这篇博客:https://blog.csdn.net/moshowgame/article/details/80275084

简单说一下聊天实现的逻辑:每次客户端创建连接时会产生一个会话session,并存放起来,该session唯一标识,当客户端发送消息时,会给服务端发送包含发送给谁及发送内容的信息的消息message,然后客户端根据客户端传过来的发送给谁的信息查询对应的session,然后调用session.getBasicRemote().sendText(message)就可以给对方发送消息了,对方会监听ws.onmessage()方法,该方法就是监听对方发消息的,只要对方发消息就会触发该方法然后接受消息,如果时群发,循环调用上面的步骤即可


9.http 与 websocket 的区别

  三次握手详解参见:https://www.jianshu.com/p/85aef5a0e3d8,
  四次挥手详解参见:https://www.cnblogs.com/qdhxhz/p/8470997.html

9.1 相同点:

  1. 都属于应用层协议

  2. 都是用Request/Response模型进行连接的简历

  3. 都可以在网络中传输数据

9.2 不同点:

  1. ws使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用

  2. ws连接建立之后,通信双方都可以在任何时刻向另一方发送数据

  3. ws连接建立之后即握手后,TCP套接字保持打开状态套接字是网络编程中的一种通信机制,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程),数据的传输使用帧来传递,不再需要Request消息

  4. ws的数据帧有序


10. websocket 和 socket区别

  说到这个我不得不用这句话来回答你:就像Java和JavaScript的关系一样,两者没有丝毫的联系。socket即通常说的套接字,它是和网络中的运输层打交道的

来源:http://www./content-4-188051.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多