【问题标题】:How to cache DNS in libsoup in Vala?如何在 Vala 的 libsoup 中缓存 DNS?
【发布时间】:2014-12-06 12:24:32
【问题描述】:

我在我的 Vala 应用程序中使用 libsoup 从 Instagram API 获取数据。但是从中加载一个页面大约需要 10 秒(而浏览器在大约 1-2 秒内显示相同的页面)。我最初认为这是因为 HTTPS(HTTPS 页面加载的时间比 HTTP 页面长),但我发现大多数情况下它可以解决我的问题。

所以,问题是:有什么方法可以缓存 DNS 结果以在每次需要连接主机时不解析主机?或者有可能吗?

这是我正在使用的功能:

public string getResponse (string host) 
{
    var session = new Soup.Session ();
    session.ssl_strict = false;
    session.user_agent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36";

    var message = new Soup.Message ("GET", host);
    message.tls_errors = GLib.TlsCertificateFlags.VALIDATE_ALL;
    message.network_event.connect((event) => {
        if (event == SocketClientEvent.RESOLVING) print("RESOLVING\n");
        if (event == SocketClientEvent.RESOLVED) print("RESOLVED\n");
        if (event == SocketClientEvent.CONNECTING) print("CONNECTING\n");
        if (event == SocketClientEvent.CONNECTED) print("CONNECTED\n");
        if (event == SocketClientEvent.PROXY_NEGOTIATING) print("PROXY_NEGOTIATING\n");
        if (event == SocketClientEvent.PROXY_NEGOTIATED) print("PROXY_NEGOTIATED\n");
        if (event == SocketClientEvent.TLS_HANDSHAKING ) print("TLS_HANDSHAKING \n");
        if (event == SocketClientEvent.TLS_HANDSHAKED) print("TLS_HANDSHAKED\n");
        if (event == SocketClientEvent.COMPLETE) print("COMPLETE\n");
    });

    print("start sending\n");
    session.send_message (message);
    print("stop sending\n");
    return (string) message.response_body.data;
}

而且加载的大部分时间都在“RESOLVING”和“RESOLVED”之间。

顺便说一句,我认为在 GSettings 中设置一些字段来存储 Instagram API 服务器 IP 并将主机的主机名替换为该 IP 地址是个好主意,这可行吗?如果可以,如何实现?

【问题讨论】:

    标签: caching https dns vala http-caching


    【解决方案1】:

    我以这种方式重写了我的 getResponse 函数,现在它按我想要的方式工作。

    public string getResponse (string host) 
    { 
        var ip = loadAddress();
        if (ip == "")
            ip = resolveHost();
    
        var newHost = replaceHostWithIp(host, ip);
    
        var session = new Soup.Session ();
        session.ssl_strict = false;
        session.user_agent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36";
    
        var message = new Soup.Message ("GET", newHost);
        message.tls_errors = GLib.TlsCertificateFlags.VALIDATE_ALL;  
    
        message.request_headers.append("Host", "api.instagram.com");
    
        session.send_message (message);
    
        if (loadAddress() == "")
            setAddress(ip);
    
        return (string) message.response_body.data;
    }
    

    其中loadAddress() 和setAddress() 是从GSettings 加载IP 并设置它的函数,replaceHostWithIp() 是用给定IP 地址替换api.instagram.com 的函数。

    【讨论】:

    • 现在当 instagram 更改他们的 IP 地址时,您的代码将永远无法再次工作......这不是一个很好的解决方案。尝试弄清楚您的 DNS 为何如此缓慢可能会更有用:我很确定 libsoup 只使用 GIO 最终基本上调用 getaddrinfo() 并且由于某种原因,您的操作系统需要很长时间才能解析地址.
    • 我知道,我想我以后会处理的。奇怪的是,api.instagram.com 解析很快,api.instagram.com 解析很慢,虽然我认为 IP 是一样的。
    • @jku btw,你能建议我怎么解决吗?我尝试使用 libcurl 而不是 libsoup(我读过它更快)并且结果相同,所以我认为这不是库问题。
    • 哎呀,api.instagram.com 链接应该以 http: 和 https: 开头
    猜你喜欢
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 2018-05-25
    • 2013-12-31
    • 1970-01-01
    • 2018-06-04
    相关资源
    最近更新 更多