Не удается загрузить HTML с локального хоста в Awesomium.Net + XNA

Я пишу игру в XNA, в которой в качестве пользовательского интерфейса используются веб-представления Awesomium. Веб-изображения отображаются в Texture2D с использованием этого класса.

Он прекрасно работает с использованием локальных html-файлов, но мне также нужно использовать некоторый XML, и Awesomium, похоже, не позволяет этого (установка для FileAccessFromFileURL и WebSecurity значения false ничего не делает). Моим решением было разместить мой HTML/XML UI на локальном веб-сервере, используя этот класс для сервера.

Веб-сервер работает нормально и доступен через мой браузер, но я получаю пустые окна, когда я устанавливаю свои источники веб-просмотра на http://localhost:8023/myindex.html. Я не получаю эти выходные данные при доступе к localhost с помощью элемента управления Awesomium WPF, а также при удаленном размещении html. Это заставляет меня думать, что проблема вызвана тем, как мой класс обрабатывает URI.

    public struct AwesomiumMenu
{
    public WebView webView;
    public Microsoft.Xna.Framework.Rectangle Rectangle;

    public AwesomiumMenu(string Source, Microsoft.Xna.Framework.Rectangle rectangle)
    {
        // WebPreferences to disable same-origin policy so we can load local XML + remove scrollbars
        const string SCROLLBAR_CSS = "::-webkit-scrollbar { visibility: hidden; }";
        WebSession session = WebCore.CreateWebSession(new WebPreferences()
        {
            CustomCSS = SCROLLBAR_CSS,
            UniversalAccessFromFileURL = true,
            FileAccessFromFileURL = true,
            WebSecurity = false
        });

        //// CSS styling
        //const string SCROLLBAR_CSS = "::-webkit-scrollbar { visibility: hidden; }";
        //WebCore.Initialize(new WebConfig()
        //{
        //    CustomCSS = SCROLLBAR_CSS
        //});

        webView = WebCore.CreateWebView(rectangle.Width, rectangle.Height, session);
        webView.Source = Source.ToUri();
        Console.WriteLine(webView.Source);
        webView.IsTransparent = true;

        while (webView.IsLoading)
            WebCore.Update();

2 ответа

Я использую mongoose в качестве локального сервера - очень прост в использовании. Я сделал простейшее тестовое приложение, которое я мог, и оно работает для меня. Вот весь код:

public partial class Form1 : Form
{
    private Awesomium.Windows.Forms.WebControl webControl1;

    public Form1()
    {
        if (!WebCore.IsInitialized)
        {
            WebCore.Initialize(new WebConfig(), true);
        }

        InitializeComponent();

        this.webControl1.Dock = System.Windows.Forms.DockStyle.Fill;
        this.webControl1.Location = new System.Drawing.Point(0, 0);
        this.webControl1.Size = new System.Drawing.Size(1134, 681);
        this.webControl1.TabIndex = 0;

        this.webControl1.WebSession = WebCore.CreateWebSession("%APPDATA%\\Test", new WebPreferences
        {
            CustomCSS = "body { overflow:hidden; }",
            WebSecurity = false,
            DefaultEncoding = "UTF-8",
        });

        this.webControl1.Source = new Uri("http://localhost:8080/Test/test.html");
    }
}

Поскольку вы играете в XNA, почему бы не встроить свой интерфейс в виде ресурсов в файлы DLL? это то, что я сделал для своей игры, и она отлично работает

В моей игре у меня есть интерфейс, загруженный из DLL, и по дизайну я предотвращаю навигацию по URL вне моего контекста (без внешней навигации по URL).

Чтобы добиться этого, я реализовал класс DataSource, который при вызове OnRequest загружает ресурс из dll, вот он (немного оптимизирован и прямо извлечен из моего проекта, но вы должны это понимать)

class SampleDataSource : DataSource {
     Assembly InterfaceAssembly;
     string[] names;

     public SampleDataSource() {
        InterfaceAssembly = typeof(Interface.HTMLInterface).Assembly;

        // Get the names of all the resources in the assembly
        names = InterfaceAssembly.GetManifestResourceNames();
        Array.Sort(names, CaseInsensitiveComparer.Default);
     }

     protected override void OnRequest(DataSourceRequest request) {
        var response = new DataSourceResponse();

        string[] parts = request.Path.Replace("\\", "/").Split('/');

        for (int i = 0; i < parts.Length - 1; i++) {
           parts[i] = parts[i].Replace(".", "_").Replace("-", "_");
        }

        string resourcePath = "Interface.html." + request.Path
           //.Replace(".", "_")
           .Replace("/", ".")
           .Replace("\\", ".");

        resourcePath = "Interface.html." + String.Join(".", parts);


        // Find the image in the names array
        int pos = Array.BinarySearch(names, resourcePath, CaseInsensitiveComparer.Default);

        if (pos > -1) {
           resourcePath = names[pos];
        }

        byte[] data = null;
        using (Stream stream = InterfaceAssembly.GetManifestResourceStream(resourcePath)) {
           data = new byte[stream.Length];
           stream.Read(data, 0, data.Length);
        }

        IntPtr unmanagedPointer = IntPtr.Zero;
        try {
           unmanagedPointer = Marshal.AllocHGlobal(data.Length);
           Marshal.Copy(data, 0, unmanagedPointer, data.Length);

           response.Buffer = unmanagedPointer;

           switch (System.IO.Path.GetExtension(request.Path).ToLower()) {
              case ".html":
              case ".htm":
                 response.MimeType = "text/html";
                 break;
              case ".js":
                 response.MimeType = "application/javascript";
                 break;
              case ".css":
                 response.MimeType = "text/css";
                 break;
              case ".png":
                 response.MimeType = "image/png";
                 break;
              case ".jpeg":
              case ".jpg":
                 response.MimeType = "image/jpeg";
                 break;
              default:
                 response.MimeType = "text/html";
                 break;
           }

           response.Size = (uint)data.Length;
           SendResponse(request, response);
        }
        catch (Exception e) {
           throw e;
        }
        finally {
           Marshal.FreeHGlobal(unmanagedPointer);
        }
     }
  }

Вы можете найти информацию о DataSource в официальной документации docs.awesomium.net

в любом случае, вот как я связываю источник данных с моим веб-представлением:

WebView.WebSession.AddDataSource("sample", new SampleDataSource());
Другие вопросы по тегам