第五期分享:WebSocket的前世今生

152人浏览 / 0人评论

这段时间做一个项目,涉及到直播和实时聊天,开发过程中用到了WebSocket,就顺带了解了一波,给大家简单做个分享(关于直播的以后有机会也可做个简单分享,哈哈哈)!

项目需求是,用户在观看直播时可以实时进行互动(群聊),用户量大,并且消息延迟不能太高,基本要实现实时发送实时接收的那种,还需要跟数据库有互动。 一开始对这个玩意是没有任何概念的,没办法,太菜了,但是在前辈的帮助下,还是完成了这一块功能,整个过程说不上轻松,倒也学到了一项新技能,这玩意还是很好玩的。 接下来就介绍下,整个需求的核心——WebSocket。

拓展:在WebSocket出现之前,一般通过两种方式来实现Web实时用:轮询机制和流技术;其中轮询有不同的轮询,还有一种叫Comet的长轮询。

轮询: 这是最早的一种实现实时 Web 应用的方案。 客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步。 这种同步方案的缺点是,当客户端以固定频率向服务 器发起请求的时候,服务器端的数据可能并没有更新,这样会带来很多无谓的网络传输,所以这是一种非常低效的实时方案。

长轮询: 是对定时轮询的改进和提高,目的是为了降低无效的网络传输。 当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者 时间过期,通过这种机制来减少无效的客户端和服务器间的交互。 当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提高。

流:常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务 器端的连接不过期。通过这种机制可以将服务器端的信息源源不断地推向客户端。这种机制在用户体验上有一点问题,需要针对不同的浏览器设计不同的方案来改进 用户体验,同时这种机制在并发比较大的情况下,对服务器端的资源是一个极大的考验。

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。 轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。 这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。 HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。 当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

创建 WebSocket 对象

  •  
  •  
  •  
var Socket = new WebSocket(url, [protocol] );var ws = new WebSocket("ws://127.0.0.1:8888");//ws表示使用WebSocket协议,后面接地址及端口

以上代码中的第一个参数 url, 指定连接的 URL。

第二个参数 protocol 是可选的,指定了可接受的子协议。

完整的客户端代码:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
<script type="text/javascript">var ws;var box = document.getElementById('box');function startWS(){  ws = new WebSocket("ws://127.0.0.1:8888");  ws.onopen = function(msg){    console.log("WebSocket已打开");  };  ws.onmessage = function(msg){    console.log("接收消息=="+msg.data);    box.insertAdjacentHTML('beforeend','<p>'+msg.data+'</p>');  };  ws.onerror = function(){    console.log("发生错误=="+error);  };  ws.onclose = function(){    console.log("WebSocket已关闭");  };}function sendMessage(){console.log("发送消息");  var text = document.getElementById('text');  ws.send(text.value);}windown.onbeforeunload = function(){  //首先关闭Websocket  ws.onclose = function(){    };  ws.close();}</script>

 

服务端代码较多,这里就不一一贴出来了,需要的朋友可以私信,一起交流!

全部评论