Asp.Net教程,WinForm教程,Asp.Net MVC,vs2008教程,vs2010教程,Silverlight技术,源码下载,Asp.Net视频教程
全站热门标签
vs2010 Silverlight 存储过程 水晶报表 ADO.NET JavaScript LINQ AjaxPro DataGridView 面向对象 Extjs GridView XML DevExpress HTML教程 Oracle jQuery 分页 GDI+ Visual C++2010 MySQL Office2010 WPF MVC Dojo WCF4.0 VB.NET Sql2005 textbox cookie WCF WinForm Discuz!NT SQL经典语句 T-SQL checkbox ASPxGridView F# asp.net SQL VS2008新特性 DropDownList Access TreeView Ajax VS2008 页面执行时间 Flex 字符串 回调 VB2005 DataSet C#时间 ASP.NET性能优化 用户在线检测 动画
Framework C#技术 VB.NET VC.NET WCFWPF
当前位置: 主页 > WinForm教程 > WPF >

WCF实现对无人终端的远程监控

时间:2010-02-01 19:33来源:未知 作者:admin 点击:

最近在项目中,遇到了一个需要在远程监视自动运行软件的实时情况的例子。因为MS面向服务方面有WCF,而且看了一些资料,觉得WCF比较适合这个应用。因此决定用WCF来实现这个功能。

首先,先说一下具体的应用,监控,顾名思义,有两个方面的意思,一方面是,也就是远程要能实时查看终端的各种情况。这里其实指的就是被监控的要能主动的,实时的向远程控制端发送自己的情况。另一方面是控,即远程端能够发布命令控制终端进行执行。并由终端返回一定的执行信息。

而且这里是一种一对一对多的关系,即一个终端可以被多个管理端监控。实际上一个管理端也可以监控多个终端,在是这种分析中,我们可以明白,真正运行服务的是终端,而不是管理端。

简单起见,假定远程发送命令的操作是void Operation(),终端更新的操作是UpdateStatus();

这个想法,从设计到实现,经历以下三种阶段的变形。

最初的想法,是一个Service类。一个接口。即

即控制端调用operation发送命令,终端调用UpdateStatus更新状态。

对应的,要有一定的回调,即控制端发送Operation时,终端要有一个callBack进行接收,相应的,当终端用UpdateStatus时,控制端也要有一个callBack进行接收。

当这两种操作被集成到一个服务中时,我们的wcf接口变成了如下结构。

namespace Geyunfei.WCF
{
    [ServiceContract(

    SessionMode 
= SessionMode.Required
   ,
  CallbackContract 
= typeof(ISeviceCallBack)
         )]
    
public interface IService
    {
        [OperationContract]
        
/// 
        
/// 远程发送控制命令
        
/// 
        
/// 
        void Operation();

        [OperationContract]
        
/// 
        
/// 更新状态
        
/// 
        void UpdateStatus();
    }
    
    
public interface ISeviceCallBack
    {

      
        
void ReceiveStatus();
        
        
void ReceiveCommand();
    }
    
public static class Global
    {
        
public static List<ISeviceCallBack> callBacks = new List<ISeviceCallBack>();
    }
    [ServiceBehavior]
    
public class Service : IService,IDisposable 
    {
        ISeviceCallBack callBack;
        
#region IService Members
        
public Service()
        {
            callBack 
= System.ServiceModel.OperationContext.Current.GetCallbackChannel<ISeviceCallBack>();

            Global.callBacks.Add(callBack);
           
        }

        
/// 
        
/// 当服务端调用这个时,向终端发命令
        
/// 
        public void Operation()
        {

            
foreach (var r in Global.callBacks)
            {
                r.ReceiveCommand();
            }
        }
        
/// 
        
/// 当终端调用时,向服务端发命令
        
/// 
        public void UpdateStatus()
        {
            
foreach (var r in Global.callBacks)
            {
                r.ReceiveStatus();
            }
        }

        
#endregion

        
#region IDisposable Members

        
public void Dispose()
        {
            Global.callBacks.Remove(
this.callBack);
        }

        
#endregion
    }
}

 

