大部分代码是借来的,JS不是我的方式,但需要创建一个扩展。
你能告诉我如何使用g_resolver_lookup_by_name()
返回IP在给定的代码?
g-resolver-lookup-by-name
const Main = imports.ui.main;
const St = imports.gi.St;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Me = imports.misc.extensionUtils.getCurrentExtension();
let myPopup;
const MyPopup = GObject.registerClass(
class MyPopup extends PanelMenu.Button {
_init () {
super._init(0);
...
this.menu.addMenuItem(
new PopupMenu.PopupMenuItem(
"Some : ", // IP is required to be returned
{reactive : false},
)
);
}
});
...
Gio.Resolver.lookup_by_name('google.com')
- TypeError: Gio.Resolver。Lookup_by_name不是一个函数
你试图调用一个方法,虽然它是静态的,但你首先需要得到默认的解析器:
const Gio = imports.gi.Gio;
// The default resolver
const resolver = Gio.Resolver.get_default();
查找名称肯定会阻塞I/O,因此在Shell扩展中使用异步变体是必要的。一个承诺包装器可能是最好的:
function lookupName(host, cancellable = null) {
return new Promise((resolve, reject) => {
resolver.lookup_by_name_async(host, cancellable, (obj, res) => {
try {
resolve(resolver.lookup_by_name_finish(res));
} catch (e) {
reject(e);
}
});
});
}
当然,正如文档所说,这将返回Gio.InetAddress
对象的列表,您必须调用to_string()
以获得可读地址。
再加上上面的答案:您实际上不再需要实现承诺包装器了。GJS有一个内置函数来让异步方法返回一个promise。
在扩展中,可以确定与主机名匹配的地址,如下所示:
- 使
lookup_by_name_async
方法返回Promise
Gio._promisify(Gio.Resolver.prototype, 'lookup_by_name_async', 'lookup_by_name_finish');
- 在扩展中初始化解析器(可能在
enable()
函数期间的某个地方)。
const resolver = Gio.Resolver.get_default();
- 定义一个async函数来查找与主机名匹配的地址,并将它们作为字符串数组返回
async function lookupHostName(resolver, hostname, cancellable=null){
let inetAddressList = await resolver.lookup_by_name_async(hostname, null);
let addressesAsStrings = inetAddressList.map(address => address.to_string());
return addressesAsStrings;
}
- 在你需要的地方调用你的函数,并使用地址
lookupHostName(resolver, "localhost").then(ipAddresses => {
log(JSON.stringify(ipAddresses));
});
在日志中,您应该看到如下内容:
["::1","127.0.0.1"]