Asynchronous 异步Vala示例
在Michael Lauer博士的《Vala简介》一书中,他提到lib-Soup异步api已被破坏。我正在努力使用Asynchronous 异步Vala示例,asynchronous,vala,libsoup,Asynchronous,Vala,Libsoup,在Michael Lauer博士的《Vala简介》一书中,他提到lib-Soup异步api已被破坏。我正在努力使用session.queue\u message编写一个简单的示例,该示例用于查询使用该服务的无线电台。这是我的密码。我非常感谢像“Al Thomas”这样有经验的程序员提供的任何帮助。多谢各位 public class Station : Object { // A globally unique identifier for the change of the stati
session.queue\u message
编写一个简单的示例,该示例用于查询使用该服务的无线电台。这是我的密码。我非常感谢像“Al Thomas”这样有经验的程序员提供的任何帮助。多谢各位
public class Station : Object {
// A globally unique identifier for the change of the station information
public string changeuuid { get; set; default = ""; }
// A globally unique identifier for the station
public string stationuuid { get; set; default = ""; }
// The name of the station
public string name { get; set; default = ""; }
// The stream URL provided by the user
public string url { get; set; default = ""; }
// and so on ... many properties
public string to_string () {
var builder = new StringBuilder ();
builder.append_printf ("\nchangeuuid = %s\n", changeuuid);
builder.append_printf ("stationuuid = %s\n", stationuuid);
builder.append_printf ("name = %s\n", name);
builder.append_printf ("url = %s\n", url);
return (owned) builder.str;
}
}
public class RadioBrowser : Object {
private static Soup.Session session;
// private static MainLoop main_loop;
public const string API_URL = "https://de1.api.radio-browser.info/json/stations";
public const string USER_AGENT = "github.aeldemery.radiolibrary";
public RadioBrowser (string user_agent = USER_AGENT, uint timeout = 50)
requires (timeout > 0)
{
Intl.setlocale ();
session = new Soup.Session ();
session.timeout = timeout;
session.user_agent = user_agent;
session.use_thread_context = true;
// main_loop = new MainLoop ();
}
private void check_response_status (Soup.Message msg) {
if (msg.status_code != 200) {
var str = "Error: Status message error %s.".printf (msg.reason_phrase);
error (str);
}
}
public Gee.ArrayList<Station> listStations () {
var stations = new Gee.ArrayList<Station> ();
var data_list = Datalist<string> ();
data_list.set_data ("limit", "100");
var parser = new Json.Parser ();
parser.array_element.connect ((pars, array, index) => {
var station = Json.gobject_deserialize (typeof (Station), array.get_element (index)) as Station;
assert_nonnull (station);
stations.add (station);
});
var msg = Soup.Form.request_new_from_datalist (
"POST",
API_URL,
data_list
);
// send_message works but not queue_message
// session.send_message (msg);
session.queue_message (msg, (sess, mess) => {
check_response_status (msg);
try {
parser.load_from_data ((string) msg.response_body.flatten ().data);
} catch (Error e) {
error ("Failed to parse data, error:" + e.message);
}
});
return stations;
}
}
int main (string[] args) {
var radio_browser = new RadioBrowser ();
var stations = radio_browser.listStations ();
assert_nonnull (stations);
foreach (var station in stations) {
print (station.to_string ());
}
return 0;
}
公共类站:对象{
//用于更改站点信息的全局唯一标识符
公共字符串changeuuid{get;set;default=”“;}
//站点的全局唯一标识符
公共字符串StationUID{get;set;default=”“;}
//车站的名称
公共字符串名称{get;set;default=”“;}
//用户提供的流URL
公共字符串url{get;set;default=”“;}
//等等…许多属性
公共字符串到_字符串(){
var builder=newstringbuilder();
builder.append\u printf(“\nchangeuuid=%s\n”,changeuuid);
builder.append\u printf(“stationuid=%s\n”,stationuid);
builder.append\u printf(“name=%s\n”,name);
builder.append\u printf(“url=%s\n”,url);
返回(拥有)builder.str;
}
}
公共类RadioBrowser:对象{
私有静态会话;
//专用静态主回路主回路;
公共常量字符串API_URL=”https://de1.api.radio-browser.info/json/stations";
public const string USER_AGENT=“github.aeldemery.radiolibrary”;
公共无线浏览器(字符串user\u agent=user\u agent,uint timeout=50)
需要(超时>0)
{
Intl.setlocale();
session=newsoup.session();
session.timeout=超时;
session.user\u agent=user\u agent;
session.use\u thread\u context=true;
//main_loop=新的MainLoop();
}
私有无效检查\响应\状态(Soup.Message msg){
如果(msg.status_code!=200){
var str=“Error:状态消息错误%s.”。printf(msg.reason\u短语);
错误(str);
}
}
公共Gee.ArrayList列表站(){
var stations=new Gee.ArrayList();
var data_list=Datalist();
数据列表。设置数据(“限制”、“100”);
var parser=newjson.parser();
parser.array_element.connect((PAR、数组、索引)=>{
var station=Json.gobject_反序列化(typeof(station)、array.get_元素(index))作为station;
断言非空(站);
stations.add(station);
});
var msg=Soup.Form.request\u new\u from\u datalist(
“职位”,
API_URL,
数据表
);
//发送消息有效,但队列消息无效
//session.send_消息(msg);
session.queue_消息(msg,(sess,mess)=>{
检查\u响应\u状态(msg);
试一试{
parser.load_from_data((string)msg.response_body.flatte().data);
}捕获(错误e){
错误(“分析数据失败,错误:+e.message”);
}
});
返回站;
}
}
int main(字符串[]args){
var radio_browser=新的RadioBrowser();
var stations=radio_browser.listStations();
断言非空(站);
foreach(变电站中的var站){
打印(station.to_字符串());
}
返回0;
}
虽然我不是艾尔·托马斯,但我还是可以帮上忙的
要使异步调用在其中工作,需要运行一个主循环,通常是从主程序线程运行。因此,您希望从main()
函数创建并执行主循环,而不是在应用程序代码中:
int main (string[] args) {
var loop = new GLib.MainLoop ();
var radio_browser = new RadioBrowser ();
// set up async calls here
// then set the main loop running as the last thing
loop.run();
}
此外,如果要等待异步调用完成,通常需要使用另一个异步函数的yield
关键字进行调用,例如:
public async Gee.ArrayList<Station> listStations () {
…
// When this call is made, execution of listStations() will be
// suspended until the soup response is received
yield session.send_async(msg);
// Execution then resumes normally
check_response_status (msg);
parser.load_from_data ((string) msg.response_body.flatten ().data);
…
return stations;
}
作为进一步阅读,我建议您阅读Vala教程的部分,以及wiki上的。非常感谢。虽然我注意到lamda外的站点不可见,因此所有循环站点必须位于listStations.begin内。是的,这是正确的,您希望在调用主循环退出之前,在
…
指示的位置执行此操作。
int main (string[] args) {
var loop = new GLib.MainLoop ();
var radio_browser = new RadioBrowser ();
radio_browser.listStations.begin((obj, res) => {
var stations = radio_browser.listStations.end(res);
…
loop.quit();
});
loop.run();
}