Chromium 自定義緩存策略


Chromium Embedded Framework (CEF) 是一個開源庫,用於在應用程序中嵌入 Chromium web 瀏覽器控制。CEF 本身並沒有直接提供自定義緩存策略的接口。它主要遵循 Chromium 的緩存策略。
然而,你可以通過一些方式間接地實現自定義緩存策略:

  1. 自定義請求處理:你可以通過實現 CefRequestHandler 接口來自定義請求的處理。例如,你可以在 OnBeforeResourceLoad 方法中修改請求的頭部,添加或修改 Cache-Control 頭部來控制緩存行爲。
  2. 禁用緩存:如果你想完全禁用緩存,你可以在創建 CefBrowser 或 CefRequest 時設置 cache_path 爲空。
  3. 離線緩存:CEF 支持 HTML5 的應用程序緩存(AppCache),你可以使用它來實現離線緩存。
  4. 自定義協議:你可以通過實現 CefSchemeHandlerFactory 和 CefResourceHandler 來創建自定義協議,然後在自定義協議中實現你自己的緩存策略。
    請注意,以上方法可能需要對 CEF 和 Chromium 的內部機制有一定的瞭解,並且可能需要一些編程工作。

CefRequestHandler 在什麼位置實現

CefRequestHandler是一個接口,你可以通過創建一個新的類來實現它,這個新類可以在你的項目中的任何位置。以下是一個基本的例子:

class MyRequestHandler : public CefRequestHandler {
public:    MyRequestHandler() {}    
virtual ~MyRequestHandler() {}    
// Implement methods from CefRequestHandler as needed.    
// For example:    
virtual ReturnValue OnBeforeResourceLoad(        
CefRefPtr browser,        
CefRefPtr frame,        
CefRefPtr request,        
CefRefPtr callback) OVERRIDE {        
// Modify request as needed.        
return RV_CONTINUE;   
}
private:    
IMPLEMENT_REFCOUNTING(MyRequestHandler);};

然後你需要在你的CefClient實現中返回這個處理器:

class MyClient : public CefClient {
public:    MyClient() : request_handler_(new MyRequestHandler()) {}   
virtual CefRefPtr GetRequestHandler() OVERRIDE {       
return request_handler_;    
}    
// Implement other methods as needed.
private:    
CefRefPtr request_handler_;    
IMPLEMENT_REFCOUNTING(MyClient);};

這樣,CEF 就會在適當的時候調用你的MyRequestHandler實現。

我如何將本地資源作爲該請求資源返回呢?

在CEF(Chromium Embedded Framework)中,你可以通過實現自定義的CefResourceHandler來實現這個功能。下面是一個簡單的例子:

class MyResourceHandler : public CefResourceHandler {
public:
    MyResourceHandler() {}

    bool ProcessRequest(CefRefPtr<CefRequest> request,
                        CefRefPtr<CefCallback> callback) OVERRIDE {
        // Check the URL of the request and decide whether you want to handle this request.
        if (request->GetURL() == "http://my.custom.url") {
            // Use callback->Continue() to start the request.
            callback->Continue();
            return true;
        }
        return false;
    }

    void GetResponseHeaders(CefRefPtr<CefResponse> response,
                            int64& response_length,
                            CefString& redirectUrl) OVERRIDE {
        // Set up the response headers.
        response->SetMimeType("text/html");
        response->SetStatus(200);

        // Load the resource from local storage.
        std::string html_content = "<html><body>Hello, world!</body></html>";
        data_ = html_content;
        response_length = data_.size();
    }

    bool ReadResponse(void* data_out,
                      int bytes_to_read,
                      int& bytes_read,
                      CefRefPtr<CefCallback> callback) OVERRIDE {
        // Copy the data from your local resource to data_out.
        int size = std::min(bytes_to_read, static_cast<int>(data_.size()));
        memcpy(data_out, data_.c_str(), size);
        bytes_read = size;
        data_ = data_.substr(size);
        return true;
    }

private:
    std::string data_;

    IMPLEMENT_REFCOUNTING(MyResourceHandler);
};

然後在你的CefRequestHandler實現中返回這個資源處理器:

lass MyRequestHandler : public CefRequestHandler {
public:
    MyRequestHandler() {}

    CefRefPtr<CefResourceHandler> GetResourceHandler(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefFrame> frame,
        CefRefPtr<CefRequest> request) OVERRIDE {
        return new MyResourceHandler();
    }

    // Implement other methods as needed.

private:
    IMPLEMENT_REFCOUNTING(MyRequestHandler);
};

這樣,當請求的URL匹配你的自定義URL時,CEF會調用你的MyResourceHandler來處理這個請求,並從本地資源中讀取數據。

我怎麼緩存網絡資源呢,比如圖片和視頻?

CEF(Chromium Embedded Framework)本身已經包含了一個強大的緩存機制,它會自動緩存網絡請求的結果(包括圖片和視頻)。你只需要在創建CefSettings時,設置cache_path屬性爲你想要的緩存路徑即可:

CefSettings settings;
CefString(&settings.cache_path) = "/path/to/cache";

這樣CEF就會自動將網絡資源緩存在指定的路徑下。

如果你想要更細粒度的控制,比如只緩存特定的資源,或者自定義緩存的策略,你可能需要實現自己的CefResourceHandler,在其中處理資源的緩存。這需要對CEF的內部機制有深入的理解,且可能需要大量的代碼來實現。

CefResourceHandler 如何實現緩存圖片和視頻,緩存時間無限長,設置緩存路徑?

