问题描述
大部分代码是借用的,JS不是我的方式,但是需要创建一个扩展。
你能告诉我如何使用 g_resolver_lookup_by_name()
在给定的代码中返回 IP 吗?
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')
- 类型错误: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 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"]