重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他

简介: 原文:重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他[源码下载] 重新想象 Windows 8.
原文: 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他

[源码下载]


重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他



作者:webabcd


介绍
重新想象 Windows 8.1 Store Apps 之通信的新特性

  • 通过 HttpBaseProtocolFilter 控制缓存逻辑,以及如何通过 HttpBaseProtocolFilter 管理 cookie
  • 自定义 HttpFilter
  • 其他



示例
HTTP 服务端
WebServer/HttpDemo.aspx.cs

/*
 * 用于响应 http 请求
 */

using System;
using System.IO;
using System.Threading;
using System.Web;

namespace WebServer
{
    public partial class HttpDemo : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 停 3 秒,以方便测试 http 请求的取消
            Thread.Sleep(3000);

            var action = Request.QueryString["action"];

            switch (action)
            {
                case "getString": // 响应 http get string 
                    Response.Write("hello webabcd: " + DateTime.Now.ToString("hh:mm:ss"));
                    break;
                case "getStream": // 响应 http get stream 
                    Response.Write("hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd hello webabcd");
                    break;
                case "postString": // 响应 http post string 
                    Response.Write(string.Format("param1:{0}, param2:{1}, referrer:{2}", Request.Form["param1"], Request.Form["param2"], Request.UrlReferrer));
                    break;
                case "postStream": // 响应 http post stream 
                    using (StreamReader reader = new StreamReader(Request.InputStream))
                    {
                        if (Request.InputStream.Length > 1024 * 100)
                        {
                            // 接收的数据太大,则显示“数据接收成功”
                            Response.Write("数据接收成功");
                        }
                        else
                        {
                            // 显示接收到的数据
                            string body = reader.ReadToEnd();
                            Response.Write(Server.HtmlEncode(body));
                        }
                    } 
                    break;
                case "uploadFile": // 处理上传文件的请求
                    for (int i = 0; i < Request.Files.Count; i++)
                    {
                        string key = Request.Files.GetKey(i);
                        HttpPostedFile file = Request.Files.Get(key);
                        string savePath = @"d:\" + file.FileName;

                        // 保存文件
                        file.SaveAs(savePath);

                        Response.Write(string.Format("key: {0}, fileName: {1}, savePath: {2}", key, file.FileName, savePath));
                        Response.Write("\n");
                    }
                    break;
                case "outputCookie": // 用于显示服务端获取到的 cookie 信息
                    for (int i = 0; i < Request.Cookies.Count; i++)
                    {
                        HttpCookie cookie = Request.Cookies[0];
                        Response.Write(string.Format("cookieName: {0}, cookieValue: {1}", cookie.Name, cookie.Value));
                        Response.Write("\n");
                    }
                    break;
                case "outputCustomHeader": // 用于显示一个自定义的 http header
                    Response.Write("myRequestHeader: " + Request.Headers["myRequestHeader"]);
                    break;
                default:
                    break;
            }

            Response.End();
        }
    }
}


1、演示如何通过 HttpBaseProtocolFilter 控制缓存逻辑,以及如何通过 HttpBaseProtocolFilter 管理 cookie
HttpBaseProtocolFilterDemo.xaml

<Page
    x:Class="Windows81.Communication.HTTP.HttpBaseProtocolFilterDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Communication.HTTP"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <TextBlock Name="lblMsg" FontSize="14.667" />

            <Button Name="btnCacheControl" Content="通过 HttpBaseProtocolFilter 控制缓存逻辑" Click="btnCacheControl_Click" Margin="0 10 0 0" />

            <Button Name="btnCookie" Content="通过 HttpBaseProtocolFilter 管理 cookie" Click="btnCookie_Click" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
</Page>

HttpBaseProtocolFilterDemo.xaml.cs

/*
 * 演示如何通过 HttpBaseProtocolFilter 控制缓存逻辑,以及如何通过 HttpBaseProtocolFilter 管理 cookie
 * 
 * 
 * 注:
 * 1、HttpBaseProtocolFilter 实现了 IHttpFilter 接口(也就是说如果想要一个自定义 HttpFilter 的话,只要实现 IHttpFilter 接口即可)
 * 2、本例仅演示通过 HttpBaseProtocolFilter 控制缓存逻辑以及管理 cookie,HttpBaseProtocolFilter 的其它功能请参见文档
 */

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Windows.Web.Http;
using Windows.Web.Http.Filters;

