只有一个浏览器的代理与 CefSharp Offscreen

Proxy for only one browser with CefSharp Offscreen

我试图在不更改其他浏览器设置的情况下为 ChromiumWebBrowser() 设置代理。

我的代码如下所示:

CEF初始化

在这里我将初始化CefSharp并调用将测试设置代理的方法

public CFTryOut()
    {
        var settings = new CefSettings()
        {
            CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\Cache"),
        };

        CefSharpSettings.ShutdownOnExit = true;

        Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

        ProxyTest();

    }

代理测试

这里我想创建两个ChromiumWebBrowser()并且只给其中一个设置代理

async Task ProxyTest()
    {
        ChromiumWebBrowser firstbrowser = new ChromiumWebBrowser();
        ChromiumWebBrowser secondbrowser = new ChromiumWebBrowser();

        waitini:
        if (!firstbrowser.IsBrowserInitialized && !secondbrowser.IsBrowserInitialized)
        {
            Thread.Sleep(100);
            goto waitini;
        }

        firstbrowser.LoadingStateChanged += FirstBrowserLoadingStateChanged;
        secondbrowser.LoadingStateChanged += SecondBrowserLoadingStateChanged;

        OpenSync("http://icanhazip.com/", firstbrowser);
        string x = await firstbrowser.GetBrowser().MainFrame.GetSourceAsync();

        //Set the Proxy
        await Cef.UIThreadTaskFactory.StartNew(delegate
        {
            var rc = firstbrowser.GetBrowser().GetHost().RequestContext;
            var v = new Dictionary<string, object>();
            v["mode"] = "fixed_servers";
            v["server"] = "http://45.77.248.104:8888";
            string error;
            bool success = rc.SetPreference("proxy", v, out error);
        });

        OpenSync("http://icanhazip.com/", firstbrowser);
        string y = await firstbrowser.GetBrowser().MainFrame.GetSourceAsync();

        OpenSync("http://icanhazip.com/", secondbrowser);
        string z = await secondbrowser.GetBrowser().MainFrame.GetSourceAsync();


    }

在这里,First/SecondBrowserLoadingStateChanged允许我在页面加载完成时进行标记,以便 OpenSync 在返回之前等待页面加载结束:

public void OpenSync(string url, ChromiumWebBrowser browser)
    {
        IsLoading = true;
        browser.Load(url);
        SpinWait.SpinUntil(() => !IsLoading);
    }

我期待的

x = 我的 ip - xx.xx.xx.xx

y = 代理的 ip - 45.77.248.104

z = 我的 ip - xx.xx.xx.xx

我得到了什么

x = 我的 ip - xx.xx.xx.xx

y = 代理的 ip - 45.77.248.104

z = 代理的 ip - 45.77.248.104

问题是我没有在 secondbrowser 上设置任何代理,但请求通过代理。我想那是因为他们共享同一个主机。

所以

1) 如何为每个 ChromiumWebBrowser 指定专用代理?

2) 如何为每个新 ChromiumWebBrowser 指定不同的主机?

感谢@amaitland,实际上这很容易。

我的问题是我试图在浏览器初始化后设置 RequestContext,而它是只读的。

但是可以在构造函数中作为参数传递:

        var rc1 = new RequestContext();
        ChromiumWebBrowser firstbrowser = new ChromiumWebBrowser("", null, rc1);
        var rc2 = new RequestContext();
        ChromiumWebBrowser secondbrowser = new ChromiumWebBrowser("", null, rc2);

全部归功于 Amaitland

为了更可重用的方式,设置代理的过程可以这样被驱逐:

    async private Task SetProxy(ChromiumWebBrowser cwb, string Address)
    {
        await Cef.UIThreadTaskFactory.StartNew(delegate
        {
            var rc = cwb.GetBrowser().GetHost().RequestContext;
            var v = new Dictionary<string, object>();
            v["mode"] = "fixed_servers";
            v["server"] = Address;
            string error;
            bool success = rc.SetPreference("proxy", v, out error);
        });
    }

那我就可以打电话了:

SetProxy(firstbrowser, "123.123.123.123:1234")

没错,但是使用("asyn")时要记住

   async private Task SetProxy(ChromiumWebBrowser cwb, string Address)
    {
        await Cef.UIThreadTaskFactory.StartNew(delegate
        {
            var rc = cwb.GetBrowser().GetHost().RequestContext;
            var v = new Dictionary<string, object>();
            v["mode"] = "fixed_servers";
            v["server"] = Address;
            string error;
            bool success = rc.SetPreference("proxy", v, out error);
        });
    }

示例使用:

   public async void dd1()
    {
      await SetProxy(firstbrowser, "123.123.123.123:1234")  
    }

/完美主义模式开启

using System.Threading.Tasks;
using System.Collections.Generic;
using CefSharp;

namespace Extensions
{
    public static class WebBrowserExtensions
    {
        public static Task SetProxy(this IWebBrowser webBrowser, string address)
        {
            return Cef.UIThreadTaskFactory.StartNew(() =>
            {
                var context = webBrowser.GetBrowser().GetHost().RequestContext;

                context.SetPreference("proxy", new Dictionary<string, object>
                {
                    ["mode"] = "fixed_servers",
                    ["server"] = address
                }, out _);
            });
        }
    }
}

用法:

await browser.SetProxy("111.111.111.111:1111")