最近由于工作需要,研究了一下手机WAP网络对于长连接推送的可行性,由于测试条件所限,仅测试了广州电信的ctwap以及广州移动的cmwap,结果也许不是相当全面。
首先,wap与net网络的最大的区别在于使用wap接入点,只能直接访问10.*.*.*,访问外网得通过一个运营商提供的http代理服务器,
移动cmwap为10.0.0.172,电信ctwap为10.0.0.200;而net接入点则能够直接访问所有互联网ip地址。早期的手机由于受限与
手机本身的处理能力以及专为手机提供的内容有限,所以一般使用wap接入,通过代理访问一些简单的移动网页,而且按照流量计费。而在电脑上通过手机上网的
时候使用net接入,按照时间计费。然而,随着手机处理能力的提升,以及运营商的计费策略调整(新出的手机套餐wap与net都已经统一按流量计费了),
目前已经基本上没有人使用wap接入了,除了少部分还在使用早期移动的cmwap包月套餐的人以外。
回到wap接入长连接推送这个问题上,虽然手机访问互联网得通过http代理,但是也并非完全没有办法建立长连接,主要有以下几个思路:
- 通过http代理的connect协议
- 使用http long polling的模式实现协议
- 使用http chunk encoding的模式传输数据
http代理的connect协议原本是用于访问https的服务的,由于https的连接数据经过ssl加密,而且建立连接的时候需要经过ssl
握手,所以http代理没办法像普通的http协议那样,通过解析http头的路径来中转http请求,而且如果代理服务器能知道https的请求机响应
内容就让https失去安全性了。因此,诞生了connect协议,在客户端需要访问https的地址时,首先向http代理服务器发起一个
connect请求,如下:
CONNECT 123.123.123.123:443 HTTP/1.1
User-Agent: UGiA CMWAP Proxy
如果服务器返回如200 Connection established之类的,表示已经在目标服务器与客户端之间建立起一个代理通道,客户端上行数据会直接传给目标服务器,目标服务器的数据也会直接传到客户端,如此就可以实现ssl握手以及https的加密数据的传输。
由于connect协议实际上是建立了一个客户端与服务器直通的代理隧道,因此,可以考虑用他来实现双通的长连接。经过测试,实际上是可行的,但是有一定的限制,具体如下:
- 连接空闲检查,如果连接空闲太久,代理会关闭代理隧道。在我的测试中,移动cmwap大概为120s,不分上下行;电信ctwap下行30s多一点不分上下行
- 连接稳定性。在我的测试中移动cmwap能够实现非常稳定的连接,我几次测试中都能稳定维持长连接超过半小时都没有断开,最后是我主动断开的;而
电信ctwap则相对没那么稳定,有两次3分钟就断了,移动和电信在测试中最长试过两个小时都还没断开,基本可以认为没有最长连接时间限制。
- 端口限制。电信ctwap只能连接443端口,移动cmwap我测试的时候没有端口限制,不过网上搜了一下据说部分地区是有端口限制的,所以最好还是使用标准的443端口。
可见,通过http代理的connect协议确实可以实现长连接推送,而且相当简单,只要保证端口是433而且设计一个定时心跳保证连接不会空闲太久就可以了。
http long
polling是什么我就不做太多的解释了,相信大部分人都知道。协议本质上还是http,因此我对wap网关对http协议的处理特点进行了一些测试。
在测试中发现,跟前面一样,wap网关对连接的最长空闲时间有一定的限制,电信ctwap和移动cmwap同样最长30s,超出这个时间限制,网关会直接
返回一个他伪造的http空响应,因此,不能直接像pc网络中实现http long
polling那样,直接把http请求hold住,等待有数据才响应。
既然不能直接hold住请求,那么可以在服务端收到请求而且不是马上有有效数据返回的时候,也马上开始发送响应,但是在响应中加一个标签(譬如说特
别的http header),并且让响应的body慢慢的发送,譬如说用chunk
encoding每个20s发送1字节没用的数据直到有有效数据的时候结束响应,或者直接发送定长100字节响应,每隔20s发送1字节没用数据,直到有
有效数据的时候一口气把100字节中剩下的发完结束响应。经过测试,这种模式是确实可行的,但是流量相对会较大,因为http请求/响应头较大。
熟悉http协议的人应该会知道Chunk Encoding。通过Chunk Encoding可以在http协议中在需要的时间发送不定长响应数据,如果把心跳和实际数据封装成chunk数据一个个数据包的发给客户端,理论上也可以实现单通的长连接。
在测试中,移动cmwap在本次测试中可以完全正常的使用Chunk
Encoding,只要不超过30s的空闲时间就没问题。然而,以前在杭州的时候曾经遇到过网关会合并与延迟
chunk数据的情况,譬如说网关会把每一分钟的所有chunk合并,然后在一分钟后才把合并后的数据用一个chunk包发给手机。
电信ctwap的情况跟cmwap基本一致,不会擅自把Chunk合并,能够拿到原始的数据,但是不保证能完全按照实际发送chunk的时间间隔接
收,尤其是前30s,如果响应没有在30s内结束,网关会把响应hold住30s,然后一次把30s内的数据全输出,后面的基本就按照服务端的输出的情况
一个个chunk转发给客户端。可见Chunk Encoding的不确定性相对比较多,
难以做到相当实时的实现数据推送,而且需要自己用一定的格式封装chunk数据,以免出现chunk合并的情况。
综上所述,wap接入实现长连接推送确实是可行的,但是由于运营商对网关的实现的差异可能会导致稳定性等有较大的差异。本来智能手机普及的现在,wap接入早已过时,运营商应该及早关闭wap接入,这样可以省下维护wap代理网关的成本,开发者也可以少考虑很多问题。