原文链接:https://www.coderutil.com/star/exp/100
webchat之所以能实现实时对话、服务端公众号实时推文效果,得益于WebSocket技术的出现、应用及能力的支持。
除IM对话产品之外,大到直播/视频网站弹幕服务、飞书/腾讯文档/语雀等在线多人文档实时协同能力……小到上传进度条、实时互动消息红点提醒等都得益于全双工通信技术Socket。有小伙这里会有疑问了:“不是在聊webscoket吗,为什么这里会提到socket,两者有啥区别与联系?”
一、要搞清身世,先了解老祖先Socket
在开始了解websocket之前,我认为大家需要先简单了解下Scoket、以及WebScoket跟它的区别与联系。
从名字上大家应该可以猜个七七八八了,显然Socket肯定出现的更早、而WebScoket是后来基于Socket的思想或技术能力被设计出来专门应用于web服务(浏览器和服务器之前通讯)的socket技术。Socket的概念最早出现在1970年,而WebSocket作为HTML5的一部分,其标准在2011年被正式确定。
Socket
"Socket"这个词来源于Unix系统,后来被广泛用于各种操作系统和编程语言中,成为描述网络通信端点的标准术语。又被称为套接字或者叫socket(套接字),套接字=Socket,Socket可以是TCP套接字,也可以是UDP套接字,分别对应不同的通信协议,其中基于TCP的套接字可以实现全双工通信。
这一段介绍中有另外一个技术名词:网络通信端点,英文描述叫Endpoint,其实就是网路通信的两个参与者,通信起点与通信终点。与之相关的还有几个概念,有必要特殊强调下,方便大家后续的理解:
网络地址,其实就是IP地址,对应webchat大家本地调试访问的127.0.0.1、localhost又或是coderutil.com(域名DNS解析后其实还是与对应一个具体的IP地址)
端口号,端口号是一个16位的数字,用于标识特定的应用程序或服务。因为一台计算机上可以运行多个网络服务,所以端口号用来区分这些服务。例如,HTTP服务通常使用端口80,而HTTPS服务使用端口443,而我们webchat自定义的端口号是8101。
端点唯一性,IP:端口号的组合确保了每个端点的唯一性。
通信过程:在网络通信中,数据包从一个端点发送到另一个端点。发送端点被称为源端点,接收端点被称为目的端点。
我们来用一张图,总结下
二、搞web 应用开发,先了解web1.0、web2.0
最近出现的web3.0,大家也应该多多稍稍有一些耳闻。但是这一小节我们不需要关注web3.0,仅了解1.0、2.0发展即可,以及技术发发展是如何催生了websocket技术的出现。
Web 1.0
Web 1.0是互联网的初始阶段,大约从1990年代到2004年。这个阶段的互联网主要是静态网页的展示,用户只能被动地查看信息,而不能进行互动。Web 1.0的网页使用HTML技术构建,用户没有交互,只有少数人创建内容。在搜索引擎出现之前,互联网的存在主要是为了宣传实体已有的东西,所有网站是“只读网站”,用户只能阅读被设定好展示的信息。
最经典的例子:早起阿里巴巴起家做的就是”中国黄页“。具体是干嘛的呢?其实就是帮助企业在互联网展示他们自家的产品信息、公司信息等,注意这里用了一个词:展示!。没错web1.0主要就是展示数据。那既然只是展示数据静态html、css足够,根本不需要websocket,甚至ajax。
web2.0
Web 2.0从2004年开始至今,这个阶段的互联网强调用户的参与和互动,催生了社交网络、博客和网络视频等新媒体形式。在Web 2.0中,用户不仅是信息的消费者,也可以成为信息的制作者和发布者。这种用户生成内容(UGC)的模式大大丰富了互联网的内容和功能。同时,Web 2.0也促进了云计算、大数据等技术的发展,使得互联网服务更加智能化和个性化。
最经典的例子:百度贴吧。用户可以自己提交帖子数据到服务端数据库、其他用户也可以主动拉取别人发布的帖子,可以给帖子点赞、评论、分享转发等数据交互式操作。
那相比于web1.0静态页,2.0的数据交互式浏览器如何支持的呢?没错,就是通过大家都非常熟悉的http请求来实现的,当然在web1.0时代html静态页面的渲染,能够显示在浏览器也是基于http实现的,不过这里我们重点讨论的是客户端(浏览器)如何把数据提交给服务端:
表单提交
在Web开发中,表单提交是一种基本的用户输入方式。用户通过填写HTML表单,将数据发送到服务器。传统的表单提交通常使用HTTP的GET或POST方法:
•GET方法:将表单数据附加到URL后面,发送到服务器。由于URL长度限制,不适合传输大量数据。
•POST方法:将表单数据放在请求体中发送到服务器,适合传输大量数据。
AJAX
AJAX(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。AJAX的主要特点包括:
•异步通信:可以在后台与服务器通信,不阻塞用户界面。
•使用XML或JSON:最初使用XML格式,后来更多使用JSON。
•基于JavaScript:通过JavaScript发起异步请求,处理响应。
•提高用户体验:通过局部更新页面,提高应用的响应性和交互性。
ps:Ajax提交数据大家一定非常熟悉,目前几乎99%的web应用数据提交都是基于ajax提交的。关于form表单提交对于一些古董级别的应用还在使用,这点如果学习过JSP的同学应该会有点印象,这是一个基础的form表单提交示例,简单了解下即可,不用花太多精力:
<!-- POST Method -->
<form action="submit_form.php" method="post">
<label for="username">Username:</label><br>
<input type="text" id="username" name="username"><br>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"><br><br>
<input type="submit" value="Submit via POST">
</form>
三、相比于主动获取数据,如何实现从被动获取服务端数据
在前面web2.0数据提交和拉取我们不论是基于form表单、还是ajax都只能实现主动获取服务端数据,什么叫主动获取?就是需要用户自己来告诉系统才能获取数据,比如刷新页面、点击按钮等。
那问题来了,如果在只有ajax的背景下,我们想要实现一个类似webchat的web服务应该如何实现?准确来说要实现用户A主动提交数据到服务端后,用户B在不操作任何主动拉取数据行为的前提下可以拿到用户A的数据?
对6~ 就是基于AJax的主动轮询拉取/加载/请求新数据来实现,思路就是A提交数据后,B浏览器客户端JS脚本没间隔几秒代替用户主动请求新数据:
通过这个例子我们可以看到在早起如果想要实现 小蓝 发送一个数据,小红想要主动或者到数据,就得多次轮训请求服务区来拉取,当时总有一次可以拿到这个数据的。但是这种实现方式最明显的两个问题:
1、这得请求多少次才能拉取到,会出现大量无效请求,这小无效请求对于服务器请求连接池、数据查询需要查询数据库等存在大量资源浪费情况。
2、间隔多久请求一次都会导致数据的获取存在延迟,如果压缩间隔时间,只会导致服务器资源更快的被消耗殆尽。
这时候有大聪明针对这两问题提出一个解决思路:long polling
long polling
即长轮训,大聪明说你不是说上面的轮训方式太高频存在服务器资源浪费问题吗,如果降低轮训频率又会导致数据拉取延迟很高的问题。那看看我这个方案呢?
longpolling最核心的思想是:当小红去请求数据的时候,如果服务端发现小蓝的数据还没有提交,就一直阻塞这个请求,知道服务端看到了小蓝提交的数据,这才返回给小红。
总结:long polling可以解决消息的延迟问题,以及确实不需要小红发起非常的查询请求,可以降低对服务端的无效资源损耗问题。但是请求一直阻塞住也不是办法,大家应该了解tomcat的http请求连接数是有上限的,如果有大量的请求一直拿不到数据阻塞,占用tomcat的连接池资源,其他正常的数据请求依然会存在进不来的问题。
这个时候就有人提出来一个思想:服务端主动推送技术
四、服务端主动推送技术
接着前面ajax以及long polling请求存在的问题,有人提出服务端主动推送技术:当服务端发现有客户端需要某个新数据的时候,可以由服务端主动将数据推送给客户端,一次来提升数据的实时性、以及降低客户端http无效请求。
服务端要主动推送给客户端就需要客户端与服务端直接有一个长期存在的管道,这样不管是客户端还是服务端就可以通过这个长期建立得到管道来实现数据的传输,你可以随时给我数据,我也可以随时给你数据,也就是在之前文章中多次提到的全双工通信机制。
到这里,我们才引出今天的主角:WebSocket
其实在websocket出现之前还是有其他的集中实现方式,但是已经很边缘了,我认为大家页没必要去了解其他的了。服务端推送目前最常用的其实就是websocket、还有SSE,SSE我们在webchat机器人实现部分会给大家在单独做分享,这里也不需要特殊关注。
ok,我们回到websocket,在第一小节我们介绍了websocket的老祖先socket,这要描述可能不是特别准确,因为他两实际上并没有特别紧密的关系,但是呢,websocket的实现和出现确实是参考了socket的方案。
那有小伙伴会问TCP socket既然是做两个端点直接的全双工通讯的,是不是也可以实现。答案是:确实可以的!又有小伙伴会问:那既然如此为啥还需要websocket?
首先webscoket的出现是专门来解决浏览器和服务器之前全双工通讯的手段和技术,自然是针对浏览器这一客户端有特定的优化手动来提升通行的性能、实时性、稳定性以及被套的api等,简单总结如下:
实时性更高:WebSocket技术可以实现实时通信,传输数据的延迟更低,可以更快地将数据传输到客户端。这对于需要即时响应的应用场景(如在线聊天、实时游戏等)非常重要。
减少网络带宽的使用:WebSocket技术可以在服务器和客户端之间建立一个持久化的连接,减少了HTTP协议中每次请求和响应所需要的网络带宽。这意味着在WebSocket连接建立之后,数据交换不需要重复的HTTP头部信息,从而减少了数据传输量。
全双工通信:WebSocket技术可以实现全双工通信,即客户端和服务器可以同时发送和接收数据。这一点与Socket技术中的TCP连接类似,但WebSocket特别适用于Web环境。
减少资源消耗:由于WebSocket保持持久连接,它减少了服务器上因频繁建立和关闭连接而产生的资源消耗。
推送功能:WebSocket支持服务器端向客户端推送功能,服务器可以直接发送数据而不用等待客户端的请求。这在需要服务器主动更新客户端信息的场景中非常有用,如股票行情更新或实时通知。
跨域支持:WebSocket技术支持跨域通信,可以在不同的域之间进行通信。
安全性更高:WebSocket技术可以通过SSL/TLS协议实现加密通信,保证数据传输的安全性。
API易用性:WebSocket是一个完整的应用层协议,包含一套标准的API,使得开发者在使用上更为方便。
适用于Web环境:WebSocket API是HTML5标准的一部分,虽然WebSocket不仅限于HTML中使用,但它与Web技术的紧密结合使得在Web应用中实现实时通信变得更加简单。
总结:WebSocket技术的出现是为了解决传统HTTP通信在实时性、效率和资源消耗方面的问题,特别是在需要高实时性和低延迟的Web应用场景中。而Socket技术虽然功能强大且灵活,但在某些场景下可能不如WebSocket高效和便捷。因此,WebSocket技术是对Socket技术的补充,而不是替代。
总结
本篇文章我们先通过webchat、直播弹幕、在线协同文档等产品能力引出socket、分享介绍了scoket的相关知识、以及在浏览器web1.0、web2.0背景下数据交互方式引出Ajax、Form表单提交等技术发展过程,再到最后因为实时性数据获取的需求介绍了早起轮训、longpolling方式存在的问题,最终引出了websocket出现的必要性以及跟scoket相比有哪些优势和特性。