Xamarin.Forms Webview:ERR_CONNECTION_REFUSED尝试使用EmbedIO

时间:2018-10-24 21:32:56

标签: android xamarin.forms android-webview localserver embedio

我正在尝试为Xamarin.Forms WebView运行本地服务器。这是为了避开CORS,因此html的结构可以像普通页面一样。这适用于UWP和iOS,但Android始终会提供ERR_CONNECTION_REFUSED。我尝试过的一些进一步的细节/事情:

  • 该应用程序正在运行自己的服务器,因此不是尝试访问单独设备上的服务器的情况。
  • 已启用Internet权限。
  • 文件的路径确实存在,否则Web服务器将无法启动。
  • 链接到本地​​服务器nuget软件包:https://github.com/unosquare/embedio

下面是我正在使用的代码的概述。实际上,我使用的是自定义渲染器,注入Javascript来访问平台功能等。但这应该简化它:

使用EmbedIO创建和启动WebServer的类:

public class LocalWebServer: IDisposable
{
    public static string Url = "http://localhost:8787/";

    private readonly string _filePath;
    private WebServer _server;

    public LocalWebServer(string filePath)
    {
        _filePath = filePath;
    }

    public void StartWebServer()
    {
        _server = new WebServer(Url);

        _server.RegisterModule(new LocalSessionModule());
        _server.RegisterModule(new StaticFilesModule(_filePath));
        _server.Module<StaticFilesModule>().UseRamCache = true;
        _server.Module<StaticFilesModule>().DefaultExtension = ".html";
        _server.Module<StaticFilesModule>().DefaultDocument = "index.html";
        _server.Module<StaticFilesModule>().UseGzip = false;



        Task.Factory.StartNew(async ()=>
        {
            Debug.WriteLine("Starting Server");
            await _server.RunAsync();
        });
    }

    public void Dispose()
    {
        _server?.Dispose();
    }
}

启动服务器并显示Web视图的代码:

    public App()
    {
        InitializeComponent();

        //Create and display a Webview
        _webView = new WebView();
        MainPage = new ContentPage()
        {
            Content = _webView,
        };
    }

    protected override async void OnStart()
    {
        //Service which can initialize app for first time use, and stores
        //the folder location for the html page on each platform
        var htmlService = DependencyService.Get<IHandleHtmlContentService>();

        //Local webserver
        var localWebServer = new LocalWebServer(htmlService.DirectoryPath);

        //This is just a function that loads the html content from the
        //bundle resource or assets into a folder. Will only really
        //matter during the first time the App boots up.
        await htmlService.InitializeHtmlContent();

        //Start the Webserver
        localWebServer.StartWebServer();

        //Navigate to the webserver
        _webView.Source = LocalWebServer.Url;
    }

我已经为此花了一段时间,所以我们将不胜感激。如果您需要更多详细信息,请告诉我。

1 个答案:

答案 0 :(得分:0)

结果证明,Android没有“本地主机”的概念(至少从我的理解中可以看出)。相反,我需要找到设备的IP地址。我使用以下代码完成了此操作:

public class LocalWebServer: IDisposable
{
    public readonly string Url;

    ...

    public LocalWebServer(string filePath)
    {
        _filePath = filePath;

        Url = "http://" + GetLocalIpAddress() + ":8787/";
    }

    ...

    private static string GetLocalIpAddress()
    {
        var listener = new TcpListener(IPAddress.Loopback, 0);
        try
        {
            listener.Start();
            return ((IPEndPoint)listener.LocalEndpoint).Address.ToString();
        }
        finally
        {
            listener.Stop();
        }
    }
}

在此Xamarin论坛帖子中找到了代码:https://forums.xamarin.com/discussion/42345/simple-android-http-listener-not-working