• 使用RX方式模拟DoubanFm的登陆


    WP7下的Get Post都是异步的

    关于RX

    http://www.cnblogs.com/yangecnu/archive/2012/11/03/Introducting_ReactiveExtensions.html

    我初步理解的Rx,是观察者模式的一种实现

    Url很简单,先来看看URL

    • URL: http://www.douban.com/j/app/login

    • Method: POST

    • Arguments:

      • app_nameradio_desktop_win

      • version100

      • email用户帐号

      • password明文密码

    • Header: Content-Type: application/x-www-form-urlencoded

    • Response ( application/json )

    在WP7下的Post过程大致如下(Get过程相对简单,只需要2步):

    第一步:

     1     public void PostMethod(string Url,string Postdata)
     2         {
     3 
     4             HttpWebRequest request;
     5             request = (HttpWebRequest)WebRequest.Create(new Uri(Url));
     6             request.Method = "POST";
     7             request.ContentType = "application/x-www-form-urlencoded";
     8             request.BeginGetRequestStream(new AsyncCallback(RequestCallback), request);10             _postdata = Postdata;
    11         }

    第二步:

     1    private void RequestCallback(IAsyncResult asyncResult)
     2         {
     3            HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
     4             UTF8Encoding encoding = new UTF8Encoding();
     5             Stream _body = request.EndGetRequestStream(asyncResult);
     6             byte[] formBytes = encoding.GetBytes(_postdata);//这是通过post方式传的
     7             _body.Write(formBytes, 0, formBytes.Length);
     8             _body.Close();
     9             request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);
    10 
    11          }

    第三步:

     1      private void ResponseCallback(IAsyncResult asyncResult)
     2         {
     3             HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
     4                
     5                     WebResponse httpwebresponse = request.EndGetResponse(asyncResult);
     6                     Stream stream=   httpwebresponse.GetResponseStream();
     7                     StreamReader reader = new StreamReader(stream);
     8                     string result=reader.ReadToEnd();
     9                  
    10             // Deployment.Current.Dispatcher.BeginInvoke(_postret, result);
    11             
    12         }

    刚学习了Rx,想看看如果用Rx应该怎么做

    先来回顾下Rx 如下

      public interface IObservable<T>  {  IDisposable Subscribe(IObserver<T> observer); } 

    1    public interface IObserver<T>
    2     {
    3         void OnCompleted();
    4         void OnError(Exception exception);
    5         void OnNext(T value);
    6     }

    在我的System.Reactive.Linq的Observable静态类下,定义了了IObservable<T>的很多扩展方法,

        public static IObservable<TResult> Select<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector)
      public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)

    这些扩展方法反映了我们可以像Linq一样获得一个IObservable<T>

    下面是获得一个IObservable<T>的最简单的方法

      public static IObservable<TResult> Return<TResult>(TResult value)

    用这个方法得到的IObservable<T>后就可以注册了,在我的System.Reactive.Core.dll,System命名空间下的ObservableExtensions静态类扩展了IObservable<T>的注册方式:

     1  public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext)
     2         {
     3             if (source == null)
     4             {
     5                 throw new ArgumentNullException("source");
     6             }
     7             if (onNext == null)
     8             {
     9                 throw new ArgumentNullException("onNext");
    10             }
    11             return source.Subscribe(new AnonymousObserver<T>(onNext, Stubs.Throw, Stubs.Nop));
    12         }

    具体实现我们不具体去关注,但是我们知道在11行,是New了一个匿名的观察者Observer了。

    接下来看看FromAsyncPattern

      public static Func<IObservable<TResult>> FromAsyncPattern<TResult>(Func<AsyncCallback, object, IAsyncResult> begin, Func<IAsyncResult, TResult> end)

    这是个静态方法,返回一个返回值类型为IObservable<TResult>,无实参,的委托

    先回顾用Rx实现的一个Get方法:

     1   public LoginTest()
     2         {
     3        
     4          var func=  Observable.FromAsyncPattern<HttpWebRequest,HttpWebResponse>(Webrequest,WebResponse);
     5          HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://www.baidu.com");
     6            
     7         var observable= func(request);
     8         observable.Subscribe(
     9             (result) =>
    10             {
    11                 var stream = result.GetResponseStream();
    12                 var sr = new StreamReader(stream);
    13                 var baiduhttphtml = sr.ReadToEnd();
    14             });
    15 
    16         }
    17 
    18         IAsyncResult Webrequest(HttpWebRequest request,AsyncCallback callbcak,object ob)
    19         {
    21             return request.BeginGetResponse(callbcak, request);
    22         }
    23         HttpWebResponse WebResponse(IAsyncResult result)
    24         {
    25             var request = result.AsyncState as HttpWebRequest;
    26           return (HttpWebResponse)request.EndGetResponse(result);
    27         }

    这样的Get方式看起来很简洁

    昨晚敲了一下,Post方式如下:(回去后在VS2013上用RX,发现他提示我最好用await,Task等新特性来做异步,今晚回去试试,实验室是VS2010)

     1  class MyHttpRequest
     2         {
     3             string PostData;
     4             AsyncCallback save;//用于中间传递
     5             public  IObservable<string> PostMethod(string URL, string PostData)
     6             {
     7                 this.PostData = PostData;
     8                 var func = Observable.FromAsyncPattern<HttpWebRequest,string>(Webrequest, ResponseCallback);//直接返回string
     9                 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
    10                 request.Method = "POST";
    11                 request.ContentType = "application/x-www-form-urlencoded";
    12               return  func(request);
    13 
    14             }
    15             IAsyncResult Webrequest(HttpWebRequest request, AsyncCallback callbcak, object ob)
    16             {
    17                 save = callbcak;//保存CallBack
    18                 return request.BeginGetRequestStream(act, request);
    19             }
    20             void act(IAsyncResult asyncResult)
    21             {
    22                 HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
    23                 UTF8Encoding encoding = new UTF8Encoding();
    24                 Stream _body = request.EndGetRequestStream(asyncResult);
    25                 byte[] formBytes = encoding.GetBytes(this.PostData);//这是通过post方式传的
    26                 _body.Write(formBytes, 0, formBytes.Length);
    27                 _body.Close();
    28                 request.BeginGetResponse(save, request);//用保存的CallBack
    29 
    30             }
    31             string ResponseCallback(IAsyncResult asyncResult)
    32             {
    33                 HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
    34                 WebResponse httpwebresponse = request.EndGetResponse(asyncResult);
    35                 Stream stream = httpwebresponse.GetResponseStream();
    36                 StreamReader reader = new StreamReader(stream);
    37                 return reader.ReadToEnd();
    38             }
    39         }

    好了,现在很清楚了,来试试效果

     1     public LoginTest()
     2         {
     3             //发出一个消息 跟MVVMLight Messenger有点像
     4         var observable=    new MyHttpRequest().PostMethod("http://www.douban.com/j/app/login", "app_name=radio_desktop_win&version=100&email=327442095@qq.com&password=");
     5         
     6 
     7             //直接在这里订阅一个匿名接收者
     8         observable.Subscribe((result) =>
     9             {
    10                 Debug.WriteLine(result);
    11             });
    12         Debug.WriteLine("我比你先返回,哈哈");
    13         }

    ~OK。

    可以使用这个方式做我的FM登陆了。

  • 相关阅读:
    堆排序回顾
    动画函数封装
    mouseenter 和mouseover的区别
    元素滚动 scroll 系列
    元素可视区 client 系列
    元素偏移量 offset 系列
    JS执行机制
    BOM
    常用键盘事件
    常用鼠标事件
  • 原文地址:https://www.cnblogs.com/07lyt/p/3973906.html
Copyright © 2020-2023  润新知