pps服务器未响应_一看就懂系列:网页即时聊天技术之TCP 长连接和服务器推技术...

曾经火过的在线聊天室相信大家都了解,你可以打开浏览器进入聊天室,同时和好几个在线好友聊天,和现在的qq群类似,只是它是基于浏览器的。浏览器是基于http协议来完成交互的,其典型的工作模式就是请求应答,那么聊天室又是如何做到在没有请求的情况下即时将消息发送给所有参与者的呢?

我们今天就来聊一下这个问题。

1.http协议工作模式:请求响应模式的缺点及改进

38f261c97d0b279df1bb7a8709d2d7e0.png

http是一种应用层协议,其本身是无状态的,http1.0中,每发起一个请求,得到一个响应,然后关闭连接。这就是其基本的请求响应工作模式。这种连接是短链接,每一次请求都要创建一个连接。假如我们要实现web 聊天功能,那么只能每隔一段时间就发起一次请求去查询服务器有没有新消息,有则返回新信息,然后关闭连接;没有则关闭连接,过一段时间再次发起查询请求。

这种为了实现聊天功能的轮询方法叫做短轮询,不用我说,大家都知道了,短轮询大部分时间都是在不停的打开、关闭连接。这些都是在做无用功,白白浪费了资源。

那么自然而然就会想到,能不能让好不容易打开的一次tcp连接保持,也就是在一个连接上发起多个请求呢?

2.长连接的实现方式

所谓长连接就是浏览器建立连接并发起请求后,服务器端通过一个死循环维持住这个连接不断开,同时在循环中不停的去检测是否有数据,没有则一直等到有数据了再返回给浏览器。整个过程其实是一个长的轮询过程。

54dd28fda38171b8ddb19d0cbd5b9fa0.png

服务器端不断循环待数据可用时返回给客户端浏览器的过程,有一个专有说法叫做“服务器端推”。另外,服务器端也需要定义一个时长,当循环时间达到该时长还没有新消息时,服务器应该返回一个“无新消息”的响应给浏览器。该时长应该小于web服务器本身的超时时长(TimeOut),以避免出现请求超时的错误。

2.1 利用iframe实现持续输出

在服务器端,在一个循环中每隔一秒持续不断的输出内容,输出的内容输出到jsp页面的iframe中,这样每次iframe刷新则会执行输出的脚本,只要在输出的脚本中调用页面的一个js方法就可以完成页面上内容持续不断的更新,达到长连接的效果。

这里只列出核心代码,完整代码可以加微信 walkingman_c 获取。

服务器端post方法中:

4860f8795e3859fe3a7d853d6c67aa6c.png

每隔2秒钟,向页面输出一段js代码,且每次showInfo方法的参数不同。

客户端页面中,存在一个form表单:

该表单向后台发起post请求,且将响应内容输出到name为rst的iframe中,如下

当iframe刷新后会执行返回的js代码,即执行parent.showInfo(1)方法,该方法会调用iframe所在页面的showInfo方法,

我们在页面加入:

就可以实现将后台返回的内容更新到页面的功能,且每隔2秒更新一次。达到服务器端不断向客户端页面刷内容的“服务器推”效果,且连接也是长连接。

为什么要借助iframe,因为这里利用了iframe的一个特性,就是当iframe的内容更新时其会自动刷新且执行最新的代码,这样,当服务器端内容到达iframe时,iframe会自动刷新并调用父页面的js方法将最新的内容显示在页面上,无需刷新父页面。

2.2 H5 websocket 实现长连接

Websocket(以下简称ws)是html5中出现的新技术,是一种浏览器和服务器全双工通信机制。建立ws连接以后,浏览器和服务器都可以主动向对方发送数据。

Ws的使用比较简单,首先在网页中新建一个socket对象,如下:

    var c = new WebSocket('ws://mysite.com/test', ['soap', 'xmpp']);

要注意的是这里的ws服务器地址是基于ws协议的,所以以ws开头,后面的参数告诉服务器我可以接受的子协议类型,服务器会根据实际情况采用某个字协议,我们可以根据创建好的连接对象c对象的 protocol 属性来得知真正采用的是何种子协议。

