代码改变世界

在Silverlight开发基于http协议客户端连接器(二)

2010-09-02 17:43  姜 萌@cnblogs  阅读(277)  评论(0编辑  收藏  举报

上一篇中我们能够通过自己的WebClientEx与web应用进行通讯,这样我们就能像js中使用ajax那样异步的通过xml或json等格式进行数据收发了。

不过每次都让人家new 一个WebClientEx对象,手动传URI不说,还要管理一个共享的CookieContainer就显得笨拙了。

好吧,我们提供Message基类和一个连接器的上下文类WebConnectorContext。

Message中包含一个消息号(MessageId),一个Parameters字典。另外一个CurrentParameterUrlPart属性,该属性会自动将当前的baseurl与parameters进行拼接,过滤无效参数然后返回一个完整的url。对于一个自定义消息可以从Message继承过来,设置一下有效参数即可。

WebConnecorContext对外只提供一个AddMessageToSend方法,在该方法中设置Message和回调即可。

image image  image

下面是Message,WebConnectorContext代码还有自定义消息类LoginMessage的代码

 

Message
public class Message 
    { 
        
public static readonly string INVALID_MESSAGE_ID = "INVALID_MESSAGE_ID"
        
protected static readonly string _messageId = "messageId"
        
public static readonly string UrlParamSeparator = "?"
        
public static readonly string ParamsSeparator = "&"
        
public static readonly string EqualSeparator = "="
        
public Message() 
        { 
            init(); 
        } 
        
private void init() 
        { 
            MessageId 
= INVALID_MESSAGE_ID; 
            Parameters 
= new Dictionary<stringstring>(); 
            AvaliableParameterNames 
= new List<string>(); 
        } 
        
protected string MessageId { getset; } 
        
public Dictionary<stringstring> Parameters 
        { 
            
get
            
private set
        } 
        
protected List<string> AvaliableParameterNames; 
        
public string CurrentParameterUrlPart 
        { 
            
get 
            { 
                
string strBuilder = UrlParamSeparator; 
                strBuilder 
+= _messageId + EqualSeparator + MessageId; 
                
foreach (var pair in Parameters) 
                { 
                    
if (AvaliableParameterNames.Contains(pair.Key)) 
                    { 
                        strBuilder 
= strBuilder.AppendParameterToUrl(pair.Key, pair.Value); 
                    } 
                    
else 
                    { 
                        System.Diagnostics.Debug.WriteLine(
string.Format("没有相应消息规则{0},将忽略此参数:", pair.Key)); 
                    } 
                } 
                
return strBuilder; 
            } 
        } 
    } 
    
public static class StringExtension 
    { 
        
public static string AppendParameterToUrl(this string s, string key, string value) 
        { 
            
return s + Message.ParamsSeparator 
                     
+ key 
                     
+ Message.EqualSeparator 
                     
+ value; 
        } 
    }

 

 

 

LoginMessage
public class LoginMessage : Message 
    { 
        
public  readonly static string Uid = "178_sig_uid"
        
public readonly static string Signtime = "178_sig_time"
        
public readonly static string Appid = "178_sig_appId"
        
public readonly static string Appversion = "178_sig_v"
        
public readonly static string Isaddapp = "178_sig_added"
        
public readonly static string Sessionkey = "178_sig_sessionId"
        
public readonly static string Friendlist = "178_sig_friends"
        
public readonly static string Signsumber = "178_sig_key"
        
public LoginMessage() 
        { 
            init(); 
        } 
        
public LoginMessage(PageSignEntity dataEntity) 
        { 
            init(); 
            
base.Parameters[LoginMessage.Uid] = dataEntity.Id; 
            
base.Parameters[LoginMessage.Appid] = dataEntity.Appid; 
            
base.Parameters[LoginMessage.Appversion] = dataEntity.Appversion; 
            
base.Parameters[LoginMessage.Signtime] = dataEntity.Signtime; 
            
base.Parameters[LoginMessage.Signsumber] = dataEntity.Signsumber; 
            
base.Parameters[LoginMessage.Sessionkey] = dataEntity.Sessionkey; 
            
base.Parameters[LoginMessage.Isaddapp] = dataEntity.Isaddapp; 
            
base.Parameters[LoginMessage.Friendlist] = dataEntity.Friendlist; 
        } 
        
private void init() 
        { 
            
base.MessageId = "10000"
            
//可以用反射少些代码,或用code generater的方式 
            base.AvaliableParameterNames.Add(Uid); 
            
base.AvaliableParameterNames.Add(Signtime); 
            
base.AvaliableParameterNames.Add(Appid); 
            
base.AvaliableParameterNames.Add(Appversion); 
            
base.AvaliableParameterNames.Add(Isaddapp); 
            
base.AvaliableParameterNames.Add(Sessionkey); 
            
base.AvaliableParameterNames.Add(Friendlist); 
            
base.AvaliableParameterNames.Add(Signsumber); 
        } 
    }

 

 

 

 

WebConnectorContext
public class WebConnectorContext 
    { 
        
private List<WebClientWrapper> _asyncTasks; 
        
private string baseAddress; 
        
public WebConnectorContext(string baseAddress) 
        { 
            
this.baseAddress = baseAddress; 
            init(); 
        } 
        
private CookieContainer _cookie = new CookieContainer(); 
        
private object _cookieDataLocker = new object(); 
        
public CookieContainer AppCookie 
        { 
            
get 
            { 
                
lock (_cookieDataLocker) 
                { 
                    
return _cookie; 
                } 
            } 
            
protected set 
            { 
                
lock (_cookieDataLocker) 
                { 
                    _cookie 
= value; 
                } 
            } 
        } 
        
private void init() 
        { 
            _asyncTasks 
= new List<WebClientWrapper>(); 
        } 
        
public virtual void AddMessageToSend(Message msg, Action<WebClientWrapper, string> action) 
        { 
            var task 
= new WebClientWrapper() 
                { 
                    Message 
= msg 
                }; 
            task.DownloadStringCompleted 
+= (s) => OnResultReceived(task, s, action); 
            _asyncTasks.Add(task); 
            task.SendAsync(baseAddress, AppCookie); 
        } 
        
private void onResultReceived(WebClientWrapper task, string e, Action<WebClientWrapper, string> action) 
        { 
            
if(action != null
                action(task, e); 
            _asyncTasks.Remove(task); 
        } 
    }