CEF(Chromium Embedded Framework)並沒有直接提供在CefResourceHandler中設置無限長緩存時間和緩存路徑的API。緩存是由CEF內部的網絡堆棧自動處理的,而CefResourceHandler主要用於處理自定義的資源請求。

如果你想要控制資源的緩存,你可能需要實現自己的緩存機制。這通常涉及到以下步驟:

在CefResourceHandler的ProcessRequest方法中,檢查請求的URL,看是否是你想要緩存的資源。

如果是,那麼檢查你的緩存(你需要自己實現緩存的存儲和檢索),看是否已經緩存了這個資源。

如果已經緩存了這個資源,那麼在GetResponseHeaders和ReadResponse方法中,返回緩存的資源。

如果沒有緩存這個資源,那麼繼續處理請求,將請求的結果保存到你的緩存中。

這個過程需要你自己實現緩存的存儲和檢索,包括緩存的路徑和過期時間。你可以使用任何你喜歡的存儲機制,比如文件系統、數據庫等。你也需要自己處理緩存的過期,比如在每次檢索緩存時,檢查緩存的時間,如果超過你設定的過期時間,那麼刪除這個緩存。

請注意,這是一個複雜的過程,需要對CEF和網絡編程有深入的理解。並且,由於CEF的網絡堆棧已經提供了強大的緩存機制,所以在大多數情況下,你可能並不需要自己實現這個功能。

demo

下是一個基本的 CefResourceHandler 的實現示例。這只是一個基礎模板,並沒有實現緩存功能。要實現緩存功能,你需要在適當的位置添加額外的代碼來處理緩存的存儲和檢索。

class MyResourceHandler : public CefResourceHandler {
 public:
  MyResourceHandler() : offset_(0) {}

  bool ProcessRequest(CefRefPtr<CefRequest> request,
                      CefRefPtr<CefCallback> callback) OVERRIDE {
    REQUIRE_IO_THREAD();

    // TODO: 在這裏檢查請求的URL,看是否是你想要緩存的資源。

    // TODO: 如果是,檢查你的緩存,看是否已經緩存了這個資源。

    // TODO: 如果已經緩存了這個資源,調用callback->Continue()然後返回true。

    // TODO: 如果沒有緩存這個資源,繼續處理請求。

    return false;
  }

  void GetResponseHeaders(CefRefPtr<CefResponse> response,
                          int64& response_length,
                          CefString& redirectUrl) OVERRIDE {
    REQUIRE_IO_THREAD();

    // TODO: 如果是從緩存中獲取的資源,設置相應的響應頭。

    // TODO: 設置response_length爲資源的長度。
  }

  bool ReadResponse(void* data_out,
                    int bytes_to_read,
                    int& bytes_read,
                    CefRefPtr<CefCallback> callback) OVERRIDE {
    REQUIRE_IO_THREAD();

    // TODO: 如果是從緩存中獲取的資源,讀取資源到data_out,並設置bytes_read。

    return false;
  }

  bool CanGetCookie(const CefCookie& cookie) OVERRIDE {
    REQUIRE_IO_THREAD();

    // Allow all cookies.
    return true;
  }

  bool CanSetCookie(const CefCookie& cookie) OVERRIDE {
    REQUIRE_IO_THREAD();

    // Allow all cookies.
    return true;
  }

  void Cancel() OVERRIDE {
    REQUIRE_IO_THREAD();
  }

 private:
  std::string data_;
  size_t offset_;

  IMPLEMENT_REFCOUNTING(MyResourceHandler);
};

這個示例中,你需要在 ProcessRequest 方法中檢查請求的 URL 和你的緩存,然後在 GetResponseHeaders 和 ReadResponse 方法中返回緩存的資源。你還需要在適當的位置處理緩存的存儲和過期。

請注意,這個示例只是一個基礎模板,實際的實現可能會更復雜。你可能需要處理各種網絡錯誤,以及緩存的併發訪問等問題。你還需要確保你的實現符合HTTP的緩存規則,比如考慮到 Cache-Control 和 Expires 等HTTP頭。

MyResourceHandler 在哪裏設置?

在CEF中,CefResourceHandler 通常在 CefRequestHandler 的 GetResourceHandler 方法中設置。你需要創建一個實現了 CefRequestHandler 的類,並在 GetResourceHandler 方法中返回你的 MyResourceHandler 實例。

以下是一個基本的示例:

class MyRequestHandler : public CefRequestHandler {
 public:
  MyRequestHandler() {}

  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) OVERRIDE {
    REQUIRE_IO_THREAD();

    // TODO: 在這裏檢查請求的URL,看是否是你想要處理的資源。

    // TODO: 如果是,創建一個MyResourceHandler實例,並返回。

    return NULL;
  }

  IMPLEMENT_REFCOUNTING(MyRequestHandler);
};

然後,你需要在創建 CefBrowser 時設置這個 CefRequestHandler。這通常在 CefBrowserHost::CreateBrowser 或 CefBrowserHost::CreateBrowserSync 調用時完成。例如:

CefWindowInfo window_info;
CefBrowserSettings browser_settings;
CefRefPtr<MyRequestHandler> request_handler = new MyRequestHandler();

// 創建一個新的CefBrowser實例。
CefBrowserHost::CreateBrowser(window_info, request_handler, url, browser_settings, NULL);

在這個示例中,CEF會在處理每個請求時調用 MyRequestHandler::GetResourceHandler 方法。如果這個方法返回一個 CefResourceHandler 實例,那麼CEF將使用這個handler來處理請求。否則,CEF將使用默認的網絡堆棧來處理請求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章