1

I'm a bit new to c# and CefSharp :-) so be cool with me !

My goal is to call an url, and then explore DOM to retrieve data and then process this data for hypervision purpose. I've achieve that retrieval and my js code work well using EvaluateScriptAsync.

By now i want to track data refresh. The page is updated by a websocket communication, which then update values in the DOM object model.

i think to use RequestHandler and adapt GetResourceResponseFilter; but i can't manage to do that and seems the the methods i've implemented were never called ... i use the Minimal solution dowloaded from cefsharp project site. I just add the two lines at the end of this snippet :

 public BrowserForm()
        {
            InitializeComponent();

            Text = "CefSharp";
            WindowState = FormWindowState.Maximized;

            browser = new ChromiumWebBrowser("www.google.com");
            toolStripContainer.ContentPanel.Controls.Add(browser);

            browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
            browser.LoadingStateChanged += OnLoadingStateChanged;
            browser.ConsoleMessage += OnBrowserConsoleMessage;
            browser.StatusMessage += OnBrowserStatusMessage;
            browser.TitleChanged += OnBrowserTitleChanged;
            browser.AddressChanged += OnBrowserAddressChanged;
            // Add this  for request handler
            Handler.RequestHandler requestHandler = new MyBasicRequestHandler();
            browser.RequestHandler = requestHandler;

And my test handler look like this !

public class MyBasicRequestHandler : CefSharp.Handler.RequestHandler
        {
            public bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
            {
                MessageBox.Show ("OnResourceResponse");
                return false;
            }
            public bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url)
            {
                MessageBox.Show("OnProtocolExecution : "+url);
                return false;
            }
            public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
            {
                MessageBox.Show("GetResourceResponseFilter : " + request.ReferrerUrl);
                return null;
            }
        }

But nothing is fired !

Any help or advice will be appreciate.

thanks!

akaioda
  • 31
  • 1
  • 4
  • What version are you using? For reference you cannot intercept websocket communication through a RequestHandler – amaitland Mar 23 '20 at 19:17
  • See https://github.com/cefsharp/CefSharp/wiki/General-Usage#response-filtering for an example of using a response filter. – amaitland Mar 23 '20 at 19:28
  • hi, @amaitland Chromium 79.0.3945.130, CEF r79.1.36+g90301bd+chromium-79.0.3945.130, CefSharp 79.1.360.0 ! ;-( for websocket but i've seen with developper tools in Chrome that there is some xhr exchange at fixed time. This will do the trick if i manage how to make RequestHandler to work. I willllok at the example you provide and back here to tell you something ! best regards – akaioda Mar 23 '20 at 19:50
  • You can access the Websocket in devtools, you cannot access it through a `RequestHandler`. The code you originally posted is incorrect for version `79`. – amaitland Mar 23 '20 at 23:19
  • Hi @amaitland, Thank you ! based on the example you have provide to me, it's working and i can filter and detect what i need in OnResourceLoadComplete :-) Now, base on this detection, i need to call my refresh method wich is in Mainform class. Can you kindly show me the way how to achieve this in a very general and safe maner ? Is declaring a static event in CustomRessourceRequestHandler, and register an handler method in Mainform can be a direction to follow ? best regards – akaioda Mar 24 '20 at 11:31
  • You can post your own answer to this question. If you have another question then ask a new question. – amaitland Mar 24 '20 at 19:50

1 Answers1

2

Thanks to amaitland kind comments this code works. I've only added few lines to CefSharp.Minimal Example.Winforms solution pulled from github to register the RequestHandler.

public BrowserForm()
        {
            InitializeComponent();

            Text = "CefSharp";
            WindowState = FormWindowState.Maximized;

            browser = new ChromiumWebBrowser("https://cefsharp.github.io/");
            toolStripContainer.ContentPanel.Controls.Add(browser);

            browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
            browser.LoadingStateChanged += OnLoadingStateChanged;
            browser.ConsoleMessage += OnBrowserConsoleMessage;
            browser.StatusMessage += OnBrowserStatusMessage;
            browser.TitleChanged += OnBrowserTitleChanged;
            browser.AddressChanged += OnBrowserAddressChanged;
            // Add this  for request handler
            Handler.RequestHandler requestHandler = new MyBasicRequestHandler();
            browser.RequestHandler = requestHandler;

            var version = string.Format("Chromium: {0}, CEF: {1}, CefSharp: {2}",
               Cef.ChromiumVersion, Cef.CefVersion, Cef.CefSharpVersion);

            var bitness = Environment.Is64BitProcess ? "x64" : "x86";
            var environment = String.Format("Environment: {0}", bitness);

            DisplayOutput(string.Format("{0}, {1}", version, environment));
        }

And then I've add code for MyBasicRequestHandler and MyCustomResourceRequestHandler Classes as follow :

public class MyCustomResourceRequestHandler : CefSharp.Handler.ResourceRequestHandler
        {
            private readonly System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();

            protected override IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
            {
                return new CefSharp.ResponseFilter.StreamResponseFilter(memoryStream);
            }

            protected override void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
            {
                //You can now get the data from the stream
                var bytes = memoryStream.ToArray();

                if (response.Charset == "utf-8")
                {
                    var str = System.Text.Encoding.UTF8.GetString(bytes);
                    Console.WriteLine("In OnResourceLoadComplete : " + str.Substring(0,10) + " <...>");
                }
                else
                {
                    //Deal with different encoding here
                }
            }
        }

        public class MyBasicRequestHandler : CefSharp.Handler.RequestHandler
        {
            protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
            {
                Console.WriteLine("In GetResourceRequestHandler : " + request.Url);
                //Only intercept specific Url's
                if (request.Url == "http://cefsharp.github.io/" || request.Url == "https://cefsharp.github.io/")
                {
                    return new MyCustomResourceRequestHandler();
                }
                //Default behaviour, url will be loaded normally.
                return null;
            }

        }

Start the app and happy to see this in the VisualStudio console ouput :

In GetResourceRequestHandler : https://cefsharp.github.io/
In OnResourceLoadComplete : <!DOCTYPE  <...>
In GetResourceRequestHandler : https://fonts.googleapis.com/css?family=Ubuntu:400,500
In GetResourceRequestHandler : https://cefsharp.github.io/stylesheets/stylesheet.css
In GetResourceRequestHandler : https://cefsharp.github.io/stylesheets/github-light.css
In GetResourceRequestHandler : https://sidecar.gitter.im/dist/sidecar.v1.js
In GetResourceRequestHandler : https://cefsharp.github.io/images/logo2.png
In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram1.png
In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram2.png
In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram3.png
In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram4.png
In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram5.png
In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram7.png
In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram6.png
In GetResourceRequestHandler : https://cefsharp.github.io/stylesheets/print.css
In GetResourceRequestHandler : https://cefsharp.github.io/images/top-header.png
In GetResourceRequestHandler : https://fonts.gstatic.com/s/ubuntu/v14/4iCs6KVjbNBYlgoKfw72.woff2
In GetResourceRequestHandler : https://fonts.gstatic.com/s/ubuntu/v14/4iCv6KVjbNBYlgoCjC3jsGyN.woff2

So my problem is solved ! Thanks again dear amaitland ;-)

akaioda
  • 31
  • 1
  • 4