协议-数据传输的艺术
前言
协议是一个很重要的概念,很多人在开发时不会去关心它,不会对它进行思考,但它是软件甚至硬件领域的一个很重要的概念。数据的传输离不开协议,开发中有大量的涉及协议这个概念,只是一些主流的协议大家都会使用,所以才不会去关系这个东西本身的一些深层次的思想,但是当你有机会去定义一套协议,你就会发现其实这个概念在我们这个领域还是比较重要的。
1. 什么是协议
简单来说,协议是一套通讯的规范,一套数据传输的约定。这样来说是不是比较容易理解。通信,或者说数据传输,离不开协议,如果没有协议,就无法进行数据传输。简单理解,我传输数据给你,我要和你定义一套规范,不然我传一串数据给你,你怎么知道是代表什么。
我们比较常见,用得比较多的就是网络通讯协议,比如http协议,都会用,洒洒水,但是你可以换位思考一下,现在http协议还没出现,后台传输数据给客户端,你要怎么拿到数据,你要设计一套规范,就比如错误吗,什么错误码表示什么错误,往更细的去思考,一串字节数组,数组的第几个到第几个要代表什么意思。这样去想,是不是觉得自己去设计一套协议的话有点小难,是不是觉得设计出http协议的人,有点东西。
2. 各种协议
上面有说,提到协议,第一反应能想到的就是网络传输协议,但是协议并不是网络传输这一层的概念,而是这个通讯层面,数据传输层面的一个概念。
所以抛开tcp、http这些我们熟悉的网络传输协议,其它地方有用到协议吗?当然有。
比如我们Android开发,比较熟悉的scheme跳转,其实也是一种协议,路由跳转,也是一种协议。
在硬件底层,我们做数据传输,会涉及到串口通讯协议,或者我们的手机,蓝牙通信协议,NFC通讯协议。这些都是数据传输之间的约定,一种规范。如果你不了解“协议”这个思想,你凭借一段时间的开发,你熟悉网络通讯协议,给http设请求头参数等操作,你玩得很6,但是这时候跳槽到一家硬件公司,这是让你做和和硬件之间的交互,你就会觉得你不懂,你要学。但是如果你理解这个概念,你心里有个底,你第一反应就是把通信协议文档给我看看,我熟悉一下,你就知道从哪个方向去入手,我不管你们数据是怎么传输的,我接你的SDK,我有协议文档,那我就能直接做
上面说了硬件的传输涉及协议,你觉得比较遥远,那我可以举例下软件,这个没关系的。夸端的数据传输,都会用到协议,比如我做Android的,我做Android游戏,我Android端要和你Cocos2d通讯,怎么做,用协议啊,这里的通讯无非指的就是两类,数据传输和事件。
我不夸端,我Android,应用层和底层的通讯,也要通过协议,应用层和底层怎么通讯,Binder嘛,都懂,Binder也充当协议的角色,我定义你怎么包装数据,怎么传输,只不过这些Android都实现了,所以我们不去关心。
H5和客户端通讯也要协议。这里我有个印象比较深的事,也是一个很好的例子,告诉你们为什么要了解“协议”这个概念。我当时入职某家公司,然后和H5对接,需求是我调他的一个方法然后传数据,很简单,因为这些代码的封装都是之前人写的,我第一反应就是按照之前的人的写法去调,然后失败了,然后我就和他说你把H5协议文档发我看看,他说“什么协议文档?你就按照之前的写法调用就行啦”,这真是让我哭笑不得,最后这个问题怎么解决的呢?两端慢慢调,他加一句打印,我出发一次,然后看看是哪里的结构有问题,最后发现说“哦,原来这个情况和之前的场景有点小不同,所以他那要改一下”。关键这个人还是那个公司那个项目的前端老大,我也不懂说什么了,从说一起调的那一刻开始,我就觉得这公司在技术层面已经输了。我现在在这公司,做H5交互,我都是按协议文档来,我都不用关注之前的人是怎么封装这一块的,我就按协议文档来写需求,没出过问题。
3. 协议使用者
上面介绍了协议,我觉得应该都能大致的了解这个概念,而且知道它在数据传输中的重要性。
那么协议的使用,又分为两类角色,一类是协议的定义者,就是定义这套协议的人,一类是协议的使用者,就是使用协议的人,我们大部分的开发中都充当这类角色,所以先说说协议的使用者。
(1)协议使用者需要关注的内容
首先协议的使用者需要关注这个协议的作用,用来做什么的,传什么数据用的。
其次协议的版本也是一个很重要的因素,我就碰到过一个厂商的协议,低版本和高版本会有比较大的差异,导致我这端是低版本,另外一端是高版本,传输的过程会出现问题。比如你觉得http1和http2一样吗?
然后在使用的时候一定要认真看协议的文档,要稍微理解这个通讯的流程,主要是能做到我们是对着文档开发的,碰到什么细节的时候你能比较清楚的找到文档中对应的地方。
需要注意的是,比较复杂的通讯过程可能会有多种通讯协议参加,比如网络通讯,每一层都有不同的协议,所以一定要清楚当前协议的作用是什么。
(2)协议定义者需要注意的细节
一般有能力定义协议的人,基本都会对这个概念有一套自己的理解。
首先比较重要的就是协议文档,每套协议都应该有套相应的协议文档对协议进行描述。就像你写SDK,也需要有套SDK文档去告诉使用者怎么使用。这里就需要再说说上面客户端与H5通信的情况。这种情况是需要一套数据传输协议去支持的,但是很多公司特别是小公司,不会有对应的协议文档,大多数都是双端互相约定一套规范,客户端调H5,“aaa/bbb/ccc/ddd” aaa表示什么,bbb表示什么...类似这样,然后这套规则没有对应的文档,而且也是只考虑某种业务场景写去设计的,最终可能会导致,有新的场景又会在这种情况下去改,或者开猿节流,把懂这个规则的人都干掉了,裁到大动脉了。新的员工在碰到这块的时候直接懵逼,“woc,这些东西是什么意思”,完全不懂,只能去猜去调试。
而且,你们公司有很多个项目组,项目A有自己的规则,项目B又有自己的规则,每个项目都是那个项目的两三个人去制定一套临时的规则。
所以如果你正巧看到这篇文章,你又正巧你们公司就是我说的情况,那你赚大了。你直接和你技术大佬说,当前双端通讯有点乱,我们应该定义一套协议,你去推动这件事情,注意,这个不是某个项目层面的,而是整个公司层面的,就得整个公司的双端通讯都用这套协议。然后你去写这个协议的文档,比如《H5通信协议》,然后署名你自己,赚麻了,这不就是为公司做额外的贡献?这不得给你绩效蹭蹭蹭往上涨。
当前定义一套协议可不是这么简单的事,还是需要有一定的积累,网络通讯协议,蓝牙通讯协议,串口通讯协议,某些厂商制定的协议,接触多了,你知道他们设计的一些细节,你才懂这块会有什么坑,而且不同场景的协议都会有些不同,你的场景更适合怎么去设计,这也是一个学问。
然后使用成本这些也是要考虑的,如果你设计的协议太复杂了,光文档都几十页,那使用者会怎么想,反正我第一反应肯定是先看看有没有其他家。
但是不管怎么设计,通信基本离不开3个概念,事件Action、状态State、数据Data
我夸端通信,我可能A端要让B端做些什么,所以我要有个Action字段给他,他收到之后才会触发对应的行为。比如http协议的GET\POST\PUT等等,就是Action。
状态State也基本是必须的,比如我可能A端想知道B端当前的状态,然后做对应的操作。比如http协议的返回码也是一种状态的表现。
数据自然不用说,通信过程基本可以说就是一个数据传输的过程,Action也是一个数据,State也是一个数据。
4. 总结
首先介绍了协议的概念,我觉得必须要让大家有个意识,就是通讯的过程、数据传输的过程基本离不开协议,而协议肯定要有对应的协议文档。当有这么一个概念之后,对任何一个通讯的过程,我觉得都能手到擒来,都能看得很通透。
其次介绍了协议的使用者和定义者两个角色,我们平时都充当使用者的角色,使用者一定要了解协议的作用,然后能根据协议文档去处理相应的需求。
而定义者就比较难了,需要有一定的积累和自身在这块领域的理解,才能定义出一份好的协议