为什么 Gio.Socket.create_source() 返回 null?
Why is Gio.Socket.create_source() returning null?
我是套接字的新手,试图在 GJS/Gio 中完成一些套接字编程,但遇到了创建 GLib.Source 来处理从套接字接收的问题。相关代码(我认为)是:
const DeviceChannel = new Lang.Class({
Name: "DeviceChannel",
_init: function (device) {
this.device = device;
this.connection = null;
this.inStream = null;
this.outStream = null;
this.socket = null;
this.sock_source = 0;
},
open: function () {
let client = new Gio.SocketClient();
this.addr = new Gio.InetSocketAddress({
address: this.device.tcpHost,
port: this.device.tcpPort
});
let conn = client.connect_async(
this.addr,
null,
Lang.bind(this, this.opened)
);
},
opened: function (client, res) {
this.connection = client.connect_finish(res);
// Streams
this.inStream = new Gio.DataInputStream({
base_stream: this.connection.get_input_stream()
});
this.outStream = new Gio.DataOutputStream({
base_stream: this.connection.get_output_stream()
});
// Socket
this.socket = this.connection.get_socket();
this.socket.set_option(6, 4, 10); // TCP_KEEPIDLE
this.socket.set_option(6, 5, 5); // TCP_KEEPINTVL
this.socket.set_option(6, 6, 3); // TCP_KEEPCNT
this.socket.set_keepalive(true);
this.sock_source = this.socket.create_source(GLib.IOCondition.IN, null);
this.sock_source.set_callback(Lang.bind(this, this._io_ready));
this.sock_source.attach(null);
},
_io_ready: function (condition) {
return true;
}
});
一切顺利,直到我调用 this.sock_source.set_callback()
时出现错误:
(JSConnect:15118): Gjs-WARNING **: JS ERROR: TypeError: this.sock_source is null
DeviceChannel<.opened@application.js:184:9
wrapper@resource:///org/gnome/gjs/modules/lang.js:178:22
@application.js:427:2
我在代码的另一部分调用了另一个套接字(尽管是 UDP)上的 Gio.Socket.create_source()
,它工作正常。调用 create_source()
本身不会抛出任何错误(即使我 运行 我的脚本使用 G_MESSAGES_DEBUG=all
)并且没有提到函数返回 null
in the documentation 所以我对我做错了什么感到困惑。
编辑:
有 3 年前的评论 here 指出:
This does not work since 1) Socket.create_source doesn't exist in
typelib as it is marked
with (skip) in Glib/gio/gsocket.c
但我假设这不再是真的,因为我已经在我的 UDP 套接字上创建了一个源,尽管那个套接字 "hand-made" 不是使用 Gio.SocketClient()
.
您可能无意中调用了 Gio.DatagramBased.create_source()
method. Looking at the source code, this will call g_socket_create_source()
eventually, but does some checks first and returns null
if those fail. Here are the checks: https://github.com/GNOME/glib/blob/master/gio/gsocket.c#L1114
看起来 the method will simply return null
甚至没有打印 check_datagram_based()
中的错误的小错误。
我是套接字的新手,试图在 GJS/Gio 中完成一些套接字编程,但遇到了创建 GLib.Source 来处理从套接字接收的问题。相关代码(我认为)是:
const DeviceChannel = new Lang.Class({
Name: "DeviceChannel",
_init: function (device) {
this.device = device;
this.connection = null;
this.inStream = null;
this.outStream = null;
this.socket = null;
this.sock_source = 0;
},
open: function () {
let client = new Gio.SocketClient();
this.addr = new Gio.InetSocketAddress({
address: this.device.tcpHost,
port: this.device.tcpPort
});
let conn = client.connect_async(
this.addr,
null,
Lang.bind(this, this.opened)
);
},
opened: function (client, res) {
this.connection = client.connect_finish(res);
// Streams
this.inStream = new Gio.DataInputStream({
base_stream: this.connection.get_input_stream()
});
this.outStream = new Gio.DataOutputStream({
base_stream: this.connection.get_output_stream()
});
// Socket
this.socket = this.connection.get_socket();
this.socket.set_option(6, 4, 10); // TCP_KEEPIDLE
this.socket.set_option(6, 5, 5); // TCP_KEEPINTVL
this.socket.set_option(6, 6, 3); // TCP_KEEPCNT
this.socket.set_keepalive(true);
this.sock_source = this.socket.create_source(GLib.IOCondition.IN, null);
this.sock_source.set_callback(Lang.bind(this, this._io_ready));
this.sock_source.attach(null);
},
_io_ready: function (condition) {
return true;
}
});
一切顺利,直到我调用 this.sock_source.set_callback()
时出现错误:
(JSConnect:15118): Gjs-WARNING **: JS ERROR: TypeError: this.sock_source is null
DeviceChannel<.opened@application.js:184:9
wrapper@resource:///org/gnome/gjs/modules/lang.js:178:22
@application.js:427:2
我在代码的另一部分调用了另一个套接字(尽管是 UDP)上的 Gio.Socket.create_source()
,它工作正常。调用 create_source()
本身不会抛出任何错误(即使我 运行 我的脚本使用 G_MESSAGES_DEBUG=all
)并且没有提到函数返回 null
in the documentation 所以我对我做错了什么感到困惑。
编辑:
有 3 年前的评论 here 指出:
This does not work since 1) Socket.create_source doesn't exist in typelib as it is marked with (skip) in Glib/gio/gsocket.c
但我假设这不再是真的,因为我已经在我的 UDP 套接字上创建了一个源,尽管那个套接字 "hand-made" 不是使用 Gio.SocketClient()
.
您可能无意中调用了 Gio.DatagramBased.create_source()
method. Looking at the source code, this will call g_socket_create_source()
eventually, but does some checks first and returns null
if those fail. Here are the checks: https://github.com/GNOME/glib/blob/master/gio/gsocket.c#L1114
看起来 the method will simply return null
甚至没有打印 check_datagram_based()
中的错误的小错误。