Smart Client 离线数据


Smart Client 我想大家都知道吧,它是Microsoft 最近推出的一种将 B/S 和 C/S 结合在一起的一种技术,叫智能客户端。在 Smart Client 中有很多新的技术,离线数据就是其中之一,对于离线数据操作我们可以有很多方法,如:数据库同步、隔离存储区、消息队列。


一、数据库同步要求在客户端也安装个应用数据库并保持与服务器应用数据库同步。

二、隔离存储区就是运用Smart Client的新技术在客户端单独开辟一块空间用来存储离线状态下的数据。
1、需要添加引用

  1. using System.IO; 
  2. // 该命名空间下的类均是对隔离存储区进行操作的
  3. using System.IO.IsolatedStorage;


2、对隔离存储区的操作如下 CacheHelper 类
  1. class CacheHelper
  2. {
  3.     public static void WriteDataSetToIsolatedStorage(DataSet data, string fileName)
  4.     {
  5.          // 获取与调用代码的程序集标识对应的用户范围的独立存储
  6.          IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForAssembly(); 
  7.          // IsolatedStorageFileStream 公开独立存储中的文件
  8.          using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(fileName, FileMode.Create, isoStore))
  9.          {
  10.              using (StreamWriter writer = new StreamWriter(isoStream))
  11.              {
  12.                  data.WriteXML(writer, XMLWriteMode.DiffGram);
  13.              }
  14.           }
  15.      }
  16.      public static void ReadDataSetFromIsolatedStorage(DataSet data, string fileName)
  17.      {
  18.          IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForAssembly();
  19.          using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(fileName, FileMode.Open, isoStore))
  20.          {
  21.              using (StreamReader reader = new StreamReader(isoStream))
  22.              {
  23.                   data.ReadXML(reader, XMLReadMode.DiffGram);
  24.               }
  25.           }
  26.       }
  27. }
3、在提交数据前还要检测网络是否联接,这就需要添加其他引用
  1. using System.Net;
  2. using System.Net.NetworkInformation;
4、具体的判断是否网络联接代码如下
  1. private void OnAddressChanged(object sender, EventArgs e)
  2. {
  3.     bool connected = IsOnline();
  4.     if (InvokeRequired)
  5.     {
  6.         // 此处是个委托
  7.         SetStatus del = delegate(bool status)
  8.         {
  9.             UpdateStatus(status);
  10.         };
  11.         Invoke(del, new object[] { connected });
  12.     }
  13.     else
  14.     {
  15.         UpdateStatus(connected);
  16.     }
  17. }

  18. private void UpdateStatus(bool connected)
  19. {
  20.     if (connected)
  21.     {
  22.           ………………
  23.     }
  24.     else
  25.     {
  26.           ………………
  27.     }
  28. }

  29. private bool IsOnline()
  30. {
  31.     NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
  32.     foreach (NetworkInterface adapter in adapters)
  33.     {
  34.         IPInterfaceProperties properties = adapter.GetIPProperties();
  35.         // 判断网络是否连接
  36.         if (adapter.OperationalStatus != OperationalStatus.Up)
  37.         {
  38.             continue;
  39.         }

  40.         // 获取此连接的单播地址
  41.         UnicastIPAddressInformationCollection addressCollection = properties.UnicastAddresses;
  42.         foreach (UnicastIPAddressInformation addressInfo in addressCollection)
  43.         {
  44.              // 是否本地地址 如 127.0.0.1
  45.              if (IPAddress.IsLoopback(addressInfo.Address))
  46.              {
  47.                  continue;
  48.              }
  49.              if (addressInfo.Address.ToString() == IPAddress.IPv6None.ToString())
  50.              {
  51.                  continue;
  52.              }
  53.              if (addressInfo.ToString() == IPAddress.None.ToString())
  54.              {
  55.                  continue;
  56.              }
  57.              return true;
  58.          }
  59.      }
  60.      return false;
  61. }

  62. delegate void SetStatus(bool status);
5、在网络正常联接时,你可以安部就班的做正常应该做的操作。如果没联接则要调用 CacheHelper 的方法对隔离存储区进行操作,也就 WriteDataSetToIsolatedStorage 和 ReadDataSetFromIsolatedStorage 方法。

三、消息队列
1、要求客户端和服务器端都添加了“消息队列”这一Windows 组件。
2、在应用程序中需要引用 System.Messaging;这一命名空间。
3、然后在向服务器提交时创建一个消息队列
  1. MessageQueue mq = new MessageQueue("s1p3//MQTest"falsetrue);
MessageQueue 类有6个构造函数,我这只是用了其中的一种
"s1p3//MQTest" 指的是该消息队列将要发送到哪里
消息队列大致可以分为3种类型:
  1. 1、公共队列
  2. 2、专用队列
  3. 3、日志队列
这3种队列的写法也有所区别
  1. 公共队列        MachineName/QueueName
  2. 专用队列        MachineName/Private$/QueueName
  3. 日志队列        MachineName/QueueName/Journal$
  4. MachineName  表示你要发送给哪台计算机,如果是本机 MachineName 可以用点号“.”
  5. QueueName     表示该计算机中的队列名称
  6. Private$ 和 Journal$ 是固定的,无需要更改
程序中常用到的也就是 “公共队列”和“专用队列”,而且其中又以“专用队列”占绝大多数。

4、消息队列有了,接下来就要涉及到消息了
我从很多资料上看到都要用到 System.Messaging.Message 类(注:不是 System.Windows.Forms.Message 类,要注意区分)
一般都是这样写的
  1. System.Messaging.Message m = new System.Messaging.Message();
然后就是设置 Message 的属性,如:
  1. MessageName.body = ojbect;
  2. MessageName.Formatter = ……
  3. ………………
5、最后 MessageQueueName.Send(MessageName);
如果你仔细点,就会注意到 MessageQueue 类的 Send() 方法里要求的参数是一个 object
所以我就尝试了一下把我要发送的内容直接当作参数,一试果然成功
当然这只是一种比较省事的做法,相对应的对该内容的一些属性参考就要被忽略了
6、当 Send() 完毕后记得把消息队列关闭哦
  1. MessageQueueName.Close();
7、如果网络通的话,消息队列会自动发送;如果网络不通的话,消息队列会保存在客户端,等到网络重新联接时消息队列会自动发送。
8、消息发送完了,就要在服务器端去接收了。获得消息的方法有几种。如:
  1. GetAllMessage()
  2. Receive() 
等。
我们从 GetAllMessage() 字面上不难看出该方法是获取所有的消息队列,而 Receive() 只是对单个消息获取。在实际应用中 GetAllMessage() 方法更切实际点。
  1. MessageQueue mq = new MessageQueue(".//MQTest");
  2. mq.Formatter = new XMLMessageFormatter(new Type[] { typeof(object) });
  3. try
  4. {
  5.     // 获取消息队列中的所有消息
  6.     System.Messaging.Message [] mss = mq.GetAllMessages(); 
  7.     // 循环所有的消息
  8.     foreach (System.Messaging.Message ms in mss) 
  9.     {
  10.         mq.Receive();
  11.         ………………           
  12.      }
  13. }
  14. catch
  15. {
  16. }
如果用 GetAllMessage() 方法的话,记得在每次获取单个消息后调用 Receive() 方法。
9、从消息中获取相应的信息,就可以对系统进行下一步操作了。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值