Smart Client 我想大家都知道吧,它是Microsoft 最近推出的一种将 B/S 和 C/S 结合在一起的一种技术,叫智能客户端。在 Smart Client 中有很多新的技术,离线数据就是其中之一,对于离线数据操作我们可以有很多方法,如:数据库同步、隔离存储区、消息队列。
一、数据库同步要求在客户端也安装个应用数据库并保持与服务器应用数据库同步。
二、隔离存储区就是运用Smart Client的新技术在客户端单独开辟一块空间用来存储离线状态下的数据。
1、需要添加引用
- using System.IO;
- // 该命名空间下的类均是对隔离存储区进行操作的
- using System.IO.IsolatedStorage;
2、对隔离存储区的操作如下 CacheHelper 类
- class CacheHelper
- {
- public static void WriteDataSetToIsolatedStorage(DataSet data, string fileName)
- {
- // 获取与调用代码的程序集标识对应的用户范围的独立存储
- IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForAssembly();
- // IsolatedStorageFileStream 公开独立存储中的文件
- using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(fileName, FileMode.Create, isoStore))
- {
- using (StreamWriter writer = new StreamWriter(isoStream))
- {
- data.WriteXML(writer, XMLWriteMode.DiffGram);
- }
- }
- }
- public static void ReadDataSetFromIsolatedStorage(DataSet data, string fileName)
- {
- IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForAssembly();
- using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(fileName, FileMode.Open, isoStore))
- {
- using (StreamReader reader = new StreamReader(isoStream))
- {
- data.ReadXML(reader, XMLReadMode.DiffGram);
- }
- }
- }
- }
- using System.Net;
- using System.Net.NetworkInformation;
- private void OnAddressChanged(object sender, EventArgs e)
- {
- bool connected = IsOnline();
- if (InvokeRequired)
- {
- // 此处是个委托
- SetStatus del = delegate(bool status)
- {
- UpdateStatus(status);
- };
- Invoke(del, new object[] { connected });
- }
- else
- {
- UpdateStatus(connected);
- }
- }
- private void UpdateStatus(bool connected)
- {
- if (connected)
- {
- ………………
- }
- else
- {
- ………………
- }
- }
- private bool IsOnline()
- {
- NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
- foreach (NetworkInterface adapter in adapters)
- {
- IPInterfaceProperties properties = adapter.GetIPProperties();
- // 判断网络是否连接
- if (adapter.OperationalStatus != OperationalStatus.Up)
- {
- continue;
- }
- // 获取此连接的单播地址
- UnicastIPAddressInformationCollection addressCollection = properties.UnicastAddresses;
- foreach (UnicastIPAddressInformation addressInfo in addressCollection)
- {
- // 是否本地地址 如 127.0.0.1
- if (IPAddress.IsLoopback(addressInfo.Address))
- {
- continue;
- }
- if (addressInfo.Address.ToString() == IPAddress.IPv6None.ToString())
- {
- continue;
- }
- if (addressInfo.ToString() == IPAddress.None.ToString())
- {
- continue;
- }
- return true;
- }
- }
- return false;
- }
- delegate void SetStatus(bool status);
三、消息队列
1、要求客户端和服务器端都添加了“消息队列”这一Windows 组件。
2、在应用程序中需要引用 System.Messaging;这一命名空间。
3、然后在向服务器提交时创建一个消息队列
- MessageQueue mq = new MessageQueue("s1p3//MQTest", false, true);
"s1p3//MQTest" 指的是该消息队列将要发送到哪里
消息队列大致可以分为3种类型:
- 1、公共队列
- 2、专用队列
- 3、日志队列
- 公共队列 MachineName/QueueName
- 专用队列 MachineName/Private$/QueueName
- 日志队列 MachineName/QueueName/Journal$
- MachineName 表示你要发送给哪台计算机,如果是本机 MachineName 可以用点号“.”
- QueueName 表示该计算机中的队列名称
- Private$ 和 Journal$ 是固定的,无需要更改
4、消息队列有了,接下来就要涉及到消息了
我从很多资料上看到都要用到 System.Messaging.Message 类(注:不是 System.Windows.Forms.Message 类,要注意区分)
一般都是这样写的
- System.Messaging.Message m = new System.Messaging.Message();
- MessageName.body = ojbect;
- MessageName.Formatter = ……
- ………………
如果你仔细点,就会注意到 MessageQueue 类的 Send() 方法里要求的参数是一个 object
所以我就尝试了一下把我要发送的内容直接当作参数,一试果然成功
当然这只是一种比较省事的做法,相对应的对该内容的一些属性参考就要被忽略了
6、当 Send() 完毕后记得把消息队列关闭哦
- MessageQueueName.Close();
8、消息发送完了,就要在服务器端去接收了。获得消息的方法有几种。如:
- GetAllMessage()
- Receive()
我们从 GetAllMessage() 字面上不难看出该方法是获取所有的消息队列,而 Receive() 只是对单个消息获取。在实际应用中 GetAllMessage() 方法更切实际点。
- MessageQueue mq = new MessageQueue(".//MQTest");
- mq.Formatter = new XMLMessageFormatter(new Type[] { typeof(object) });
- try
- {
- // 获取消息队列中的所有消息
- System.Messaging.Message [] mss = mq.GetAllMessages();
- // 循环所有的消息
- foreach (System.Messaging.Message ms in mss)
- {
- mq.Receive();
- ………………
- }
- }
- catch
- {
- }
9、从消息中获取相应的信息,就可以对系统进行下一步操作了。