ICE学习第四步-----客户端请求服务器返回数据
这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上。
根据上一篇文章介绍的Slice语法,我们先来定义ICE文件。我定义两个ICE文件,一个用来描述测试数据库表中属性相关信息,另一个则是请求数据的方法。
结构如下:

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

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

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

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

给出这几个类的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleSer.common
{
public class DbData
{
public string dataName;//数据库中列名
public object dataValue;//数据库中列值
} public class DbDataList
{
public IList<DbData> dataRow;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleSer.common;
using IBM.Data.DB2;
using System.Data; namespace ConsoleSer.database
{
public class Db2:DbMain
{
public override IList<DbDataList> GetDataFromDatabase(string strSql)
{
IList<DbDataList> list = new List<DbDataList>(); using (DB2Connection con = new DB2Connection("server=127.0.0.1;database=TEST;uid=db2admin;pwd=db2admin;"))
{
con.Open();
DB2DataAdapter oda = new DB2DataAdapter(strSql, con);
DataSet ds = new DataSet();
oda.Fill(ds);
if (ds.Tables.Count > )
{
DataTable dt = ds.Tables[];
for (int i = ; i < dt.Rows.Count; i++)
{
IList<DbData> rowsData = new List<DbData>();
for (int j = ; j < dt.Columns.Count; j++)
{
DbData data = new DbData();
data.dataName = dt.Columns[j].ColumnName;
data.dataValue = dt.Rows[i][data.dataName];
rowsData.Add(data);
}
DbDataList rows = new DbDataList();
rows.dataRow = rowsData;
list.Add(rows);
}
}
}
return list;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleSer.common; namespace ConsoleSer.database
{
public class DbMain
{
public virtual IList<DbDataList> GetDataFromDatabase(string strSql)
{
IList<DbDataList> list = new List<DbDataList>();
return list;
}
}
}
最终查询完数据库返回的是这样的一条数据:(IList<DbDataList> list = new List<DbDataList>(); DbDataList包含两个字段string dataName;object dataValue;)

但是这并不是我们想要的返回类型,我们再将其转换为DbTableData类型数组,于是在TestTableMethodI实现类中有如下代码(假设客户端请求字符串是getTable):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using tableStructFamily;
using ConsoleSer.common;
using ConsoleSer.database; namespace ConsoleSer.slice2csI
{
class TestTableMethodI:DoSelectTableDisp_
{
public static List<DbTableData> tbData = new List<DbTableData>();//数据库中表信息
private static DbMain dbObject = new Db2(); public override DbTableData[] getDataFromDb(string requestCode, Ice.Current current__)
{
if (requestCode == "getTable")
{
Console.WriteLine("收到请求!");
return selectDataFromDb();
}
else
{
throw new Exception();
}
} private DbTableData[] selectDataFromDb()
{
IList<DbDataList> list = dbObject.GetDataFromDatabase("select * from A.T_test"); DbTableData[] objs = new DbTableData[list.Count]; for (int i = ; i < list.Count; i++)
{
DbDataList row = list[i];
DbTableData obj = GetTableObj(row);
tbData.Add(obj);
objs[i] = obj;
}
return objs;
} private DbTableData GetTableObj(DbDataList dataRow)
{
DbTableData obj = new DbTableData();
for (int i = ; i < dataRow.dataRow.Count; i++)
{
DbData data = dataRow.dataRow[i];
setObjValue(data, ref obj);
}
return obj;
} private void setObjValue(DbData data, ref DbTableData obj)
{
string name = data.dataName.ToLower();
switch (name)
{
case "id":
obj.ID = Convert.ToInt32(data.dataValue);
break;
case "nname":
obj.Nname = data.dataValue.ToString();
break;
default:
break;
}
}
}
}
附上Main函数初始化ICE的方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using tableStructFamily; namespace ConsoleTestIceServer
{
class Program
{
static void Main(string[] args)
{
int status = ;
Ice.Communicator ic = null;
try
{
ic = Ice.Util.initialize(ref args);
Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("tableSelector", "default -p 10000");
Ice.Object obj = new ConsoleSer.slice2csI.TestTableMethodI();
adapter.add(obj, Ice.Util.stringToIdentity("tableSelector"));
adapter.activate();
Console.WriteLine("初始化成功!");
ic.waitForShutdown();
}
catch (Exception e)
{
Console.Error.WriteLine(e);
status = ;
}
finally
{
if (ic != null)
{
ic.destroy();
}
}
Environment.Exit(status);
}
}
}
如此一来服务端代码就写好了。
很少用BD2数据库,一直用SqlServer编译时报了如下警告,不能运行:

在网上搜索了一下:改成了.NET Framwork4,没有后面的Client Profile,就可以用了;这个修改需要右击项目,然后选择其中的属性。
接下来我们编写客户端代码:
与服务端相同一开始是一系列基本工作:创建工程,添加对ICE的引用,拖入编译好的文件
大体结构如下图:

在Form上添加三个控件:

给出完整客户端代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using tableStructFamily; namespace FormCli
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void btnSendRequestCode_Click(object sender, EventArgs e)
{
int status = ;
Ice.Communicator ic = null;
try
{
ic = Ice.Util.initialize();
txtShowMsg.AppendText("初始化成功!\r\n");
Ice.ObjectPrx obj = ic.stringToProxy("tableSelector:default -p 10000");
DoSelectTablePrx selector = DoSelectTablePrxHelper.checkedCast(obj);
if (selector == null)
{
throw new ApplicationException("Invalid proxy");
}
txtShowMsg.AppendText("开始发送请求!\r\n");
DbTableData[] objs = selector.GetDataFromDb("getTable");
txtShowMsg.AppendText("发送请求成功!\r\n"); if (objs.Length > )
{
txtShowMsg.AppendText("成功获取数据!\r\n");
} foreach (DbTableData td in objs)
{
txtShowMsg.AppendText(td.id.ToString() + "\r\n");
txtShowMsg.AppendText(td.nName.ToString() + "\r\n");
} DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Nname");
foreach (DbTableData td in objs)
{
DataRow dr = dt.NewRow();
dr["ID"] = td.id;
dr["Nname"] = td.nName;
dt.Rows.Add(dr);
} dgvShowTable.DataSource = dt; //显示到gridview中
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
status = ;
}
finally
{
if (ic != null)
ic.destroy();
}
txtShowMsg.AppendText(status.ToString());
//Environment.Exit(status);
} }
}
DoSelectTablePrx selector = DoSelectTablePrxHelper.checkedCast(obj);
DbTableData[] objs = selector.GetDataFromDb("getTable");
这两行代码是客户端能获取服务器上数据的关键,客户端与服务器调用相同的函数,通过返回值类型,客户端就能够从服务器上得到返回的数据。
最终运行结果如下:

ICE学习第四步-----客户端请求服务器返回数据的更多相关文章
- Koa2学习(四)POST请求
Koa2学习(四)POST请求 接受请求 POST请求的数据实体,会根据数据量的大小进行分包传送. 当node.js后台收到post请求时,会以buffer的形式将数据缓存起来.Koa2中通过ctx. ...
- C# FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址。"的错误
FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址."的错误 解决方法是在原代码上增加这句话 reqFTP.UsePassive = f ...
- Postman----模拟服务器返回数据
使用场景:在某些情况下,比如A接口还没开发好,我们需要测试B接口,刚好B接口的请求数据中需要包含A接口返回的数据,这时我们就可以模拟A接口服务器返回的数据来测试B接口 解决办法: 举例:模拟此 htt ...
- 02 - Unit01:服务器返回数据的json处理+搭建项目环境
服务器返回数据的json处理+搭建项目环境 服务器返回数据的json处理 springMVC JSP响应流程 请求 -->DispatcherServlet -->HandlerMappi ...
- js进阶ajax读取json数据(ajax读取json和读取普通文本,和获取服务器返回数据(链接)都是一样的,在url处放上json文件的地址即可)
js进阶ajax读取json数据(ajax读取json和读取普通文本,和获取服务器返回数据(链接)都是一样的,在url处放上json文件的地址即可) 一.总结 ajax读取json和读取普通文本,和获 ...
- asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。
原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...
- charles技能之修改请求参数/返回数据(map Local、Rewrite、Breakpoints)
之前一直用postman调接口比较多,但有时候想要去修改APP的页面展示,造数据又会比较麻烦,此时可以用以下三种方法修改请求参数或修改响应: map Local(本地映射).Breakpoints(打 ...
- ICE学习第三步-----Slice语言
ICE:Slice语言(一)-编译 Introduce简介 Slice(Specification language for ice)是分离对象和对象的实现的基础的抽象机制.Slice在客户端和服务器 ...
- MongoDB学习(四)客户端工具备份数据库
在上一篇MongoDB学习(三)中讲解了如何在服务器端进行数据的导入导出与备份恢复,本篇介绍下如何利用客户端工具来进行远程服务器的数据备份到本地. 以客户端工具MongoVUE为例来进行讲解: 1.首 ...
随机推荐
- php获取客户端ip get_client_ip()
php获取客户端ip get_client_ip() function get_client_ip(){if (getenv("HTTP_CLIENT_IP") && ...
- OFFSET & FETCH
OFFSET & FECTH 关键字与ORDER BY结合使用,实现对查询结果的分页 一.单独使用OFFSET: 示例:查询所有职员的信息,按雇佣日期排序并跳过前285条记录(共290条) U ...
- 3D FPS游戏中Player摄像机的运动
最近遇到一些类似3D FPS的game play.针对这里面Player摄像机的运动的问题,随便总结一些东西以备参考.首先,对问题做一些的假设: Player摄像机在多数情况下在场景中的位置是固定的, ...
- uvalive4513
https://vjudge.net/problem/UVALive-4513 终于做出来了......... 各种sb错误,最后对拍出来了,还没改对..................... 快半天 ...
- java代码实现对excel加密、解密(设置或去除打开密码)
使用jxcell组件来完成对excel加密.解密的功能. jxcell.jar[点击下载](此jar没有使用限制,你懂得) 具体代码如下: import java.io.IOException; im ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(5)-EF增删改查by糟糕的代码
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(5)-EF增删改查by糟糕的代码 上一讲我们创建了一系列的解决方案,我们通过一个例子来看看层与层之间的关系 ...
- 吐槽一下CSDN的封停审查机制
今天和一同学用私信交流,我回答中用了"春季zhaopin"这几个字(大家知道是哪两个字),结果提示我内容非法无法发送,我立即改动用了谐音发了过去.结果我出来一看,显示我的个人主页 ...
- QT+QT creator+OpenCV图像灰度化
1).pro文件 #------------------------------------------------- # # Project created by QtCreator 2014-05 ...
- cocos2dx实现android的对讯飞语音的合成(语言朗读的实现)
事实上非常easy,只是有些细节须要注意. 关于讯飞语音在android上的应用,大家须要自己去下载SDK,然后依照讯飞语音提供的api在自己的android的Demo上执行成功,那东西也相当的简单. ...
- [转] Node.js 服务端实践之 GraphQL 初探
https://medium.com/the-graphqlhub/your-first-graphql-server-3c766ab4f0a2#.n88wyan4e 0.问题来了 DT 时代,各种业 ...