namespace Windows81.Communication.HTTP
{
    public sealed partial class HttpBaseProtocolFilterDemo : Page
    {
        private HttpClient _httpClient;
        private HttpBaseProtocolFilter _filter;

        public HttpBaseProtocolFilterDemo()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // 释放资源
            if (_filter != null)
            {
                _filter.Dispose();
                _filter = null;
            }

            if (_httpClient != null)
            {
                _httpClient.Dispose();
                _httpClient = null;
            }            
        }

        // 演示如何通过 HttpBaseProtocolFilter 控制缓存逻辑
        private async void btnCacheControl_Click(object sender, RoutedEventArgs e)
        {
            _filter = new HttpBaseProtocolFilter();

            // 实例化 HttpClient 时,指定此 HttpClient 所关联的 IHttpFilter 对象
            _httpClient = new HttpClient(_filter);

            try
            {
                // 获取到 http 响应的数据后写入缓存的行为
                //     NoCache - 不写入缓存
                //     Default - 默认行为,一般会写入缓存(默认值)
                _filter.CacheControl.WriteBehavior = HttpCacheWriteBehavior.NoCache;

                // 请求 http 时,从缓存获取数据的逻辑
                //     Default - 使用 RFC 2616 中由 IETF 指定的缓存算法(默认值)
                //     MostRecent - 尽可能使用本地 HTTP 缓存,但应始终询问服务器是否有更新的内容可用
                //     OnlyFromCache - 只使用本地 HTTP 缓存中的数据,适合脱机的场景
                _filter.CacheControl.ReadBehavior = HttpCacheReadBehavior.Default;

                HttpResponseMessage response = await _httpClient.GetAsync(new Uri("http://localhost:39630/HttpDemo.aspx?action=getString"));

                lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;
                lblMsg.Text += Environment.NewLine;

                lblMsg.Text += await response.Content.ReadAsStringAsync();
                lblMsg.Text += Environment.NewLine;
            }
            catch (Exception ex)
            {
                lblMsg.Text += ex.ToString();
                lblMsg.Text += Environment.NewLine;
            }
        }

        // 演示如何通过 HttpBaseProtocolFilter 管理 cookie
        private async void btnCookie_Click(object sender, RoutedEventArgs e)
        {
            _httpClient = new HttpClient();

            try
            {
                // 构造一个 cookie(需要指定 cookie 的 name, domain, path)
                HttpCookie cookie = new HttpCookie("name", "localhost", "/");
                cookie.Value = "webabcd";
                cookie.Expires = DateTimeOffset.Now.AddDays(1);
                cookie.Secure = false;
                cookie.HttpOnly = false;

                // 通过 HttpBaseProtocolFilter 写入 cookie(也可以获取 cookie 或者删除 cookie)
                HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
                bool replaced = filter.CookieManager.SetCookie(cookie, false);

                // 请求 http 时会带上相应的 cookie
                HttpResponseMessage response = await _httpClient.GetAsync(new Uri("http://localhost:39630/HttpDemo.aspx?action=outputCookie"));

                lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;
                lblMsg.Text += Environment.NewLine;

                lblMsg.Text += await response.Content.ReadAsStringAsync();
                lblMsg.Text += Environment.NewLine;
            }
            catch (Exception ex)
            {
                lblMsg.Text += ex.ToString();
                lblMsg.Text += Environment.NewLine;
            }
        }
    }
}


2、演示如何使用自定义的 HttpFilter
MyHttpFilter.cs

/*
 * 实现 IHttpFilter 接口,开发一个自定义的 HttpFilter
 * 
 * 
 * 本 HttpFilter 会在请求和响应的 http header 中添加一条自定义数据
 */

using System;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Web.Http;
using Windows.Web.Http.Filters;

namespace Windows81.Communication.HTTP
{
    public class MyHttpFilter : IHttpFilter
    {
        private HttpBaseProtocolFilter _innerFilter;

