ICE学习第四步-----客户端请求服务器返回数据

这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上。

根据上一篇文章介绍的Slice语法,我们先来定义ICE文件。我定义两个ICE文件,一个用来描述测试数据库表中属性相关信息,另一个则是请求数据的方法。

结构如下:

  

定义结构体,和数据库中表的列对应,添加序列(相当于数组类型)。

在获取表的方法中注意要记得#include带有结构的ice文件,并把接口函数的返回值类型写成之前定义的数组类型,否则就像HelloWorld例子中只能在服务器显示,调回不到客户端了。(DbTableDataSeq getDataFromDb(string requestCode);这个方法其实就是客户端一调用,然后服务器操作完成,最后返回DbTableDataSeq类型的数据)

编译ICE文件:

在数据库中随便插入几条数据:

之后是一系列基本工作:创建工程,添加对ICE的引用,拖入编译好的文件,对具有接口函数的ICE文件创建实现类,实现抽象类DoSelectTableDisp_

大体结构如下图:              

为了结构能更清晰,我们把它改成这样,同时添加上查询数据库的方法:

给出这几个类的代码如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5
 6 namespace ConsoleSer.common
 7 {
 8     public class DbData
 9     {
10         public string dataName;//数据库中列名
11         public object dataValue;//数据库中列值
12     }
13
14     public class DbDataList
15     {
16         public IList<DbData> dataRow;
17     }
18 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using ConsoleSer.common;
 6 using IBM.Data.DB2;
 7 using System.Data;
 8
 9 namespace ConsoleSer.database
10 {
11     public class Db2:DbMain
12     {
13         public override IList<DbDataList> GetDataFromDatabase(string strSql)
14         {
15             IList<DbDataList> list = new List<DbDataList>();
16
17             using (DB2Connection con = new DB2Connection("server=127.0.0.1;database=TEST;uid=db2admin;pwd=db2admin;"))
18             {
19                 con.Open();
20                 DB2DataAdapter oda = new DB2DataAdapter(strSql, con);
21                 DataSet ds = new DataSet();
22                 oda.Fill(ds);
23                 if (ds.Tables.Count > 0)
24                 {
25                     DataTable dt = ds.Tables[0];
26                     for (int i = 0; i < dt.Rows.Count; i++)
27                     {
28                         IList<DbData> rowsData = new List<DbData>();
29                         for (int j = 0; j < dt.Columns.Count; j++)
30                         {
31                             DbData data = new DbData();
32                             data.dataName = dt.Columns[j].ColumnName;
33                             data.dataValue = dt.Rows[i][data.dataName];
34                             rowsData.Add(data);
35                         }
36                         DbDataList rows = new DbDataList();
37                         rows.dataRow = rowsData;
38                         list.Add(rows);
39                     }
40                 }
41             }
42             return list;
43         }
44     }
45 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using ConsoleSer.common;
 6
 7 namespace ConsoleSer.database
 8 {
 9     public class DbMain
10     {
11         public virtual IList<DbDataList> GetDataFromDatabase(string strSql)
12         {
13             IList<DbDataList> list = new List<DbDataList>();
14             return list;
15         }
16     }
17 }

最终查询完数据库返回的是这样的一条数据:(IList<DbDataList> list = new List<DbDataList>(); DbDataList包含两个字段string dataName;object dataValue;)

但是这并不是我们想要的返回类型,我们再将其转换为DbTableData类型数组,于是在TestTableMethodI实现类中有如下代码(假设客户端请求字符串是getTable):

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using tableStructFamily;
 6 using ConsoleSer.common;
 7 using ConsoleSer.database;
 8
 9 namespace ConsoleSer.slice2csI
10 {
11     class TestTableMethodI:DoSelectTableDisp_
12     {
13         public static List<DbTableData> tbData = new List<DbTableData>();//数据库中表信息
14         private static DbMain dbObject = new Db2();
15
16         public override DbTableData[] getDataFromDb(string requestCode, Ice.Current current__)
17         {
18             if (requestCode == "getTable")
19             {
20                 Console.WriteLine("收到请求!");
21                 return selectDataFromDb();
22             }
23             else
24             {
25                 throw new Exception();
26             }
27         }
28
29         private DbTableData[] selectDataFromDb()
30         {
31             IList<DbDataList> list = dbObject.GetDataFromDatabase("select * from A.T_test");
32
33             DbTableData[] objs = new DbTableData[list.Count];
34
35             for (int i = 0; i < list.Count; i++)
36             {
37                 DbDataList row = list[i];
38                 DbTableData obj = GetTableObj(row);
39                 tbData.Add(obj);
40                 objs[i] = obj;
41             }
42             return objs;
43         }
44
45         private DbTableData GetTableObj(DbDataList dataRow)
46         {
47             DbTableData obj = new DbTableData();
48             for (int i = 0; i < dataRow.dataRow.Count; i++)
49             {
50                 DbData data = dataRow.dataRow[i];
51                 setObjValue(data, ref obj);
52             }
53             return obj;
54         }
55
56         private void setObjValue(DbData data, ref DbTableData obj)
57         {
58             string name = data.dataName.ToLower();
59             switch (name)
60             {
61                 case "id":
62                     obj.ID = Convert.ToInt32(data.dataValue);
63                     break;
64                 case "nname":
65                     obj.Nname = data.dataValue.ToString();
66                     break;
67                 default:
68                     break;
69             }
70         }
71     }
72 }

附上Main函数初始化ICE的方法:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using tableStructFamily;
 6
 7 namespace ConsoleTestIceServer
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             int status = 0;
14             Ice.Communicator ic = null;
15             try
16             {
17                 ic = Ice.Util.initialize(ref args);
18                 Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("tableSelector", "default -p 10000");
19                 Ice.Object obj = new ConsoleSer.slice2csI.TestTableMethodI();
20                 adapter.add(obj, Ice.Util.stringToIdentity("tableSelector"));
21                 adapter.activate();
22                 Console.WriteLine("初始化成功!");
23                 ic.waitForShutdown();
24             }
25             catch (Exception e)
26             {
27                 Console.Error.WriteLine(e);
28                 status = 1;
29             }
30             finally
31             {
32                 if (ic != null)
33                 {
34                     ic.destroy();
35                 }
36             }
37             Environment.Exit(status);
38         }
39     }
40 }

