Day21 用更高阶的网路框架实现更多功能

上一回介绍过 CC: Tweaked Wired Modem 和 Wireless Modem 的网路功能
事实上,这在 CC: Tweaked 里头是比较低阶的网路实作
弹性比较大,但功能比较少

CC: Tweaked 其实已经帮我们包装好这些底层实作,另提供一个较高阶的网路 API: rednet
透过 rednet API 除了可以实现电脑之间传讯的基本功能之外
还有一些进阶功能,包括广播、无限长度传输、讯息分类与过滤、限时传送、主机定义
而且撰写 rednet API 的程序码,也比直接用底层 peripheral/modem API 来得少
以下我是直接阅读 /rom/apis/rednet.lua 後,以底层的 peripheral API 来解释,总结 rednet API 的用途

为了避免解释复杂,我先总结两个共通特性:

  1. rednet 预设都是以目前电脑 id 当作通讯 channel,也就是上一回我讲的 modem 的 senderChannel
  2. rednet 定义 broadcast channel 编号为 65535, repeat channel 为 65533

全部 rednet API 的底层实作如下:

  • rednet.open( side )
    寻找 side 方向的数据机,并 open id channel,同时 open broadcast channel
  • rednet.close( [side] )
    关闭 side 方向的数据机的 id channel 和 broadcast channel。如果不给参数,就关闭所有 modem 的 channel
  • rednet.isOpen( [side] )
    判断 side 方向的数据机是否有开启 id channel 和 broadcast channel。如果不给参数,就判断是否有任何数据机是 open,只要有一个数据机是 open 就回传 true
  • rednet.send( receiverID, message, [protocol] )
    透过所有打开的数据机,传送讯息给 receiverID(接收端电脑 id),而 replyChannel 则是目前电脑 id,同时也会传送到 repeat channel
    而传送的讯息会是一个 table 结构如下
    {
        nMessageID = nMessageID,  -- 乱数
        nRecipient = nRecipient,  -- receiverID
        message = message,        -- 真正的讯息内容
        sProtocol = sProtocol,    -- 过滤分类用的字串
    }
    
  • rednet.broadcast( message, [protocol] )
    广播讯息,其作用等同於
    send(CHANNEL_BROADCAST, message, sProtocol)
  • rednet.receive( [protocol], [timeout] ) -- Returns: senderID, message, protocol
    根据 protocol 或是 timeout 接收讯息,有四种接收讯息的方式
    1. rednet.receive() 无限时间接收任何讯息
    2. rednet.receive(protocol) 无限时间,只接收属於 protocol 类的讯息 (protocol 不为数字)
    3. rednet.receive(timeout) 在 timeout 时限内,接受任何讯息
    4. rednet.receive(protocol, timeout) 在 timeout 时限内,只接受属於 protocol 类的讯息
  • rednet.host( protocol, hostname )
    这是方便玩家分类、定义主机类型与名称,架设你在麦块世界里面搞个云端平台,那真的要好好分类才是 XD
  • rednet.unhost( protocol )
    搭配 host 来管理主机
  • rednet.lookup( protocol, [hostname] ) -- Returns: ID
    方便玩家寻找特定 protocol, hostname 的电脑 id。这样有个好处是管理庞大的主机群,并且在取得 id 之後,都用 rednet.send() 通讯即可,不要每次都 broadcast 浪费网路资源。这跟现实的网路世界实在很像 XD

CC: Tweaked Rednet 的无限距离传输

介绍过 Rednet API 的大概实作後,来实际 demo 吧,我们来解决上一回的问题:Wireless Modem 的最远传输距离是 64 格方块。
无限距离传输超级简单,CC: Tweaked 也包装好工具了
架设你想要传输 A -> E 中间大约距离 240 格方块,那麽只要在这中间大约每隔 60 方块距离放置一台电脑,各自安装一台 Wireless Modem,开机後直接执行 repeat,之後就不用管了
示意如下,要执行 repeat 的有 B, C, D 电脑
A (60方块)-> B (60方块)-> C (60方块)-> D (60方块)-> E

repeat 就是 /rom/programs/rednet/repeat.lua
它做的事情就是一直不断接收 Repeat channel 的讯息并转发,所以理论上,只要你肯大约每隔 60 方块就放置一台电脑做 repeat,传输可以无限远

要测试的话,其实也不用急着写 code
还记得 CC: Tweaked 有个互动式的 Lua 环境可以用吗?
输入 lua 即可,程序在 /rom/programs/lua.lua
首先要到遥远的接收端开启 rednet 并持续接收讯息

rednet.open("top")  -- 假设你数据机是放在上方
rednet.receive()    -- 不限制 protocol,不限时间接收讯息

接着回到传送端电脑

rednet.open("top")  -- 假设你数据机是放在上方
rednet.send(19, "I love moon")  -- 你必须先知道接收端电脑的 id
rednet.broadcast("I love moon") -- 不知道 id 就先用 broadcast 试试

接收端的画面收到讯息如下
CC: Tweaked Rednet Receive

中间作为中继站的电脑,画面如下
CC: Tweaked Rednet Repeat

最後,实际感受一下到底传了多远(远目...
CC: Tweaked Rednet Repeat

今天就介绍到这里,至於 protocol, hostname, timeout 的设计,真的就看玩家自己怎麽应用了
你也可以试试~


<<:  D-09 资料库存取 ? Dapper

>>:  [Day 21] 阿嬷都看得懂的满版横幅怎麽写与 normalize.css

ASP.NET MVC 从入门到放弃 (Day3) -C#变数型态介绍

接下来讲讲变数基本型态介绍如下 Short短整数:-32,768 至 32,767 int整数:-2...

企划实现(7)

立案流程 第一步: 到公司网查询是否有同名的公司,输入 1-5 个想要设立的公司名称,确认公司名称是...

Day19:19 - 结帐服务(3) - PayPal Python Checkout SDK(1)

Sveiki,我是Charlie! 在Day18我们讲到了结帐的前端,而今天我们将进入Paypal金...

纯手工打造UART版资料清洗工具之 PySide2 GUI 大补帖 - Part B

从七月开始从零开始研究PySide2 GUI相关设计及程序如何撰写,已经有一段时间了,笔者深深有感,...

[教学] ASP NET Core将HighChart图片插入到Word中并提供下载

大家好,我是一名菜鸟工程师,这篇文章用来记录我工作遇到的需求及解决方式,如果有更好的解决方式,也欢迎...