namespace Geyunfei.WCF3
{
    [ServiceContract(

    SessionMode 
=
 SessionMode.Required
   ,
  CallbackContract 
= typeof
(ISeviceCallBack)
         )]
    
public interface
 IService
    {
        [OperationContract]
        
/// 

        
/// 远程发送控制命令
        
/// 

        void Operation();
    }

    
public interface
 ISeviceCallBack
    {
        
void
 ReceiveStatus();
    }
    
public static class
 Global
    {
        
public static List<ISeviceCallBack> callBacks = new List<ISeviceCallBack>
();
        
public static
 ReceiveCommandHandler receiveCommad;
    }
    [ServiceBehavior]
    
public class
 Service : IService, IDisposable
    {
        ISeviceCallBack callBack;
        
#region IService Members

        
public Service()
        {
            callBack 
= System.ServiceModel.OperationContext.Current.GetCallbackChannel<ISeviceCallBack>
();
            Global.callBacks.Add(callBack);

        }
        
/// 

        
/// 当终端调用时,向服务端发命令
        
/// 

        public void Operation()
        {

            
if (Global.receiveCommad != null
)
                Global.receiveCommad();
        }
        
#endregion

        
#region IDisposable Members
        
public void Dispose()
        {
            Global.callBacks.Remove(
this
.callBack);
        }

        
#endregion

    }


   
    
public delegate void ReceiveCommandHandler();
    
public class
 ServiceHost
    {
        
public
 ServiceHost()
        {
        }

        
public void
 Start()
        {
            
//在这里启动运行一个Service服务

        }
        
public void
 Stop()
        {
            
//在这里停止服务

        }


        
/// 

        
/// 当收到远程的命令时,触发此事件
        
/// 

        public event ReceiveCommandHandler ReceveCommand
        {
            add
            {
                Global.receiveCommad 
+=
 value;
            }
            remove
            {
                Global.receiveCommad 
-=
 value;
            }
        }


        
/// 

        
/// 更新状态
        
/// 

        public void UpdateStatus()
        {
            
foreach (var r in
 Global.callBacks)
            {
                r.ReceiveStatus();
            }
        }

    }
}

这样做实现起来比较方便,但是缺点也是很明显的,因为实际上终端只需要调用updateStatus,并回调receiveCommand,而管理端只需要调用Operation,回调receiveUpdateStatus(),现在这两种操作同时暴露给了终端和管理端 ,因此从设计上,这是一种不安全设计。。而且在调用相应的操作时,服务端自己又回得到相应的callBack,让人感到很费解。

那么下一步的想法,显然是把面向终端和管理端的服务进行分开。同时,用全局的变量或MSMQ进行交互,这里为了简单起见,只使用了List<>,没有使用委托。

这时,我们的设计变成了如下的形式:

namespace Geyunfei.WCF2
{
    
/// 
    
/// 面向终端的服务
    
/// 
    [ServiceContract(

    SessionMode 
= SessionMode.Required
   ,
  CallbackContract 
= typeof(ITerminalSeviceCallBack )
         )]
    
public interface ITerminalService
    {
        [OperationContract]
        
/// 
        
/// 更新状态
        
/// 
        void UpdateStatus();
    }

    
/// 
    
/// 面向管理端的服务
    
/// 
    [ServiceContract(

    SessionMode 
= SessionMode.Required
   ,
  CallbackContract 
= typeof(IControlSeviceCallBack)
         )]
    
public interface IControlService
    {
        [OperationContract]
        
/// 
        
/// 远程发送控制命令
        
/// 
        
/// 
        void Operation();
    }

    
public interface ITerminalSeviceCallBack
    {
        
void ReceiveCommand();
    }

    
public interface IControlSeviceCallBack
    {
        
void ReceiveStatus();
    }
    
public static class Global
    {
        
public static List<IControlSeviceCallBack > controlcallBacks = new List<IControlSeviceCallBack >();
        
public static List<ITerminalSeviceCallBack> terminalcallBacks = new List<ITerminalSeviceCallBack>();
    }
    [ServiceBehavior]
    
public class TerminalService : ITerminalService, IDisposable
    {
         ITerminalSeviceCallBack callBack;
        
#region IService Members
         
public TerminalService()
        {
            callBack 
= System.ServiceModel.OperationContext.Current.GetCallbackChannel<ITerminalSeviceCallBack>();
            Global.terminalcallBacks .Add(callBack);

        }
        
/// 
        
/// 当终端调用时,向服务端发命令
        
/// 
        public void UpdateStatus()
        {
            
foreach (var r in Global.controlcallBacks)
            {
                r.ReceiveStatus();
            }
        }

        
#endregion

        
#region IDisposable Members

        
public void Dispose()
        {
            Global.terminalcallBacks .Remove(
this.callBack);
        }

        
#endregion
    }


    [ServiceBehavior]
    
public class ControlService : IControlService, IDisposable
    {
        IControlSeviceCallBack  callBack;
        
#region IService Members
        
public ControlService()
        {
            callBack 
= System.ServiceModel.OperationContext.Current.GetCallbackChannel<IControlSeviceCallBack >();

            Global.controlcallBacks .Add(callBack);

        }

        
/// 
        
/// 当服务端调用这个时,向终端发命令
        
/// 
        public void Operation()
        {

            
foreach (var r in Global.terminalcallBacks)
            {
                r.ReceiveCommand();
            }
        }

        
#endregion

        
#region IDisposable Members

        
public void Dispose()
        {
            Global.controlcallBacks .Remove(
this.callBack);
        }

        
#endregion
    }
}

 

现在,终端和管理端的服务分开了,接口也清晰了。
但是这样做又有另一个缺点,即我的每一个终端是只运行一个软件的,即我在运行terminalService时,只有一个点在接入。这时,我为这一个点开一个服务,是一种浪费 。
于是,就有了第三种方案。即服务是面向管理端的。终端只实例一个简单的承载体,如下:
这时,我们的方案就已经接近完美了。

 

 

(责任编辑:admin)
Tags:WCF 远程监控
责任编辑:admin
返回顶部
------分隔线----------------------------
推荐内容
骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价 骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价