        public MyHttpFilter()
        {
            _innerFilter = new HttpBaseProtocolFilter();
        }

        // IHttpFilter 唯一的一个需要实现的方法
        public IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage request)
        {
            return AsyncInfo.Run<HttpResponseMessage, HttpProgress>(async (cancellationToken, progress) =>
            {
                // 添加一个自定义 request http header
                request.Headers.Add("myRequestHeader", "request webabcd");

                // 借用 HttpBaseProtocolFilter 来完成 SendRequestAsync() 的工作
                HttpResponseMessage response = await _innerFilter.SendRequestAsync(request).AsTask(cancellationToken, progress);

                cancellationToken.ThrowIfCancellationRequested();

                // 添加一个自定义 response http header
                response.Headers.Add("myResponseHeader", "response webabcd");

                return response;
            });
        }

        public void Dispose()
        {
            _innerFilter.Dispose();
            GC.SuppressFinalize(this);
        }
    }
}

CustomHttpFilter.xaml

<Page
    x:Class="Windows81.Communication.HTTP.CustomHttpFilter"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Communication.HTTP"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <TextBlock Name="lblMsg" FontSize="14.667" />

            <Button Name="btnDemo" Content="自定义 HttpFilter" Click="btnDemo_Click" Margin="0 10 0 0" />

            <Button Name="btnCancel" Content="cancel" Click="btnCancel_Click" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
</Page>

CustomHttpFilter.xaml.cs

/*
 * 演示如何使用自定义的 HttpFilter
 * 
 * 
 * 自定义 HttpFilter 需要实现 IHttpFilter 接口,请参见:MyHttpFilter.cs
 */

using System;
using System.Threading;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Windows.Web.Http;

namespace Windows81.Communication.HTTP
{
    public sealed partial class CustomHttpFilter : Page
    {
        private HttpClient _httpClient;
        private CancellationTokenSource _cts;

        // 自定义的 HttpFilter
        private MyHttpFilter _filter;

        public CustomHttpFilter()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // 释放资源
            if (_filter != null)
            {
                _filter.Dispose();
                _filter = null;
            }

            if (_httpClient != null)
            {
                _httpClient.Dispose();
                _httpClient = null;
            }

            if (_cts != null)
            {
                _cts.Dispose();
                _cts = null;
            }
        }

        private async void btnDemo_Click(object sender, RoutedEventArgs e)
        {
            _filter = new MyHttpFilter();

            // 实例化 HttpClient 时,指定此 HttpClient 所关联的 IHttpFilter 对象
            _httpClient = new HttpClient(_filter);

            _cts = new CancellationTokenSource();

            try
            {
                HttpResponseMessage response = await _httpClient.GetAsync(new Uri("http://localhost:39630/HttpDemo.aspx?action=outputCustomHeader")).AsTask(_cts.Token);

                lblMsg.Text += ((int)response.StatusCode) + " " + response.ReasonPhrase;
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "myResponseHeader: " + response.Headers["myResponseHeader"];
                lblMsg.Text += Environment.NewLine;

                // IHttpContent.ReadAsStringAsync() - 获取 string 类型的响应数据
                // IHttpContent.ReadAsBufferAsync() - 获取 IBuffer 类型的响应数据
                // IHttpContent.ReadAsInputStreamAsync() - 获取 IInputStream 类型的响应数据
                lblMsg.Text += await response.Content.ReadAsStringAsync();
                lblMsg.Text += Environment.NewLine;
            }
            catch (TaskCanceledException)
            {
                lblMsg.Text += "取消了";
                lblMsg.Text += Environment.NewLine;
            }
            catch (Exception ex)
            {
                lblMsg.Text += ex.ToString();
                lblMsg.Text += Environment.NewLine;
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            // 取消 http 请求
            if (_cts != null)
            {
                _cts.Cancel();
                _cts.Dispose();
                _cts = null;
            }
        }
    }
}


3、其他
Other.xaml

