异步HttpLib

HttpLib,一个基于C#语言的http协议的开源类库,让异步交互处理数据更容易。

官方下载地址:http://httplib.codeplex.com/

本文作用演示的例子的源代码:源代码下载

一:HttpLib

HttpLib类库中包含三个主要类文件:HttpVerb.cs, NamedFileStream.cs, Request.cs,另外有一个辅助类Utils.cs

基于http协议的异步操作是定义在Request.cs中。包括Get,Head,Post,Delete,Put,Patch,Upload等,而NamedFileStream.cs是在上传文件到服务器时会用到一个容器类,用于描述上传的文件。Utils.cs则是对于Url参数的处理工具类。

对于HttpLib类库实现异步操作是基于WebHttpRequest对象的异步委托实现的,具体的实现代码可以到官网下载源代码,本文接下来更多是演示以及说明HttpLib类库是怎么来运作的,不会涉及到底层采用什么机制或者相关多线程的问题。

二:用于测试的准备工作

为了更好的测试HttpLib异步调用的结果,我首先创建一个Server服务器对象,并且架设在IIS中启动起来。

Server包含两个一般处理程序一个.aspx页面,一个HttpHandler.ashx,另一个是FileHandler.ashx。还有WebForm.aspx页面。

namespace YZR.Server
{
    /// <summary>
    /// HttpHandler 的摘要说明
    /// </summary>
    public class HttpHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            string method = context.Request.HttpMethod.ToString();
            if (method.ToLower() == "get")
            {
                string Name = context.Request["Name"];
                if (string.IsNullOrEmpty(Name))
                {
                    context.Response.Write("YZR.Get(No Parameters)");
                }
                else
                {
                    context.Response.Write("YZR.Get(Name:" + Name + ",Create By " + DateTime.Now.ToString("yyyy-MM-dd") + ")");
                }
            }
            else
            {
                string LYF = context.Request["LYF"];
                if (string.IsNullOrEmpty(LYF))
                {
                    context.Response.Write("YZR.Post(No Parameters)");
                }
                else
                {
                    context.Response.Write("YZR.Post(你好,大人:" + LYF + ",Create By " + DateTime.Now.ToString("yyyy-MM-dd") + ")");
                }
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

HttpHandler.ashx

namespace YZR.Server
{
    /// <summary>
    /// FileHandler 的摘要说明
    /// </summary>
    public class FileHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            HttpFileCollection files = HttpContext.Current.Request.Files;
            if (files.Count > 0)
            {
                HttpPostedFile _upfile = files[0];
                string fileName = _upfile.FileName;/*获取文件名: C:\Documents and Settings\Administrator\桌面\123.jpg*/
                string suffix = fileName.Substring(fileName.LastIndexOf(".") + 1).ToLower();/*获取后缀名并转为小写: jpg*/
                int bytes = _upfile.ContentLength;//获取文件的字节大小   

                if (suffix != "jpg")
                    ResponseWriteEnd(context, "2"); //只能上传JPG格式图片
                if (bytes > 1024 * 1024)
                    ResponseWriteEnd(context, "3"); //图片不能大于1M   

                _upfile.SaveAs(HttpContext.Current.Server.MapPath("~/images/logo.jpg"));//保存图片
                context.Response.Write("上传成功");
            }
            else
            {
                context.Response.Write("请选择上传文件");
            }

        }
        private void ResponseWriteEnd(HttpContext context, string msg)
        {
            context.Response.Write(msg);
            context.Response.End();
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

FileHandler.ashx

namespace YZR.Server
{
    public partial class WebForm : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                string Name = Request["Name"];
                if (!String.IsNullOrEmpty(Name))
                {
                    Response.Write("Hello " + Name + ",Create By " + DateTime.Now.ToString("yyyy-MM-dd"));
                }
            }
        }
    }
}

WebForm.aspx.cs

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm.aspx.cs" Inherits="YZR.Server.WebForm" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            WebForm
        </div>
    </form>