如此一来服务端代码就写好了。

很少用BD2数据库,一直用SqlServer编译时报了如下警告,不能运行:

在网上搜索了一下:改成了.NET Framwork4,没有后面的Client Profile,就可以用了;这个修改需要右击项目,然后选择其中的属性。

接下来我们编写客户端代码:

与服务端相同一开始是一系列基本工作:创建工程,添加对ICE的引用,拖入编译好的文件

大体结构如下图:

在Form上添加三个控件:

给出完整客户端代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using tableStructFamily;
10
11 namespace FormCli
12 {
13     public partial class Form1 : Form
14     {
15         public Form1()
16         {
17             InitializeComponent();
18         }
19
20         private void btnSendRequestCode_Click(object sender, EventArgs e)
21         {
22             int status = 0;
23             Ice.Communicator ic = null;
24             try
25             {
26                 ic = Ice.Util.initialize();
27                 txtShowMsg.AppendText("初始化成功!\r\n");
28                 Ice.ObjectPrx obj = ic.stringToProxy("tableSelector:default -p 10000");
29                 DoSelectTablePrx selector = DoSelectTablePrxHelper.checkedCast(obj);
30                 if (selector == null)
31                 {
32                     throw new ApplicationException("Invalid proxy");
33                 }
34                 txtShowMsg.AppendText("开始发送请求!\r\n");
35                 DbTableData[] objs = selector.GetDataFromDb("getTable");
36                 txtShowMsg.AppendText("发送请求成功!\r\n");
37
38                 if (objs.Length > 0)
39                 {
40                     txtShowMsg.AppendText("成功获取数据!\r\n");
41                 }
42
43
44                 foreach (DbTableData td in objs)
45                 {
46                     txtShowMsg.AppendText(td.id.ToString() + "\r\n");
47                     txtShowMsg.AppendText(td.nName.ToString() + "\r\n");
48                 }
49
50                 DataTable dt = new DataTable();
51                 dt.Columns.Add("ID");
52                 dt.Columns.Add("Nname");
53                 foreach (DbTableData td in objs)
54                 {
55                     DataRow dr = dt.NewRow();
56                     dr["ID"] = td.id;
57                     dr["Nname"] = td.nName;
58                     dt.Rows.Add(dr);
59                 }
60
61                 dgvShowTable.DataSource = dt;
62
63                 //显示到gridview中
64             }
65             catch (Exception ex)
66             {
67                 MessageBox.Show(ex.ToString());
68                 status = 1;
69             }
70             finally
71             {
72                 if (ic != null)
73                     ic.destroy();
74             }
75             txtShowMsg.AppendText(status.ToString());
76             //Environment.Exit(status);
77         }
78
79     }
80 }

DoSelectTablePrx selector = DoSelectTablePrxHelper.checkedCast(obj);

DbTableData[] objs = selector.GetDataFromDb("getTable");

这两行代码是客户端能获取服务器上数据的关键,客户端与服务器调用相同的函数,通过返回值类型,客户端就能够从服务器上得到返回的数据。

最终运行结果如下:

ICE学习第四步-----客户端请求服务器返回数据

