传统C/S架构
在多层分布式应用中,客户端和服务器之间可以加入一层或多层应用服务程序,这种程序称为“应用服务器”(Application Server)。开发人员可以将企业应用的商业逻辑放在中间层服务器上,而不是客户端,从而将应用的业务逻辑与用户界面隔离开,在保证客户端功能的前提下,为用户提供一个瘦的(thin)界面。
这意味着如果需要修改应用程序代码,则可以只在一处(中间层服务器上)修改,而不用修改成千上万的客户端应用程序。 从而使开发人员可以专注于应用系统核心业务逻辑的分析、设计和开发,简化了企业系统的开发、更新和升级工作,极大增强了企业应用的伸缩性和灵活性。
XML Web Service
|
Remoting
|
Enterprise Service
|
WSE
|
MSMQ
|
WCF
|
|
跨平台
|
√
|
√
|
||||
.net到.net
|
√
|
√
|
||||
分布式事务
|
√
|
√
|
||||
安全可靠
|
√
|
√
|
||||
消息队列
|
√
|
√
|
分布式:一
WebServices demo1
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Services; 6 using System.Data; 7 using System.IO; 8 using System.Runtime.Serialization.Formatters.Binary; 9 namespace WebService1 10 { 11 /// <summary> 12 /// Service1 的摘要说明 13 /// </summary> 14 [WebService(Namespace = "http://tempuri.org/")] 15 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 16 [System.ComponentModel.ToolboxItem(false)] 17 // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 18 // [System.Web.Script.Services.ScriptService] 19 public class Service1 : System.Web.Services.WebService 20 { 21 22 [WebMethod(Description = "测试")] 23 public string HelloWorld() 24 { 25 return "Hello World"; 26 } 27 [WebMethod(Description = "测试")] 28 public string GetServerTime() 29 { 30 return "Server current Time:" + DateTime.Now; 31 } 32 33 [WebMethod(Description = "测试")] 34 public int[] GetArrays() 35 { 36 return new int[] { 1, 2, 3, 3, 5 }; 37 } 38 39 [WebMethod] 40 public DataTable GetDataTable() 41 { 42 DataTable dt = new DataTable("emp"); 43 dt.Columns.Add("员工号"); 44 dt.Columns.Add("姓名"); 45 dt.Columns.Add("年龄"); 46 dt.Columns.Add("公司"); 47 DataRow dr = dt.NewRow(); 48 dr["员工号"] = "001"; 49 dr["姓名"] = "peter.peng"; 50 dr["年龄"] = "100"; 51 dr["公司"] = "hcc"; 52 dt.Rows.Add(dr); 53 return dt; 54 } 55 56 57 [WebMethod] 58 public Byte [] GetDataTable1() 59 { 60 DataTable dt = new DataTable();//这样如果不加表名webServices就不会序列化它,就会有问题。 61 dt.Columns.Add("员工号"); 62 dt.Columns.Add("姓名"); 63 dt.Columns.Add("年龄"); 64 dt.Columns.Add("公司"); 65 DataRow dr = dt.NewRow(); 66 dr["员工号"] = "001"; 67 dr["姓名"] = "peter.peng"; 68 dr["年龄"] = "100"; 69 dr["公司"] = "hcc"; 70 dt.Rows.Add(dr); 71 72 //这里就要手动的序化列 73 74 BinaryFormatter bf = new BinaryFormatter(); 75 MemoryStream ms = new MemoryStream();//内存流 76 bf.Serialize(ms, dt);//把对像序化成内存流 77 byte[] bt = ms.ToArray();//把内存中的流数据直可以转成数组 78 ms.Close();//别忘了关掉流 79 return bt; ; 80 } 81 } 82 }
1 private void button2_Click(object sender, EventArgs e) 2 { 3 Host.WebServices.Services1.Service1SoapClient _client = new Host.WebServices.Services1.Service1SoapClient(); 4 string ss = _client.GetServerTime(); 5 } 6 7 private void button1_Click(object sender, EventArgs e) 8 { 9 Host.WebServices.Services1.Service1SoapClient _client = new Host.WebServices.Services1.Service1SoapClient(); 10 byte[] bufferData = _client.GetDataTable1(); 11 12 BinaryFormatter bf = new BinaryFormatter(); 13 MemoryStream ms = new MemoryStream(bufferData);//把字节数据转换成流 14 DataTable dt = bf.Deserialize(ms) as DataTable; 15 this.dataGridView1.DataSource = dt; 16 }
异步调用WebServices(添加web引用)
其它后台的方法写的都一样,只是前端调用的时候用一个事件触发,如下代码所示
1 public string sss = null; 2 void host_HelloWorldCompleted(object sender, HelloWorldCompletedEventArgs e) 3 { 4 sss = e.Result; 5 } 6 protected void Button1_Click(object sender, EventArgs e) 7 { 8 Host.Services1.Service1 host = new Service1(); 9 host.HelloWorldCompleted += new HelloWorldCompletedEventHandler(host_HelloWorldCompleted); 10 host.GetHelloAsync(); 11 }
分布式二:
Remoting demo1
第一层:接口
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace ClassLibrary1 7 { 8 public interface IHello 9 { 10 string Hello(string name); 11 } 12 }
第二层:服务端
1 private void button1_Click(object sender, EventArgs e) 2 { 3 TcpChannel channel = new TcpChannel(3333);//step 1 4 5 ChannelServices.RegisterChannel(channel, false);//step 2 register channel 6 7 RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyHello), "hello", WellKnownObjectMode.SingleCall);//注册远程对象 8 9 this.label1.Text = "server is running.."; 10 }
第三层:前台(引用接口)
1 IHello myHello = Activator.GetObject(typeof(IHello), "tcp://127.0.0.1:3333/hello") as IHello; 2 3 this.label1.Text = myHello.Hello("peter.peng");
分布式三:WCF
接口
理解契约式编程
掌握服务契约
服务契约描述了暴露给外部的类型(接口或类)、服务所支持的操作、使用的消息交换模式和消息的格式。每个WCF服务必须实现至少一个服务契约。使用服务契约必须要引用命名空间System.ServiceModel 。
ServiceContractAttribute
OperationContractAttribute
掌握数据契约
大部分的系统都是以数据为中心的(Data Central),数据是信息的载体,一个分布式的互联系统关注于数据的交换,而数据正常交换的根本前提是参与数据交换的双方对于数据结构的一致性理解。这就为数据的表现提出了要求,为了保证处于不同平台、不同厂商的应用能够正常地进行数据交换,交换的数据必须采用一种大家都能够理解的展现方式。在这方面,XML无疑是最好的选择。所以WCF下的序列化(Serialization)解决的就是如何将数据从对象的表现形式转变成XML表现形式,以确保数据的正常交换。
DataContractAttribute和DataMemberAttribute
对于应用了DataContractAttribute特性的类型,只有应用了DataMemberAttribute特性的字段或者属性成员才能成为数据契约的数据成员。
理解DataContractSerializer
DataContractSerializer能自动序列化任何实现了System.Runtime.Serialization.ISerializable接口的.NET类型。
通过使用DataContract和DataMember特性,可以非常简单地让WCF的DataContractSerializer将开发者定制的数据类型序列化。
WCF对DataContractSerializer的调用被隐藏起来了.
MemoryStream stream = new MemoryStream();
DataContractSerializer serializer = new DataContractSerializer(typeof(ClientViewOfData));
serializer.WriteObject(stream, calculation);
Console.WriteLine(UnicodeEncoding.UTF8.GetChars(stream.GetBuffer());
DataContractSerializer主要通过两个方法进行序列化和反序列化:
WirteObject和ReadObject。
掌握消息契约