"服务器"上的存根是什么?"骨架"又是什么意思?

25

stub在服务器端有什么作用?skeleton是什么?

From Wikipedia

这是维基百科上的一个图示。我已经在服务器机器和客户端机器上都安装了stub。我知道stub能够帮助客户端进行网络连接,但是在服务器端stub有什么作用呢?

另外,在上面的图中,skeleton是什么意思?

7个回答

24

请看下面的图片:

skeleton

简单来说,stubskeleton是Web服务安装中的对应关系。 Skeleton归属于服务提供方stub则归属于接收方。在较低层次上,stub和skeleton相互通信。

从客户端的角度来看,业务对象与 stub 对象进行交流,而 stub 负责消息,并调用 Web 服务。一旦调用完成,在服务提供商方面,skeleton 是 stub 的并行对象,它接收请求消息并理解它,并将信息传递给服务端的业务对象。


8

服务器上的存根被称为骨架吗?与客户端机器上的相同存根吗? - program-o-steve
1
Skeleton只是服务器端的一个存根。我想是这样的。自从我在大学使用RMI以来已经很长时间了... :) - Matjaz Muhic
它与客户端机器上的存根有何不同? - program-o-steve
4
区别就是我在答案中所描述的:Stub负责将调用Java对象的操作进行编组(转换)为网络级别的"调用",而Skeleton则反过来,将网络级别的"调用"解组(转换回)为Java类调用。 - Matjaz Muhic
1
当我在服务器和客户端上保留相同的 .class 文件时,它们会有什么不同的表现?你能解释一下吗? - program-o-steve
骨架负责将调用分派到实际的远程对象实现。如果这是真的,那么骨架是服务器端的,而存根是客户端的。这样骨架就可以接收客户端的调用(将序列化对象转换为真实对象)。 - Raja Nagendra Kumar

7

首先,您需要忘记骨架。自1998年以来,它们已经过时。

存根是远程对象在导出时创建的。然后,它要么绑定到注册表并通过查找获得客户端,要么作为另一个远程方法的结果直接返回给客户端。

然后,客户端使用存根作为相关远程接口的实现,执行RMI的网络部分,并与服务器JVM交互,最终调用客户端在存根中调用的相同方法在远程对象中调用。


6
理解“存根”和“骨架”的关键是理解“编组”的概念:(Marshalling) rmiregistry只是一个查找设施,没有其他功能。当服务器执行bind()时,它会向rmiregistry“注册”自己。当客户端执行lookup()时,它会检查在服务器上注册了什么。没有更多,也没有更少。
我认为争论“骨架”等术语并没有意义。如果您愿意,可以将所有内容称为“存根”。关键是两者都是代理,都进行编组,一侧存在于客户端(客户端调用),另一侧存在于服务器上(骨架调用实际服务器代码)。
希望我的解释和示例对您的另一个链接有所帮助(至少有一点)。

3

远程对象的桩充当客户端本地代表或远程对象的代理。桩隐藏了参数的序列化和网络级通信,以向调用者呈现简单的调用机制。

或者,考虑在一台计算机上运行的程序:每个方法都是一个分支。当您将方法移动到远程计算机时,您切断了该分支,留下了仅包含通信的桩。
源代码

enter image description here


骨架

在远程JVM中,每个远程对象都可能有一个相应的骨架。骨架负责将调用分派到实际的远程对象实现。

我认为骨架是第一个实现 - 它满足调用约定,执行部分操作并顺利完成。

来自Oracle的表单


骨架代码不是虚拟代码,它们都不是伪代码。 - user207421

3

存根: 存根是一个小程序例程,用于代替可能稍后加载或位于远程位置的更长的程序。

骨架: 用于远程对象的骨架是一个服务器端实体,可以将调用分派到实际的远程对象实现。


1
我只回答为什么存根需要在服务器端和客户端都存在的问题。其他问题已经得到回答。
当导出的远程对象作为方法参数或返回值传递给远程对象时,会发生以下情况。在服务器机器上创建一个存根,然后将其序列化,通过网络发送到客户机器,并在那里反序列化以创建存根的相同副本。此后,在服务器机器上不再需要该存根。
以下是典型的场景。
在服务器机器S上,创建并导出一个对象s。 导出的一部分是为s创建一个存根;称之为ss0。 机器S执行Naming.bind,并将s作为参数。 服务器端存根ss0被序列化并发送到注册表的机器R。 使用ss0的序列化版本在R上创建ss1的副本。 注册表在R上保留对ss1的引用。
服务器端使用存根的一个用途是将其序列化并将其副本发送到其他计算机,例如作为绑定的一部分。类似地,当客户端进行查找时,注册表会将其副本(ss1)序列化并将其发送给客户端。

存根在远程对象导出时创建,而不是每次用作参数或返回值时都创建。因此,您的要点也是无序的。 "之后,在客户端机器上不再需要存根" 也是不正确的,当您还谈论参数和返回值时,使用 "服务器" 和 "客户端" 只会令人困惑。 - user207421
注册表不保留任何指针,只保留存根。您在定义之前提到了 ss1,但是所有关于 ss0/1/2 的讨论都是无意义的。它们都是同一个存根的副本,就像“ss0 的序列化版本”一样。没有必要将“服务器端存根”和副本视为不同的东西进行讨论。它们都只是“存根”。 - user207421
ss2 是一个打字错误。已经修复。谢谢。如果你不喜欢“指针”这个词,那就用“引用”。不同虚拟机中的存根是不同的对象。它们可能代表相同的东西,但它们是不同的对象。OP 想知道为什么服务器的 VM 上有一个存根对象。这就是我要解释的内容。目前得到最多赞的两个答案(aMooly 和 Matjaz)没有回答这个问题的这一部分。 - Theodore Norvell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接