</body>
</html>

WebForm.aspx

本文接下来都是基于这个Server对象使用HttpLib类库进行异步调用。

接下来创建两个客户端Client对象,YZR.Client这是一个控制台程序,YZR.JSClient是WebForm程序。在这两个程序都添加对HttpLib类库的引用,并且将在这两个客户端中测试从服务器异步调用的结果。

三:Get异步

我们先来看一下控制台程序(YZR.Client):

namespace YZR.Client
{
    using Redslide.HttpLib;
    using System.IO;
    class Program
    {
        static void Main(string[] args)
        {
            //Get 无参数
            //Request.Get("http://localhost:9876/HttpHandler.ashx", result => { Func(result); });
            //Request.Get("http://localhost:9876/WebForm.aspx", result => { Func(result); });
            //Get  带参数
            //Request.Get("http://localhost:9876/HttpHandler.ashx?Name=YZR", result => { Func(result); });
            //Request.Get("http://localhost:9876/HttpHandler.ashx", new { Name = "YZR" }, result => { Func(result); });
            //Request.Get("http://localhost:9876/WebForm.aspx", new { Name = "YZR" }, result => { Func(result); });
            Console.ReadKey();
        }

        static void Func(String result)
        {
            String Test = result;
            Console.WriteLine(result);
        }

    }
}

运行控制台之后,当异步访问ashx文件是将会显示一般处理程序返回来的结果。

而对于aspx页面来说则是一整个页面的html字符串。

在webform程序中,结果也是一样的,下面我们将从服务器获取页面数据,然后将获取到的页面数据输出在我们自己定义的Test.aspx页面中:

namespace YZR.JSClient
{
    using Redslide.HttpLib;
    public partial class Test : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if(!IsPostBack)
            {
                Redslide.HttpLib.Request.Get("http://localhost:9876/WebForm.aspx", new { Name = "YZR" }, result => { Func(result); });
                System.Threading.Thread.Sleep(1000);
            }
        }

        void Func(String result)
        {
            String Test = result;
            Response.Write(Test);

        }
    }
}

Test.aspx.cs

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="YZR.JSClient.Test" %>

Test.aspx

四:Post异步

Post的书写方式是相似于Get方式的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YZR.Client
{
    using Redslide.HttpLib;
    using System.IO;
    class Program
    {

        static void Main(string[] args)
        {
            //Get 无参数
            //Request.Get("http://localhost:9876/HttpHandler.ashx", result => { Func(result); });
            Request.Get("http://localhost:9876/WebForm.aspx", result => { Func(result); });
            //Get  带参数
            //Request.Get("http://localhost:9876/HttpHandler.ashx?Name=YZR", result => { Func(result); });
            //Request.Get("http://localhost:9876/HttpHandler.ashx", new { Name = "YZR" }, result => { Func(result); });
            //Request.Get("http://localhost:9876/WebForm.aspx", new { Name = "YZR" }, result => { Func(result); });

            //Post 无参数
            //Request.Post("http://localhost:9876/HttpHandler.ashx", new { }, action => Func(action));
            //Post 带参数
            //Request.Post("http://localhost:9876/WebForm.aspx", new { Name = "LYF" }, result => { Func(result); });

            Console.ReadKey();
        }

        static void Func(String result)
        {
            String Test = result;
            Console.WriteLine(result);
        }

    }
}

Post

五:浏览器端的异步Ajax

Js不具有异步功能,但通过浏览器Js+Xml可以实现Ajax技术异步操作:

