让我们使用 docker 来运行一个完整的示例。您需要启动 3 个终端并安装 docker,但我们可以在一台主机上完成这一切。我将 3 个终端称为“域”、“沙盒”和“主机系统”。
在域终端中,启动一个新的 redhawk 2.0.2 实例:
docker run -it --name=domain axios/redhawk:2.0.2 bash -l
在沙盒终端中,启动另一个 redhawk 2.0.2 实例:
docker run -it --name=sandbox axios/redhawk:2.0.2 bash -l
如果您不熟悉 docker,这两个 docker 实例具有独特的文件系统、内存和网络。检查每个ifconfig
IP 地址并记下它们。请注意,它们位于同一子网中,并且可以相互 ping 通。
我们现在可以通过创建两个无法相互连接的新网络来模拟您的 10GigE 端口。在主机终端上,使用 docker 创建两个单独的假网络并将它们分配给您的容器实例。
docker network create -o "com.docker.network.bridge.host_binding_ipv4"="1.1.1.1" bad_net_1
docker network create -o "com.docker.network.bridge.host_binding_ipv4"="2.2.2.2" bad_net_2
docker network connect bad_net_1 domain
docker network connect bad_net_2 sandbox
回到 Domain 和 Sandbox 终端重新运行ifconfig
,请注意您现在有一个 eth0 和 eth1 接口,其中 Domain 和 Sandbox 实例上的 eth1 位于唯一的子网上并且无法通信。
您的 IP 地址可能不同,但对我来说,我有:
领域:
eth0:172.17.0.2
eth1:172.19.0.2
沙盒:
eth0:172.17.0.3
eth1:172.20.0.2
我现在将域配置为omniNames 主机,设置omniORB 连接超时,这样我们就不会挂起corba 调用,并且错误地配置endPoint 以便通告错误的IP 地址。
在域机器上:
sudo tee /etc/omniORB.cfg << EOF
InitRef = NameService=corbaname::172.17.0.2:2809
supportBootstrapAgent = 1
InitRef = EventService=corbaloc::172.17.0.2:11169/omniEvents
endPoint = giop:tcp:172.19.0.2:
serverCallTimeOutPeriod = 5000
clientConnectTimeOutPeriod = 5000
clientCallTimeOutPeriod = 5000
EOF
在沙盒机器上:
sudo tee /etc/omniORB.cfg << EOF
InitRef = NameService=corbaname::172.17.0.2:2809
supportBootstrapAgent = 1
InitRef = EventService=corbaloc::172.17.0.2:11169/omniEvents
endPoint = giop:tcp:172.20.0.2:
serverCallTimeOutPeriod = 5000
clientConnectTimeOutPeriod = 5000
clientCallTimeOutPeriod = 5000
EOF
在域机器上启动 omniNames 和事件,通过cleanomni
它们也将清除任何陈旧状态:
cleanomni
在沙盒机器上运行nameclt list
以查看 omniORB 对象。请注意,它不起作用,因为为域通告的端点地址是错误的。如果我们通过 /etc/omniORB.cfg 登录,traceLevel=40
我们甚至可以在消息中看到不正确的 IP 地址。
omniORB: inputMessage: from giop:tcp:172.17.0.2:2809 236 bytes
omniORB:
4749 4f50 0100 0101 e000 0000 0000 0000 GIOP............
0400 0000 0000 0000 0000 0000 2a00 0000 ............*...
4944 4c3a 6f6d 672e 6f72 672f 436f 734e IDL:omg.org/CosN
616d 696e 672f 4269 6e64 696e 6749 7465 aming/BindingIte
7261 746f 723a 312e 3000 0000 0100 0000 rator:1.0.......
0000 0000 9400 0000 0101 0200 0b00 0000 ................
3137 322e 3139 2e30 2e32 0000 23ae 0000 172.19.0.2..#...
0e00 0000 ff00 bb05 0a58 0100 003c 0000 .........X...<..
0002 0000 0400 0000 0000 0000 0800 0000 ................
0100 0000 0054 5441 0100 0000 1c00 0000 .....TTA........
0100 0000 0100 0100 0100 0000 0100 0105 ................
0901 0100 0100 0000 0901 0100 0300 0000 ................
1600 0000 0100 0000 0b00 0000 3137 322e ............172.
3137 2e30 2e32 0000 f90a 0000 0354 5441 17.0.2.......TTA
0800 0000 bb05 0a58 0100 003c .......X...<
在域终端上,使用 vim 或 emacs 修复 /etc/omniORB.cfg 中的端点并运行cleanomni
以清除所有旧引用并重新启动全方位服务。您现在可以从沙盒终端正确运行nameclt list
.
在域终端上使用沙盒终端启动域,nodeBooter -D
并通过 python 从沙盒终端连接到域,并确认您可以按预期与其交互。
>>> from ossie.utils import redhawk
>>> dom = redhawk.attach('REDHAWK_DEV')
>>> dom.name
'REDHAWK_DEV'
>>> fs = dom.fileManager
>>> fs.list('.')
请注意,到目前为止,我们只从沙盒向域进行调用,因此只有域机器的广告端点很重要。像“start”和“stop”这样的调用是从你到一个组件的,但像 pushPacket 这样的调用是从组件发出给你的。我们可以通过将域机器上的 SigGen 连接到沙盒机器上的 HardLimit 来确认这一点。请记住,现在域机器已正确配置,而沙盒机器未正确配置。
在域机器上,停止域并运行以下命令来安装波形并使用 GPP 启动域:
sudo yum install -y rh.basic_components_demo
nodeBooter -D -d /var/redhawk/sdr/dev/nodes/DevMgr_12ef887a9000/DeviceManager.dcd.xml
现在回到 python 中的沙箱机器:
from ossie.utils import redhawk, sb
import time
dom = redhawk.attach('REDHAWK_DEV')
app = dom.createApplication('/waveforms/rh/basic_components_demo/basic_components_demo.sad.xml')
siggen = app.comps[0]
siggen.start()
hardlimit = sb.launch('rh.HardLimit')
sink = sb.DataSink()
hardlimit.connect(sink)
siggen.connect(hardlimit)
sb.start()
time.sleep(1)
sink.getData()
您应该在接收器中没有数据,因为沙盒机器通告了错误的端点。现在退出 python 修复 Sandbox 实例上的 endPoint 并重新运行此实验。这次您获得了数据,因为两个端点都已正确配置。
最后,如果您根本不设置端点会发生什么?(正如我想象的那样)来自omniORB示例配置文件:
默认情况下,未定义端点配置。在这种情况下,ORB 将只创建 1 个 tcp 端点,就好像在配置文件中指定了行:endPoint = giop:tcp::
和
主机和端口参数是可选的。如果缺少一个或两个,ORB 将填补空白。例如,“giop:tcp::”将导致 ORB 选择一个任意的 tcp 端口作为端点,它会选择一个主机的 IP 地址作为主机地址。
所以你可能会得到非常奇怪的行为。希望这个例子对每个人都有帮助并且足够容易地运行/重现。
现在我们已经完成了,我们可以清理我们的 docker 实例和 docker 网络:
docker rm -f domain sandbox
docker network rm bad_net_1 bad_net_2