A simple in-process HTTP server for UWP

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了A simple in-process HTTP server for UWP相关的知识,希望对你有一定的参考价值。

原文 http://www.dzhang.com/blog/2012/09/18/a-simple-in-process-http-server-for-windows-8-metro-apps

简单来说,就是在UWP中做一个简单的Web Server,本实例UWP(server) 与 Winform(client) 在同一机子将无法通讯,但UWP(server)写client代码可调用调试。

注意,Package.appxmanifest 选项“功能”卡中的Internet配置。

Below is some code for a simple HTTP server for Metro/Modern-style Windows 8 apps. This code supports GET requests for a resource located at the root-level (e.g. http://localhost:8000/foo.txt) and looks for the corresponding file in the Data directory of the app package. This might be useful for unit testing, among other things.

public class HttpServer : IDisposable {
  private const uint BufferSize = 8192;
  private static readonly StorageFolder LocalFolder
               = Windows.ApplicationModel.Package.Current.InstalledLocation;

  private readonly StreamSocketListener listener;

  public HttpServer(int port) {
    this.listener = new StreamSocketListener();
    this.listener.ConnectionReceived += (s, e) => ProcessRequestAsync(e.Socket);
    this.listener.BindServiceNameAsync(port.ToString());
  }

  public void Dispose() {
    this.listener.Dispose();
  }

  private async void ProcessRequestAsync(StreamSocket socket) {
    // this works for text only
    StringBuilder request = new StringBuilder();
    using(IInputStream input = socket.InputStream) {
      byte[] data = new byte[BufferSize];
      IBuffer buffer = data.AsBuffer();
      uint dataRead = BufferSize;
      while (dataRead == BufferSize) {
        await input.ReadAsync(buffer, BufferSize, InputStreamOptions.Partial);
        request.Append(Encoding.UTF8.GetString(data, 0, data.Length));
        dataRead = buffer.Length;
      }
    }

    using (IOutputStream output = socket.OutputStream) {
      string requestMethod = request.ToString().Split(\n)[0];
      string[] requestParts = requestMethod.Split( );

      if (requestParts[0] == "GET")
        await WriteResponseAsync(requestParts[1], output);
      else
        throw new InvalidDataException("HTTP method not supported: "
                                       + requestParts[0]);
    }
  }

  private async Task WriteResponseAsync(string path, IOutputStream os) {
    using (Stream resp = os.AsStreamForWrite()) {
      bool exists = true;
      try {
        // Look in the Data subdirectory of the app package
        string filePath = "Data" + path.Replace(/, \\);
        using (Stream fs = await LocalFolder.OpenStreamForReadAsync(filePath)) {
          string header = String.Format("HTTP/1.1 200 OK\r\n" +
                          "Content-Length: {0}\r\n" +
                          "Connection: close\r\n\r\n",
                          fs.Length);
          byte[] headerArray = Encoding.UTF8.GetBytes(header);
          await resp.WriteAsync(headerArray, 0, headerArray.Length);
          await fs.CopyToAsync(resp);
        }
      }
      catch (FileNotFoundException) {
        exists = false;
      }

      if (!exists) {
        byte[] headerArray = Encoding.UTF8.GetBytes(
                              "HTTP/1.1 404 Not Found\r\n" +
                              "Content-Length:0\r\n" +
                              "Connection: close\r\n\r\n");
        await resp.WriteAsync(headerArray, 0, headerArray.Length);
      }

      await resp.FlushAsync();
    }
  }
}

Usage:

const int port = 8000;
using (HttpServer server = new HttpServer(port)) {
  using (HttpClient client = new HttpClient()) {
    try {
      byte[] data = await client.GetByteArrayAsync(
                    "http://localhost:" + port + "/foo.txt");
      // do something with 
    }
    catch (HttpRequestException) {
      // possibly a 404
    }
  }
}

 

Notes:

  • The app manifest needs to declare the "Internet (Client & Server)" and/or the "Private Networks (Client & Server)" capability.
  • Due to the Windows 8 security model:
    • A Metro app can access network servers within its own process.
    • A Metro app Foo can access network servers hosted by another Metro app Bar iff Foo has a loopback exemption. You can use CheckNetIsolation.exe to do this. This is useful for debugging only, as it must be done manually.
    • A Desktop app cannot access network servers hosted by a Metro app. The BackgroundDownloader appears to fall into this category even though that is an API available to Metro apps.

以上是关于A simple in-process HTTP server for UWP的主要内容,如果未能解决你的问题,请参考以下文章

如何修复错误“ANCM In-Process Handler Load Failure”?

Status bar could not find cached time string image. Rendering in-process?

python国内镜像源

python国内镜像源

解决pip安装Cannot fetch index base URL http://pypi.python.org/simple/

ListView simple adapter