• 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("初始化成功!
    ");
    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("开始发送请求!
    ");
    35                 DbTableData[] objs = selector.GetDataFromDb("getTable");
    36                 txtShowMsg.AppendText("发送请求成功!
    ");
    37 
    38                 if (objs.Length > 0)
    39                 {
    40                     txtShowMsg.AppendText("成功获取数据!
    ");
    41                 }
    42 
    43 
    44                 foreach (DbTableData td in objs)
    45                 {
    46                     txtShowMsg.AppendText(td.id.ToString() + "
    ");
    47                     txtShowMsg.AppendText(td.nName.ToString() + "
    ");
    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");

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

    最终运行结果如下:

  • 相关阅读:
    [持续更新] ERP学习资源
    How to: Use a Windows Communication Foundation Client
    Overview of SOAP Client in Windows XP
    WSDL Overview
    How to: Configure a Basic Windows Communication Foundation Client
    Hosting Windows Communication Foundation Services
    Specifying an Endpoint Address
    Endpoint Creation Overview
    Implementing Service Contracts
    A Quick Introduction to WSDL
  • 原文地址:https://www.cnblogs.com/T-J-D/p/3867459.html
Copyright © 2020-2023  润新知