Web 的话,受浏览器限制,与服务器通信只有通过浏览器提供的接口,XHR / fetch 或是 WebSocket,当然还有 WebRTC。其他的,也只能是这些的封装罢了,或是浏览器根据新标准推出新的 API。各种第三方库也都是普通封装,比如
Socket.IO 封装了 WebSocket,帮你处理心跳包,并对文本进行格式化封装以支持直接发送 JavaScript 对象数组( JSON ),在 WebSocket 连接失败后自动切换到短轮询。gRPC-Web 则是引入了 protobuf 二进制库,然后通过 POST 与中间代理服务器进行通讯,代理服务器将请求掐头去尾转给后端 RPC 服务。
GET、POST 以及其他方法也都受限制,比如同源策略,GET 不能带 body 之类的(其他地方则没有这个限制,比如 ElasticSearch 带 body 的 GET 请求),URL 必须编码,并且总长度有限制之类的。
在没有 Websocket 和 WebRTC 之前,用的长轮询、短轮询。
短轮询就是你本地不断请求服务器的一个 API 接口,没消息的话服务器会直接返回空,本地延迟几秒再重新请求。这种方法貌似没多少在用:本地延迟短的话,HTTP 请求消耗太大(那时还是 HTTP/1.1 ),本地延迟长的话,消息不够及时。
长轮询也是你本地不断请求服务器的一个 API 接口,不一样的是没消息的话,服务器不返回数据,一直持有这个连接,而本地也一直等待服务器返回,一旦有新消息,服务器会通过持有的这个连接立即返回数据。如果长时间没有消息的话,有个超时时间,超时后连接断开,本地无延迟立即重新请求。这个相比短轮询就好很多了,在 Websocket 出来之前,这种方法算是主流,常年不维护的 QQ 邮箱就是这种方法一直用到今天还在用。
Websocket 出来之后,就取代了长轮询,其实原理和长轮询差不多,也是请求一个接口,然后进行协商协议升级,从 HTTP 升级到 WebSocket,服务器持有这个连接不断开,就可以一直发送消息了。相比长轮询,这个连接没有浏览器硬性的超时时间限制,并且无需断开,支持双向同时通信,无限发送消息文本或二进制数据,并且不用每次发消息都带臃肿巨大的 HTTP 协议头,可以节省很大的资源。为避免 TCP 意外断开,会要求每隔几秒发个心跳包,这个只要一两个字节就够了。
WebRTC 则更多的是面向实时视频、音频这类多媒体服务的。当然,也可以传任意文本、二进制。