var AjaxHelp = {
    GetXhr: function () {  //创建异步对象
        var xhr= false;

        var xmlhttpObj = ["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp","Microsoft.XmlHttp"];
        if(window.XMLHttpRequest){
           xhr = new XMLHttpRequest();
         }
        else if(window.ActiveXObject){
           for(i=0;i<xmlhttpObj.length;i++)
           {
               xhr = new ActiveXObject(xmlhttpObj[i]);
               if(xhr){
                    break;
                }
            }
         }
         else{
            alert("暂时不能创建XMLHttpRequest对象");
         }
        return xhr ? xhr:false;
    },
    //处理ajax的get请求
    ProcessGet: function (url, callback) {
        this.ProcessAjax("get", url, null, callback);
    },
    ProcessPost: function (url, params, callback) {
        this.ProcessAjax("post", url, params, callback);
    },
    //统一处理的方法
    ProcessAjax: function (method, url, params, callback) {
        //1.0创建异步对象
        var xhr = this.GetXhr();
        if (method == "get") {  //2.0打开链接
            xhr.open("get", url, true); //3.0不使用缓存
            xhr.setRequestHeader("if-modified-since", "0");
        } else { //2.0打开链接
            xhr.open("post", url, true); //3.0将参数放在form data属性中
            xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
        }
        //4.0设置回调函数
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                //得到从服务器里得到的数据
                var content = JSON.parse(xhr.responseText);//---->转成js对象
                //调用回调函数(执行自己的业务逻辑)
                callback(content);
            }
        }
        //5.0发送请求
        xhr.send(params);
    }
};

Ajax

在代码上,他们的书写方式我觉得是极为的相似,而且他们都是进行异步操作。

六:上传

使用HttpLib类库还有一个上传的异步操作,文章一开始说的NamedFileStream就是为了上传文件而定义的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YZR.Client
{
    using Redslide.HttpLib;
    using System.IO;
    class Program
    {

        static void Main(string[] args)
        {
            //Get 无参数
            //Request.Get("http://localhost:9876/HttpHandler.ashx", result => { Func(result); });
            Request.Get("http://localhost:9876/WebForm.aspx", result => { Func(result); });
            //Get  带参数
            //Request.Get("http://localhost:9876/HttpHandler.ashx?Name=YZR", result => { Func(result); });
            //Request.Get("http://localhost:9876/HttpHandler.ashx", new { Name = "YZR" }, result => { Func(result); });
            //Request.Get("http://localhost:9876/WebForm.aspx", new { Name = "YZR" }, result => { Func(result); });

            //Post 无参数
            //Request.Post("http://localhost:9876/HttpHandler.ashx", new { }, action => Func(action));
            //Post 带参数
            //Request.Post("http://localhost:9876/WebForm.aspx", new { Name = "LYF" }, result => { Func(result); });

            //上传
            //NamedFileStream file = new NamedFileStream("file", "1.jpg", "image/jpeg", new FileStream(@"C:\1.jpg", FileMode.Open));

            //Request.Upload("http://localhost:9876/FileHandler.ashx", new { }, new[] { new NamedFileStream("file", "1.jpg", "image/jpeg", new FileStream(@"C:\1.jpg", FileMode.Open)) }, action => Func(action));
            Console.ReadKey();
        }

        static void Func(String result)
        {
            String Test = result;
            Console.WriteLine(result);
        }

    }
}

Upload

在服务端Server下images文件夹下就会保存从客户端上传上来的文件。

总而言之,HttpLib类库可以让我们在后台中更轻松的完成异步调用,当你在程序中需要使用异步时,HttpLib也许能帮得上忙。

时间: 2024-08-25 18:28:29

异步HttpLib的相关文章

开源代码:Http请求封装类库HttpLib介绍、使用说明

今天介绍一个很好用的Http请求类库--Httplib.一直以来,我们都是为了一次web请求,单独写一段代码 有了这个类,我们就可以很方便的直接使用了. 项目介绍: http://www.suchso.com/UIweb/jquery-Plupload-use.html 基于C#语言,Httplib让异步交互处理数据更容易了.类库的方法包括:上传文件到服务器,获取页面数据. 该项目专门为web服务写的,如果你打算重新写一个http客户端和服务端的话,建议你使用wcf. 最新代码下载:http:/

HttpLib - 一个对 Http 协议进行封装的库