时间: 2024-10-10 12:28:17

ICE学习第四步-----客户端请求服务器返回数据的相关文章

ICE学习第三步-----Slice语言

ICE:Slice语言(一)-编译 Introduce简介 Slice(Specification language for ice)是分离对象和对象的实现的基础的抽象机制.Slice在客户端和服务器端之间建立契约,描述应用程序使用的类型对象的接口.这样的描述是独立于实现功能的语言的,所以服务器和客户端的实现所使用的语言没有任何关系. 编译器将语言无关的定义翻译为特定语言的类型定义和API.这些翻译后的类型定义和API将被使用在应用程序的功能中,以及用来与Ice交互.这种从一种语言无关的定义到各

C# Socket基础(四)之客户端向服务器发消息

private Socket socketClient;//客户端套接字,关于实例化请参考C# Socket基础(三)之客户端连接服务器和接收消息 客户端发送消息 1 /// <summary> 2 /// 发送数据到服务端 3 /// </summary> 4 private void Send() 5 { 6 if (socketClient == null) 7 { 8 9 ShowMsg("服务器未启动!"); 10 return; 11 } 12 by

基于TCP网络通信的自动升级程序源码分析-客户端请求服务器上的升级信息

每次升级,客户端都会获取服务器端存放在upgradefile文件夹下的需要升级的文件和升级信息配置文件(即upgradeconfig.xml文件) 我们来看一下代码 //升级信息配置文件相对应的类 ( 升级信息配置文件是由这个类转化成的) private UpgradeConfig upgradeConfig = null; //客户端存储升级配置文件的地址 是放在客户端根目录下的 (就是把服务器 upgradefile/upgradeconfig.xml下载到客户端存放的位置) string

android客户端与服务器交互数据(基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合)

在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,做过JAVA ME的人都知道有KSOAP这个第三方的类库,可以帮助我们获取服务器端webService调用,当然KSOAP已经提供了基于android版本的jar包 首先下载KSOAP包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar包 然后新建android项目 以

使用getJSON()异步请求服务器返回json格式数据

我们可以使用jquery的getJSON()方法请求服务器返回json格式数据: js代码: function test(){ $.getJSON("JsonServlet",function(result){ alert(result.name); }); } 服务器端servlet响应: @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletEx

Postman----模拟服务器返回数据

使用场景:在某些情况下,比如A接口还没开发好,我们需要测试B接口,刚好B接口的请求数据中需要包含A接口返回的数据,这时我们就可以模拟A接口服务器返回的数据来测试B接口 解决办法: 举例:模拟此 https://t.app.goodiber.com/api/todo/month-list的服务器返回数据 1.添加一个Examples 点击"Add Example"之后出现的页面如下,根据标出的步骤分别根据实际需要进行填写. 添加完Example返回,可看到页面如下. 2.添加Mock 创

MongoDB学习(四)客户端工具备份数据库

在上一篇MongoDB学习(三)中讲解了如何在服务器端进行数据的导入导出与备份恢复,本篇介绍下如何利用客户端工具来进行远程服务器的数据备份到本地. 以客户端工具MongoVUE为例来进行讲解: 1.首先要连接本地服务器以及远程服务器数据库 2.在本地服务器(127.0.0.1)中,右键Add Database,弹出框中输入数据库名称,如下图: 注:要先在本地服务器中添加数据库,以备导出时要用. 3.选中要导出服务器(192.168.5.117)中的数据库(iflashbuy-log),右键Cop

Java实验四 TCP客户端和服务器的应用

实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全 4.对通信内容进行摘要计算并验证 实验步骤 1.信息安全传送: 发送方A——————>接收方B A加密时,用B的公钥 B解密时,用B的私钥 发送方A对信息(明文)采用DES密钥加密,使用RSA加密前面的DES密钥信息,最终将混合信息进行传递.同时用hash函数将明文进行用作验证.    接收方B接收到信息后,用RSA解密DES密钥信息,再用RSA解密获取到的密钥信息解密密文信息,最终就可以得到我们要的信息(明文)

分布式数据库数据从属与客户端与服务器的数据同步

老实说,目前市面上许多产品,的确是不成熟的产品. 用过一些,给人蛋痛的感觉. 导言 分布还是集总 今天我们来探讨一个很重要的问题. 每个程序员都有其思想,我的思想之一,就是分布式. 分布式,面对的一个问题,就数据的同步. 比如说,我们人类是分布式的,我们每个细胞都在无时无刻与其它细脑交换数据. 而现实世界,我们的设计是什么样子?一般都是集总式. 首先来说,这种方式,与现实世界并不一致.所以,带来的最严重的一个影响就是效率的问题. 自己这些年,一直在无线通信领域. 无线通信,有两个重要的特点: 1