码迷,mamicode.com
首页 > Web开发 > 详细

A simple in-process HTTP server for UWP

时间:2017-09-27 10:21:09      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:nec   stp   connect   false   sub   task   选项   ted   requests   

原文 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

标签:nec   stp   connect   false   sub   task   选项   ted   requests   

原文地址:http://www.cnblogs.com/lonelyxmas/p/7599766.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!