数据交换,纠结于Remoting和webservices
项目背景:
连锁店各分支机构与总部数据交换,比如某公司总部在北京:有一服务器MastServer,在全国各地有分支机构,如武汉,上海,河北。。。。
现在各分支机构需要将其营业数据上传总部,服务器MastServer,同时需要从总部服务器MastServer下载数据
我的初步想法是用Remoting或webservices来做通讯桥梁,然后利用FTP方式上传,下载文件,这里我比较纠结:
1、到底是用Remoting还是webservices
2、Remoting和webservices的区别
3、如果用Remoting方式处理,那么该如何写,以前没接触过这个技术
[解决办法]
Remoting和webservices做的事情差不多,都是远程调用(RPC),但是在通讯过程中实现的标准不同,Remoting是微软独有的技术,和其它平台的互操作兼容性要差一些,性能好一些,使用不如webservices那么广泛。webservices并非性能不好,只是说它在通讯本身的开销会大一些。
[解决办法]
我推荐你使用webservices,这样可以和其他平台客户端交互
[解决办法]
两个有不同的基础和假设。在微软平台,以前remoting是非常流行、非常稳定、非常方便好用的技术,它的编程方式非常类似于普通的基于class的编程,甚至事件回调机制也非常类似于普通的event调用(只不过需要自己多设计一个中间代理对象)。之后慢慢地也使用开了webservice(asmx),一方面是因为大力宣传这种东西是“未来的趋势”,另一方面从技术上说当时更多地是强调“无状态的服务器集群”方式(也就是说,服务器可以随时重启、可以随时负载均衡到其它主机),而且(比较实际地是)强调webservice方式支持服务器端随时可以更新数据实体的Class定义(例如增加或者删除属性)而客户端并不需要立刻同步地重新编译系统。
在我们追逐(当时)时髦地使用web service之前,对于remoting都是很熟悉的。其实不论是remoting还是web service,都是为了方便于通讯程序的初学者而设计的,它们通过许多层次地反复自动化封装,而让初学者少理解一些知识而更容易上手。
不过在比较专业的、稍微大一些的系统那里,始终是基于tcp/http方式的简单通讯为主,那是几十年不变的。比如说你可以试试看,使用简单的WebClient(或者HttpRequest)来Upload/Download一个string或者byte[]也不算困难。而数据可以采用xml或者json或者自定义协议。
一个人如果认为“将对象序列化/反序列化为json”是很麻烦的,那么就使用简单容易上手的wcf吧。不过这对性能和概念股能要求稍微高一点的稍微专业的“客户-服务器”开发来说,显然是“先甜后苦”的。
在自己的服务器设计方面,一个windows service工程中可以集成TcpListener、UdpClient(作为服务器)、HttpListener、ServiceHost、NamedPipeServerStream等,可以实现短连接、长链接等等不同的机制,可以最大限度、最轻量级地使用异步多线程处理方式来处理命令。如果你有几种服务器端构建方式都可以支持相同的面向业务领域而设计的信令协议,你就能对比出来差异,基本上WCF很适合给开发客户端的初学者能够快速上手而用(因为性能和功能扩展性降低了至少1倍)。而remoting跟有点异类,跟上述所有的机制都不在同一层层次上(remoting是非常复杂的rpc封装,现在看算是过度复杂了),尽管remoting非常棒,还是不大希望再花精力去维护和编程。
[解决办法]
该回复于2012-10-10 09:10:51被版主删除
[解决办法]
听说Remoting可以穿越防火墙
[解决办法]
我的Remotine的 代码如下:
private DataTable m_dt;
private bool m_exitFlag = false;
public Server()
{
InitializeComponent();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.m_exitFlag == true)
{
//强行退出线程
jcMy.TranFileRemoting.TranFileRemoting.Stop(true);
}
else
{
this.WindowState = FormWindowState.Minimized;
e.Cancel = true;
}
}
private void Form1_Load(object sender, EventArgs e)
{
//配置服务,线程访问数据库服务器的时间间隔(毫秒)
//TranFileRemoting.Start("eCTransRemoteServer.exe.config", eCMy.RemotingServer.Properties.Settings.Default.ThreadInterval);//("TestServer.exe.config");
//TranFileRemoting.Start("eCTransRemoteServer.exe.config",1000);//("TestServer.exe.config");
TranFileRemoting.Start("jcTransRemoteServer.exe.config", jCMy.RemotingServer.Properties.Settings.Default.ThreadInterval);
//跨线程访问FORM
ListBox.CheckForIllegalCrossThreadCalls = false;
//添加事件处理
CheckRequest.NotifyServerEvent+=new CheckRequest.NotifyServerDele(CheckRequest_NotifyServerEvent);
//设置下载文件时,为每个客户端生成的"远程调用类"访问"共享字典"的时间间隔(毫秒)
DownLoadFile.SetIntervalTime(jCMy.RemotingServer.Properties.Settings.Default.RemotingInterval);
this.Ntfy.Text = "ecSun远程通信中心服务 v5.0";
this.WindowState = FormWindowState.Minimized;
this.IniGridView();
}
private void IniGridView()
{
//生成一张数据表
this.m_dt = new DataTable();
m_dt.Columns.Add("GUID");
m_dt.Columns.Add("shopNumber");
m_dt.Columns.Add("tranFileType");
m_dt.Columns.Add("actionType");
m_dt.Columns.Add("time");
this.Gv.DataSource = m_dt;
this.Gv.Columns[0].HeaderText = "全局唯一标识";
this.Gv.Columns[1].HeaderText = "分店号";
this.Gv.Columns[2].HeaderText = "操作类型";
this.Gv.Columns[3].HeaderText = "状态或文件名";
this.Gv.Columns[4].HeaderText = "时间";
this.Gv.Columns["GUID"].Visible = false;
}
private void CheckRequest_NotifyServerEvent(TranFileType tranFileType, ActionType actionType, string message)
{
//string showMsg;
if (this.WindowState == FormWindowState.Maximized ) //最大化才显示
{
string[] strMsg = message.Split(new char[] { CheckRequest.SPLITORCHAR });
string guid = strMsg[strMsg.Length - 1];
if (tranFileType == TranFileType.DownLoadFile)
{
string strState = null;
//判断下载文件的状态
switch (strMsg[0])
{
case CheckRequest.DOING:
strState = "正在准备数据";
break;
case CheckRequest.DONE:
strState = "准备数据已完成";
break;
case CheckRequest.ERROR:
strState = "准备数据出错";
break;
}
//查找数据表中是否有此记录,如果有则更新其状态,否则添加记录
DataRow[] dr = m_dt.Select("GUID='" + guid + "'");
if (dr.Length > 0)
{
dr[0]["actionType"] = strState;
dr[0]["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
else
{
//添加记录
DataRow dRow = m_dt.NewRow();
dRow["GUID"] = guid;
dRow["shopNumber"] = strMsg[1];
dRow["tranFileType"] = "下载文件";
dRow["actionType"] = strState;
dRow["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
m_dt.Rows.Add(dRow);
}
//showMsg = "操作:下载文件"+" 状态:" + strMsg[0] + " 分店号:" + strMsg[1] + " 数据类型:" + strMsg[2] + " 开始时间:" + strMsg[3] + " 结束时间:" + strMsg[4] + " IP:" + strMsg[5];
}
else
{
//添加记录
DataRow dRow = m_dt.NewRow();
dRow["GUID"] = guid;
dRow["shopNumber"] = strMsg[0];
dRow["tranFileType"] = "上传文件";
dRow["actionType"] = strMsg[1];
dRow["time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
m_dt.Rows.Add(dRow);
//showMsg = "操作:上传文件"+ " 分店号:" + strMsg[0] + " 文件名:" + strMsg[1];
}
}
}
private void Server_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
//this.ShowInTaskbar = false;
this.Visible = false;
}
}
private void Ntfy_DoubleClick(object sender, EventArgs e)
{
this.Visible = true;
//this.ShowInTaskbar = true;
this.Activate();
this.WindowState = FormWindowState.Maximized;
}
private void Tlm_exit_Click(object sender, EventArgs e)
{
if (MessageBox.Show("确定要退出文件远程服务?", "系统消息", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
this.m_exitFlag = true;
this.Close();
}
}
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
ModifyConnectin vSetFrm=new ModifyConnectin ();
vSetFrm.ShowDialog();
}
[解决办法]
客户端调用:
public Client()
{
InitializeComponent();
}
private string m_resultState = null;
private void CallBack_ThreadFun()
{
MessageBox.Show("CallBack_ThreadFun");
this.Text = m_resultState;
}
private void OnCallBack_DownLoadFile(IAsyncResult asResult)
{
//强制转化接口为类
AsyncResult res = (AsyncResult)asResult;
DownLoadFileDelegate msgdele = (DownLoadFileDelegate)res.AsyncDelegate;
//结束异步代理释放资源
string strResult = msgdele.EndInvoke(asResult);
//this.listBox1.Items.Add("结果:" + strResult);
//启动一线程来操作FORM
m_resultState = strResult;
Thread thdCallBack = new Thread(new ThreadStart(CallBack_ThreadFun));
thdCallBack.Start();
}
private void btn_start_Click(object sender, EventArgs e)
{
//DownLoadFile obj = new DownLoadFile();
//jcMy.ITranFileRemoting.IDownLoadFile obj = (IDownLoadFile)Activator.GetObject(typeof(IDownLoadFile), "http://yiduochaoshi001.gicp.net:16791/TranFileRemoting/DownLoadFile");
jcMy.ITranFileRemoting.IDownLoadFile obj = (IDownLoadFile)Activator.GetObject(typeof(IDownLoadFile), "http://192.168.1.200:16791/TranFileRemoting/DownLoadFile");
if (obj == null)
{
MessageBox.Show("could not locate server");
return;
}
//显示租约信息
//ILease lease = (ILease)obj.GetLifetimeService();
//if (lease != null)
//{
// Console.WriteLine("Lease Config");
// Console.WriteLine("initialLeaseTime:" + lease.InitialLeaseTime);
// Console.WriteLine("renewOnCallTime:" + lease.RenewOnCallTime);
//}
DownLoadFileDelegate d = new DownLoadFileDelegate(obj.BeginDownLoad);
IAsyncResult iar = d.BeginInvoke(this.tb_shopNumber.Text, this.tb_dataType.Text, this.dp_startTime.Value.ToString("yyyy-MM-dd HH:mm:ss"), this.dp_endTime.Value.ToString("yyyy-MM-dd HH:mm:ss"), "192.168.1.200", new AsyncCallback(OnCallBack_DownLoadFile), null);
this.listBox1.Items.Add("正在等待服务器返回结果");
}
private void Form1_Load(object sender, EventArgs e)
{
//RemotingConfiguration.Configure("ClientRemote.config",false);
RemotingConfiguration.Configure("TestClient.exe.config", false);
//ListBox.CheckForIllegalCrossThreadCalls = false;
Form.CheckForIllegalCrossThreadCalls = false;
}
private void btn_upload_Click(object sender, EventArgs e)
{
//eCMy.TranFileRemoting.IUpLoadFile obj = new UpLoadFile();
jcMy.ITranFileRemoting.IUpLoadFile obj = (IUpLoadFile)Activator.GetObject(typeof(IUpLoadFile), "http://192.168.1.200:16791/TranFileRemoting/UpLoadFile");
if (obj != null)
{
//显示租约信息
//ILease lease = (ILease)obj.GetLifetimeService();
//if (lease != null)
//{
// Console.WriteLine("Lease Config");
// Console.WriteLine("initialLeaseTime:" + lease.InitialLeaseTime);
// Console.WriteLine("renewOnCallTime:" + lease.RenewOnCallTime);
//}
string result=obj.BeginUpLoad(this.tb_shopNumber.Text, this.tb_fileName.Text);
if (result == "true")
MessageBox.Show("上传数据完成");
else
MessageBox.Show(result);
}
}