<Page
    x:Class="Windows81.Communication.Other"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows81.Communication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0">

            <TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap">
                <Run>1、实时通信支持 Windows.Web.Http API 了(仍然要求 app 必须在锁屏上),关于实时通信请参见:http://www.cnblogs.com/webabcd/archive/2013/10/28/3391694.html</Run>
                <LineBreak />
                <Run>2、增加了对 Geofence 的支持,即某设备在进入或退出某地理区域后可以向 app 发出通知。Windows.Devices.Geolocation.Geofencing 命名空间用于 Geofence 管理, LocationTrigger 用于后台任务触发 Geofence 事件</Run>
                <LineBreak />
                <Run>3、支持设备的 WiFi 直连,参见 Windows.Devices.WifiDirect 命名空间</Run>
            </TextBlock>

        </StackPanel>
    </Grid>
</Page>



OK
[源码下载]

目录
相关文章
|
3天前
|
JSON JavaScript 前端开发
Haskell中的数据交换:通过http-conduit发送JSON请求
Haskell中的数据交换:通过http-conduit发送JSON请求
|
5天前
|
JSON API 开发者
Python网络编程新纪元:urllib与requests库,让你的HTTP请求无所不能
【9月更文挑战第9天】随着互联网的发展,网络编程成为现代软件开发的关键部分。Python凭借简洁、易读及强大的特性,在该领域展现出独特魅力。本文介绍了Python标准库中的`urllib`和第三方库`requests`在处理HTTP请求方面的优势。`urllib`虽API底层但功能全面,适用于深入控制HTTP请求;而`requests`则以简洁的API和人性化设计著称,使HTTP请求变得简单高效。两者互补共存,共同推动Python网络编程进入全新纪元,无论初学者还是资深开发者都能从中受益。
26 7
|
3天前
|
开发者
HTTP状态码是由网页服务器返回的三位数字响应代码,用于表示请求的处理结果和状态
HTTP状态码是由网页服务器返回的三位数字响应代码,用于表示请求的处理结果和状态
9 1
|
6天前
|
存储 JSON API
Python编程:解析HTTP请求返回的JSON数据
使用Python处理HTTP请求和解析JSON数据既直接又高效。`requests`库的简洁性和强大功能使得发送请求、接收和解析响应变得异常简单。以上步骤和示例提供了一个基础的框架,可以根据你的具体需求进行调整和扩展。通过合适的异常处理,你的代码将更加健壮和可靠,为用户提供更加流畅的体验。
26 0
|
10天前
|
网络安全 虚拟化 Windows
windows 11安装openSSH server 遇到的"kex_exchange_identification: read: Connection reset"问题
windows 11安装openSSH server 遇到的"kex_exchange_identification: read: Connection reset"问题
|
20天前
|
PHP Windows
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
|
30天前
|
开发框架 .NET API
Windows Server 2022 安装IIS 报错 访问临时文件夹 C:\WINDOWS\TEMP\3C 读取/写入权限 错误: 0x80070005
Windows Server 2022 安装IIS 报错 访问临时文件夹 C:\WINDOWS\TEMP\3C 读取/写入权限 错误: 0x80070005
64 0
|
1月前
|
Linux Docker Windows
Windows——Docker拉取Windows Server镜像
Windows——Docker拉取Windows Server镜像
98 0
|
2月前
|
弹性计算 持续交付 Docker
阿里云云效产品使用合集之如何部署到阿里云服务器上的 Windows Server 上的 IIS
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
2月前
|
网络协议 Unix 网络安全
FTP服务器怎么搭建?Windows server搭建FPT服务器
FTP服务器是按照FTP协议提供文件传输服务的计算机。它用于在两台计算机间安全地传输文件,支持用户权限管理和跨平台操作。FTP使用控制连接处理命令,数据连接传输文件,有PORT和PASV模式。要搭建FTP服务器,首先在Windows Server 2008 R2上安装IIS,确保选中FTP服务。接着,创建FTP文件夹作为站点根目录,通过IIS管理器添加FTP站点,配置站点信息、身份验证和权限。测试客户端通过telnet和浏览器访问FTP服务器,确认能成功登录及浏览文件。FTP常用于文件共享和管理,可通过专用工具如FlashFXP上传下载文件。
105 0
FTP服务器怎么搭建?Windows server搭建FPT服务器

热门文章

最新文章