CERL2 系列5:SDL与我对网络协议的思考

40 篇文章 0 订阅
18 篇文章 0 订阅

网络编程中,网络协议是最最关键的角色。这就像我在客户端编程的时候,最关心模块接口一样。网络协议是客户端(B或C)与服务端(S)之间的交互接口。

 

我关注网络协议的时候,和很多人关注的面是不同的。不少人问我,你喜欢用Soap,REST,还是喜欢自己定义网络协议?喜欢用XML,还是json?从某种意义上来说,我不关心这些。对我来说,这些只是网络协议的载体。

 

提到网络协议,我们应该意识到,这里面其实有两个层面的意思:

  1. 协议的载体。也就是具体使用的协议编码方式。是用Soap,REST,还是自定义的?
  2. 协议自身的逻辑。

多数情况下,我更关注的其实是后者。如何以最清晰的方式表达逻辑?我的答案是:SDL。

 

SDL 是一门用于描述服务器接口的DSL(领域专用语言)。在前文,我介绍了《CERL SDL 语法及类型系统》。并且我说:SDL 语言是我认为CERL库中最重要的成就。

 

我们为什么需要用一个 DSL?这涉及到我对信息表示的朴素看法:越通用的信息表示手段,在表示信息的时候越冗长。举几个例子:

 

例子1: 对于算式:a + b * c;如果我们用xml表示,那么它可能是这样的:

 

<add>
   <var name="a"/>
   <mul>
      <var name="b"/>
      <var name="c"/>
   </mul>
</add>

 

例子2: 对于函数: func(Int32 a, String b) -> {ok, String val} | {error, Int32 reason}; 如果我们用xml表示,又将需要如何表示呢?(很冗长,这里略过)

 

所以,对于任何一个专业领域,引入 DSL 来解决信息表示的复杂度问题,是很自然的一件事情。我花这么长的篇幅描述这件事情,是因为我发现有些人对xml或者json太崇拜了,以至于忘了自己究竟是为了什么而用xml/json。

 

我们说 SDL 是描述服务器接口的一门 DSL,但这句话还没有完全描述清楚它的定位。

 

理解 SDL 的另一个关键点,在于清楚一件事情:SDL 并非是一个完整的网络协议。前面我们说到网络协议有两个层面:协议载体与协议的逻辑。SDL 关注的仅仅是协议逻辑。

 

所以,同一个 SDL,会有很多个编译器,以生成不同编程模型,不同网络协议下的客户端和服务器框架代码。

 

举个例子。我们用 SDL 写了一个服务器:

 

server HashServer
{
   [id=1] put(String key, String val) -> ok;
   [id=2] get(String key) -> {ok, String val} | false;
}

 

如果我们用 venus 这个模型实现该服务器,那么用 venusc 这个编译器来编译生成客户端调用代码和服务器框架。如果我们用 mars 这个模型实现该服务器,那么用 marsc 编译它。

 

如果协议要改用 soap 呢?这时候则不是由 soapc 这样的编译器来编译。而是提供一个 venus2soap 或者 mars2soap 这样的适配性质的编译器来编译它。

 

也就是说,在 CERL2 中,我们的服务器编程模型只有 venus 和 mars。而 soap 是网络协议,并非一种编程模型。我们可以用 venus 模型来实现,也可以用 mars 模型来实现。

 

最后一句话总结:venus 和 mars 是编程模型,并非协议(注解:不过 venusc 或者 marsc 确实生成了一个自定义的网络协议,但那不是必须的。如果我们用 venus2soap,那么表示编程模型用 venus,网络协议用 soap)。

 

 

评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值