ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Smart Client 离线数据

2019-07-19 09:02:52  阅读:190  来源: 互联网

标签:队列 离线 System Client 消息 using new Message Smart


原文链接:http://www.cnblogs.com/SamXie/archive/2006/08/10/SamXie.html

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

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

隔离存储区就是运用Smart Client的新技术在客户端单独开辟一块空间用来存储离线状态下的数据
需要添加引用
using System.IO; 
using System.IO.IsolatedStorage; // 该命名空间下的类均是对隔离存储区进行操作的
对隔离存储区的操作如下 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)
                {
                    if (IPAddress.IsLoopback(addressInfo.Address)) // 是否本地地址 如 127.0.0.1
                    {
                        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);
在网络正常联接时,你可以安部就班的做正常应该做的操作
如果没联接则要调用 CacheHelper 的方法对隔离存储区进行操作,也就
WriteDataSetToIsolatedStorage 和 ReadDataSetFromIsolatedStorage 方法

至于消息队列,要求客户端和服务器端都添加了“消息队列”这一Windows 组件
在应用程序中需要引用 System.Messaging;这一命名空间
然后在向服务器提交时创建一个消息队列
MessageQueue mq = new MessageQueue("s1p3\\MQTest", false, true);
MessageQueue 类有6个构造函数,我这只是用了其中的一种
"s1p3\\MQTest" 指的是该消息队列将要发送到哪里
消息队列大致可以分为3种类型,1 公共队列 2 专用队列 3 日志队列
这3种队列的写法也有所区别
公共队列        MachineName\QueueName
专用队列        MachineName\Private$\QueueName
日志队列        MachineName\QueueName\Journal$
MachineName  表示你要发送给哪台计算机,如果是本机 MachineName 可以用点号“.”
QueueName     表示该计算机中的队列名称
Private$ 和 Journal$ 是固定的,无需要更改
程序中常用到的也就是 “公共队列”和“专用队列”,而且其中又以“专用队列”占绝大多数
消息队列有了,接下来就要涉及到消息了
我从很多资料上看到都要用到 System.Messaging.Message 类(注:不是 System.Windows.Forms.Message 类,要注意区分)
一般都是这样写的
System.Messaging.Message m = new System.Messaging.Message();
然后就是设置 Message 的属性,
如 MessageName.body = ojbect;
      MessageName.Formatter = ……
………………
最后 MessageQueueName.Send(MessageName);
如果你仔细点,就会注意到 MessageQueue 类的 Send() 方法里要求的参数是一个 object
所以我就尝试了一下把我要发送的内容直接当作参数,一试果然成功
当然这只是一种比较省事的做法,相对应的对该内容的一些属性参考就要被忽略了
当 Send() 完毕后记得把消息队列关闭哦
MessageQueueName.Close();
如果网络通的话,消息队列会自动发送
如果网络不通的话,消息队列会保存在客户端,等到网络重新联接时消息队列会自动发送
消息发送完了,就要在服务器端去接收了
获得消息的方法有几种
GetAllMessage()
Receive() 等
我们从 GetAllMessage() 字面上不难看出该方法是获取所有的消息队列
而 Receive() 只是对单个消息获取
在实际应用中 GetAllMessage() 方法更切实际点
            MessageQueue mq = new MessageQueue(".\\MQTest");
            mq.Formatter = new XmlMessageFormatter(new Type[] { typeof(object) });
如果需要知道 Message 的一些属性需要添加以下代码,否则会有错误报出
            mq.MessageReadPropertyFilter.SourceMachine = true;
            mq.MessageReadPropertyFilter.Body = true;
下面就获取所有的消息队列吧
            try
            {
                System.Messaging.Message [] mss = mq.GetAllMessages(); // 获取消息队列中的所有消息
                foreach (System.Messaging.Message ms in mss) // 循环所有的消息
                {
                    mq.Receive();

                   ………………           
                }
            }
            catch
            {
            }
如果用 GetAllMessage() 方法的话,记得在每次获取单个消息后调用 Receive() 方法
从消息中获取相应的信息,就可以对系统进行下一步操作了

转载于:https://www.cnblogs.com/SamXie/archive/2006/08/10/SamXie.html

标签:队列,离线,System,Client,消息,using,new,Message,Smart
来源: https://blog.csdn.net/weixin_30662109/article/details/96469981

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有