c对象创建好了以后,我们就可以向服务器发送信息或者接受服务器发出的信息了。调用c对象的send方法来发送信息。同时,我们可以定义多个监听方法来监听连接对象的各种事件,例如当连接创建出错时、或者每次连接收到来自服务器的信息时,或者连接成功打开时:

  c.onopen = function () {  connection.send('你好'); // 当连接成功打开时,向服务器发送“你好”   };                    c.onerror = function (e) {          console.log('出现错误: ' + e;        };//当建立连接出错时,记录错误日志。        c.onmessage = function (d) {//当接受到服务器的信息时,记录日志。      console.log('收到来自服务器的信息' + d.data);};

网页可以通过send方法向服务器发送字符串、二进制数据(例如图片或者文件等)。

Ws协议不受浏览器同源策略的限制,换句话说,就是服务器可以同时和多个不同域下建立多个ws连接。

服务器要同时维持大量ws长连接,对服务器是有要求的,通常需要服务器是以非阻塞高性能的要求进行设计才可以胜任,通常建议的服务器有nodejs等。

我们以nodejs为例讲解一下服务器端相关开发。

首先在package.json中添加对ws模块的依赖关系:

    "dependencies": {        "ws": "1.1.1"    }

执行npm install 安装依赖模块,然后我们就可以在app.js入口文件中编写代码了。

代码如下:

    const ws= require('ws');//模块导入    const SocketServer= ws.Server;    const wss = new SocketServer({        port: 3000    });//实例化一个在3000端口监听的websocket服务器。    wss.on('connection', function (ws) {//当客户端发起连接时的回调函数。           ws.on('message', function (message) {//该连接上有消息抵达时的处理函数。               console.log(`接收到客户端信息: ${message}`);    //打印接收到的消息    ws.send(`回复消息: ${message}`, (err) => {//通过该连接向客户端发送回复信息                if (err) {//回复消息发送错误时的处理函数                    console.log(`错误日志: ${err}`);                }            });        })    });

我们可以看到,服务器端在某个端口监听连接的接入,有连接接入后会对通过该连接发过来的消息做处理,这个处理逻辑就是我们的后台业务逻辑,最简单的处理逻辑就是简单的打印日志并回复一个消息给客户端。

3.几个容易混淆的概念的区别:长连接、长轮询、websocket。

本小结帮大家澄清几个容易混淆的概念。

长连接:所谓长连接是指TCP长连接,它的本质其实就是连接复用或称之为持久连接,也就是当完成一次请求响应后并不立即关闭连接,而是复用该tcp连接继续发送多次请求响应。其好处是能充分利用连接资源,其缺点是相比于单请求响应单连接而言带来了编程上的复杂性。

长连接是一种利用单个连接发送接收多个请求/响应的思想,其具体的实现办法有很多,例如在http1.0 协议中,浏览器通过在请求头中增加一个Connection: keep-alive 头来告诉服务器该连接是长连接,服务器收到带该请求头的请求后,保存该连接open,同时在响应报文中同样增加Connection: keep-alive,这样浏览器就知道该连接未关闭,下一次请求仍然可以使用该连接来发送。直到浏览器或者服务器任何一端主动关闭该连接为止。在http1.1中默认使用长连接,这样一个TCP长连接能够发送多个请求,不过不同的浏览器实现有不同的最大并发连接数限制,你可以修改并发连接数来提高浏览器网页加载速度。

长轮询:当服务器端有数据时主动推送给客户端,这样一个简单的需求的实现也是经历了很长的历史过程。我们知道,最简单的方法就是让浏览器不断的发请求,这种办法是非常浪费服务器资源的,因为要不断的新建连接、解析http 头、查询数据是否存在、产生响应(往往是一个无数据的空响应)、关闭连接。长轮询则是选择在创建连接以后尽可能长的hold住这个连接,直到有数据可用再返回给客户端。这样就避免无效的反复创建链接、白白浪费了服务器资源。

Websocket:websocket,以下简称ws。是一种为web创造的实时双向通信技术。它是基于TCP/IP协议栈的一种简洁型传输层协议,通过对底层通信细节进行抽象封装为web开发者提供了一种安全可靠的全双工异步实时通信机制。

总体来说,长连接是一种提高浏览器网页性能的思想,通过长连接可以充分利用连接来发送多个请求响应从而提高加载性能,而长轮询则是为了解决服务器推这样一种应用场景而采用的技术手段,只不过后来发明的websocket提供了一种实时双向交互技术,真正解决了服务器推的需求。

4.如果自己动手开发一个web版本的qq: 要点概述。

Web qq 实现中最关键的技术点在于服务器推的实现,我们知道websockt可以实现这个需求,具体到腾讯的web qq 其底层仍然是基于socket来实现的即时双向信息交互,采用的是flash的socket模块,flash提供的xmlsocket类,在网页中嵌入一个使用了xmlsocket的flash程序,js通过调用flash的接口利用xmlsocket来和服务器建立socket连接,同时将服务器发送的消息显示在网页上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值