今日,在 Codeplex 上看到一个开源项目,对 Http 协议进行了封装,这下可以方便这些在 .NET 平台下访问 Web 服务器的同学们了,比如,从 Web 服务器抓取一个页面,使用 .NET 而不是借助浏览器向服务器发一个 Post 请求之类的操作,就可以直接调用一下实现好的方法了. 项目的地址:http://httplib.codeplex.com/ 也可以直接到下载页面下载你需要的源代码或者编译完成的类库. 下载页面的地址:http://httplib.codeplex.com/re

cocos2dx lua中异步加载网络图片,可用于显示微信头像

最近在做一个棋牌项目,脚本语言用的lua,登录需要使用微信登录,用户头像用微信账户的头像,微信接口返回的头像是一个url,那么遇到的一个问题就是如何在lua中异步加载这个头像,先在引擎源码里找了下可能会提供这个功能的地方,发现好像没有提供类似功能,那么只能自己动手写.所以我在ImageView这个类里面添加了一个成员方法,其实可以不写在ImageView里,而且我觉得非必需情况下还是不要修改引擎源码的好,因为如果源码改动比较多的话,将来引擎版本升级会比较麻烦.我写在ImageView里纯粹是想偷

学习笔记12JS异步请求

*一般用JS来监听按钮事件,都应该先监听页面OnLoad事件. *Js写在哪里,就会在页面解析到哪里执行. 异步请求:所谓异步请求,就是使用JS来监听按钮点击事件,并且发送请求,等到回复后,再使用JS来进行页面跳转,或动态改变页面.使用场合:当请求是ashx是,都可以使用异步方法,页面就无需刷到ashx的一个空白页面或者不用于展示的页面了. *使用jquery发送异步请求:$("#按钮ID").Click(fuction(){ $.get( "页面URL.ashx"

同步异步中的一致性

简述一致性中关于同步与异步环境下的共识理论 (##转载请注明) 共识问题:可称作协作,所有正确的进程对提议的值达成一致.分布式系统中,节点之间通过通信,对请求达成一致的定序. 问题定义:进程Pi处于未决状态(undecideed),提议集合D中的某个值Vi.进程之间相互通信,交换各自的提议.每个进程设置自己的决定变量(decision variable),进入决定状态(decided),此状态下不改变di的数值. 要求满足如下几个性质: 终止性(Termination):正确的进程最终都可以设置

信号驱动和异步驱动的区别

5种I/O模型: 1.阻塞I/O 2.非阻塞I/O 3.异步I/O 4.信号驱动I/O 5.I/O复用 信号驱动和异步驱动的区别 信号驱动IO是指:进程预先告知内核,使得 当某个socketfd有events(事件)发生时,内核使用信号通知相关进程. 异步IO(Asynchronous IO)是指:进程执行IO系统调用(read / write)告知内核启动某个IO操作,内核启动IO操作后立即返回到进程.IO操作即内核当中的服务例程. 异步I/O和信号驱动I/O的区别很容易被混淆.前者与后者的区

java中同步和异步有什么异同?

同步交互:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程: 异步交互:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待. 区别:一个需要等待,一个不需要等待,在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式. 哪些情况建议使用同步交互呢?比如银行的转账系统,对数据库的保存操作等等,都会使用同步交互操作,其余情况都优先使用异步交互.

019-JQuery(Ajax异步请求)

使用jquery完成异步操作 ->开发文档提供的异步API url:请求地址 type:请求方式,主要是get.post data:{}:请求的数据 dataType:返回值的类型,主要有xml.text.json.script.html success:function(data){...}成功的回调函数(4,200) GetTime.html 1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml&q

异步处理未登录url跳转

http://localhost:8080/xxx/login?url=http://localhost:8080/xxx/oldurl // 从url中获取原页面url=http://localhost:8080/xxx/oldurl function GetQueryString(paras){ var url = location.href; var paraString = url.substring(url.indexOf("?")+1,url.length).split(&