• 权限管理系统系列之WCF通信


    目录

    权限管理系统系列之序言     

            首先说下题外话,有些园友看了前一篇【权限管理系统系列之序言】博客加了QQ群(186841119),看了我写的权限管理系统的相关文档(主要是介绍已经开发的功能),给出了一些建议,感觉非常好,希望后续有更多的园友能再接再厉给出更多的指导意见,在平常的开发中个人会结合你们的建议做出适当修改和完善,促进共同学习和进步。关于源码共享的问题,可能会过段时间公布,不会现在公开源码,个人还在不断完善中,等完成差不多后会公开源码。

            客户端与服务器的通信在一个程序中会占住关键的作用,处理起来可能会有很多方式,比如说Remoting、Socket、WebServices、WCF等等都可以实现。本人这几种基本上都用过,Socket可能比较少些,一些聊天室的程序就会使用Socket,通过字节的形式接收数据;WebServices会WinCE开发中使用到,数据传输进行压缩,这样操作数据就比较方便,实时操作数据库;Remoting主要用在MIS系统的客户端与服务端通信,个人也说不出那种好;WCF也是我最近一两年才接触到的,公司现在使用的就是WCF通信的,个人感觉用WCF比较方便和简单,实用起来使用三个函数(一个函数是检测客户端与服务器端的心跳,一个是用于登录的、一个是公共的接口,基本上所有的客户端和服务端的通信都是用這个函数),這个函数可以搞定所有的客户端访问服务端的方法,所有的SQL在服务端执行,便于维护和日常的分工,不过在平常的开发中也不会分客户端和服务端的开发,基本上也是一个一个模块进行分工的。

    WCF的配置(包括客户端和服务端)

    客户端的配置文件:

     1 <?xml version="1.0"?>
     2 <configuration>
     3   <system.serviceModel>
     4     <bindings>
     5       <netTcpBinding>
     6         <binding name="TcpBinding_AppService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="10485760" maxBufferSize="10485760" maxConnections="10" maxReceivedMessageSize="10485760">
     7           <readerQuotas maxDepth="32" maxStringContentLength="10485760" maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760"/>
     8           <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
     9           <security mode="None">
    10             <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
    11             <message clientCredentialType="Windows"/>
    12           </security>
    13         </binding>
    14 
    15         <binding name="TcpBinding_MessageService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="10485760" maxBufferSize="10485760" maxConnections="10" maxReceivedMessageSize="10485760">
    16           <readerQuotas maxDepth="32" maxStringContentLength="10485760" maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760"/>
    17           <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
    18           <security mode="None">
    19             <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
    20             <message clientCredentialType="Windows"/>
    21           </security>
    22         </binding>
    23 
    24       </netTcpBinding>
    25     </bindings>
    26     <client>
    27       <endpoint address="net.tcp://localhost:9090/AppService" binding="netTcpBinding" bindingConfiguration="TcpBinding_AppService" contract="IAppService" name="TcpBinding_AppService"/>
    28 
    29       <endpoint address="net.tcp://localhost:7070/MessageService" binding="netTcpBinding" bindingConfiguration="TcpBinding_MessageService" contract="IMessageService" name="TcpBinding_MessageService"/>
    30     </client>
    31   </system.serviceModel>
    32 </configuration>
    View Code

    服务端的配置文件:

     1 <?xml version="1.0"?>
     2 <configuration>
     3   <system.serviceModel>
     4     <services>
     5       <service behaviorConfiguration="Service.Behavior" name="Server.AppService">
     6         <endpoint address="AppService" binding="netTcpBinding" bindingConfiguration="AppServiceBinding" name="TcpBinding_AppService" contract="Server.IAppService" />
     7         <endpoint address="AppService/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
     8         <host>
     9           <baseAddresses>
    10             <add baseAddress="net.tcp://localhost:9090" />
    11           </baseAddresses>
    12         </host>
    13       </service>
    14       <service behaviorConfiguration="Service.Behavior" name="Server.MessageService">
    15         <endpoint address="MessageService" binding="netTcpBinding" bindingConfiguration="MessageServiceBinding" name="TcpBinding_MessageService" contract="Server.IMessageService" />
    16         <endpoint address="MessageService/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
    17         <host>
    18           <baseAddresses>
    19             <add baseAddress="net.tcp://localhost:7070" />
    20           </baseAddresses>
    21         </host>
    22       </service>
    23     </services>
    24     <bindings>
    25       <netTcpBinding>
    26         <binding name="AppServiceBinding" maxBufferSize="10485760" maxReceivedMessageSize="10485760">
    27           <readerQuotas maxDepth="32" maxStringContentLength="10485760"
    28             maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760" />
    29           <reliableSession ordered="true" inactivityTimeout="00:10:00"
    30             enabled="false" />
    31           <security mode="None" />
    32         </binding>
    33         <binding name="MessageServiceBinding" maxBufferSize="10485760" maxReceivedMessageSize="10485760">
    34           <readerQuotas maxDepth="32" maxStringContentLength="10485760"
    35             maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760" />
    36           <reliableSession ordered="true" inactivityTimeout="00:10:00"
    37             enabled="false" />
    38           <security mode="None" />
    39         </binding>
    40       </netTcpBinding>
    41     </bindings>
    42     <behaviors>
    43       <serviceBehaviors>
    44         <behavior name="Service.Behavior">
    45           <serviceMetadata />
    46           <serviceDebug includeExceptionDetailInFaults="true" />
    47           <!--会话最大数量(并发会话)-->
    48           <serviceThrottling maxConcurrentSessions="100" />
    49           <!--数据序列最大量-->
    50           <dataContractSerializer maxItemsInObjectGraph="10485760" />
    51         </behavior>
    52         <behavior name="mexConfig">
    53           <serviceDebug includeExceptionDetailInFaults="True" />
    54           <serviceMetadata />
    55         </behavior>
    56       </serviceBehaviors>
    57     </behaviors>
    58   </system.serviceModel>
    59 </configuration>
    View Code

    以上为客户端与服务端的配置文件,有两个配置,一个为基本通信所用,一个为双工通信所用。

    介绍完配置文件后再介绍实现函数:

     1 [ServiceContract(Name = "IAppService", SessionMode = SessionMode.Allowed, Namespace = "http://tempuri.org/")]
     2     public interface IAppService
     3     {
     4         //心跳
     5         [OperationContract]
     6         string HeartBeat(string echo);
     7 
     8         //登录
     9         [OperationContract]
    10         bool Login(string UserName, string Password);
    11 
    12         //统一的应用业务请求调用,用于会话控制和调用转发
    13         [OperationContract]
    14         Result AppCall(Request request);
    15     }
    16 
    17     #region * 推送消息
    18     [ServiceContract(CallbackContract = typeof(IPushClient))]
    19     public interface IMessageService
    20     {
    21         [OperationContract]
    22         void RegisterClient();
    23     }
    24 
    25     public interface IPushClient
    26     {
    27         [OperationContract(IsOneWay = true)]
    28         void SendMessage(string message);
    29     }
    30     #endregion

          分别有三个函数,一个是维持服务端与客户端的心跳,一个为登陆所用,一个为所有函数的接口,基本上所有的通信都是通过这个函数进行调用。最下面的为双工通信的定义,定义成回调函数的形式。

    以上函数实现逻辑:

      1  //每个会话一个实例,同一个会话下的多线程并发
      2     [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
      3     public class AppService : IAppService
      4     {
      5         //记录是否登录
      6         bool IsLogined = false;
      7         Context context = new Context();
      8 
      9         private static readonly string _username = "Server";
     10         private static readonly string _password = "123456";
     11 
     12         //心跳请求,维持链路正常
     13         public string HeartBeat(string echo)
     14         {
     15             Log.Log.Debug("收到请求:" + echo);
     16             return "Re:" + echo;
     17         }
     18 
     19         //用于登录
     20         public bool Login(string UserName, string Password)
     21         {
     22             Log.Log.Debug("收到请求:" + UserName + ";" + Password);
     23             if (_username.Equals(Encrypt.DecryptDES(UserName, Const.EncryptKey)) && _password.Equals(Encrypt.DecryptDES(Password, Const.EncryptKey)))
     24             {
     25                 IsLogined = true;
     26                 context.UserName = UserName;
     27                 return IsLogined;
     28             }
     29             else
     30             {
     31                 IsLogined = false;
     32                 context.UserName = "";
     33                 return IsLogined;
     34             }
     35         }
     36 
     37         //统一的业务请求调用代理
     38         delegate Result ActionDelegate(string reqdata);
     39         //统一的应用业务请求调用,用于会话控制和调用转发
     40         public Result AppCall(Request request)
     41         {
     42             if (!string.IsNullOrEmpty(request.data))
     43             {
     44                 if (request.data.Contains(JSON.CompressionFlag))
     45                 {
     46                     Log.Log.Debug("收到请求:" + Compression.DecompressString(request.data.Replace(JSON.CompressionFlag, JSON.ReplaceFlag)));
     47                 }
     48                 else
     49                 {
     50                     Log.Log.Debug("收到请求:" + request.data);
     51                 }
     52             }
     53             if (!IsLogined)
     54             {
     55                 Result result = new Result() { success = false, errors = "用户未登录,请登录后再提交请求!" };
     56                 Log.Log.Info("Server.AppService.AppCall(Request request):" + JSON.Object2Json(result, false));
     57                 return result;
     58             }
     59 
     60             if (request.action == null || request.method == null)
     61             {
     62                 Result result = new Result() { success = false, errors = "请求数据格式不正确{request.action==null || request.method==null},请检查!" };
     63                 Log.Log.Error("Server.AppService.AppCall(Request request)出错:" + JSON.Object2Json(result, false));
     64                 return result;
     65 
     66             }
     67             try
     68             {
     69                 Type type = Type.GetType("Server.Action." + request.action);
     70                 object action = Activator.CreateInstance(type, new object[] { this.context });
     71                 ActionDelegate doAction = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), action, request.method);
     72                 Result result = doAction(request.data);
     73                 return result;
     74             }
     75             catch (Exception e)
     76             {
     77                 Log.Log.Error("Server.AppService.AppCall(Request request)异常:" + e.ToString());
     78                 return new Result() { success = false, errors = "执行业务请求错误!" };
     79             }
     80         }
     81     }
     82 
     83     #region * 推送消息
     84     [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
     85     public class MessageService : IMessageService, IDisposable
     86     {
     87         public static List<IPushClient> ClientCallbackList { get; set; }
     88         public MessageService()
     89         {
     90             ClientCallbackList = new List<IPushClient>();
     91         }
     92 
     93         public void RegisterClient()
     94         {
     95             var client = OperationContext.Current.GetCallbackChannel<IPushClient>();
     96             var id = OperationContext.Current.SessionId;
     97             //Console.WriteLine("{0}registered.", id);
     98             Log.Log.Info(string.Format("{0}registered.", id));
     99             OperationContext.Current.Channel.Closing+=new EventHandler(Channel_Closing);
    100             ClientCallbackList.Add(client);
    101         }
    102 
    103         private void Channel_Closing(object sender, EventArgs e)
    104         {
    105             lock (ClientCallbackList)
    106             {
    107                 ClientCallbackList.Remove((IPushClient)sender);
    108             }
    109         }
    110 
    111         public void Dispose()
    112         {
    113             ClientCallbackList.Clear();
    114         }
    115     }
    116     #endregion
    117 }
    View Code

           通信接口通过以上实体,success为函数执行状态,msg为函数返回的信息,data为返回的数据(格式为json格式的),errors为返回的错误信息,sql为函数执行的sql,返回给前台界面。

    WCF服务生成客户端的配置文件步骤:
    a.打开vs命令行,用cd进入到exe文件目录。
    b.svcutil .exe
    c.svcutil *.wsdl *.xsd
    完成以上即可。

    客户调用CS文件:

      1 //------------------------------------------------------------------------------
      2 // <auto-generated>
      3 //     此代码由工具生成。
      4 //     运行时版本:4.0.30319.18444
      5 //
      6 //     对此文件的更改可能会导致不正确的行为,并且如果
      7 //     重新生成代码,这些更改将会丢失。
      8 // </auto-generated>
      9 //------------------------------------------------------------------------------
     10 
     11 namespace Server.Domain
     12 {
     13     using System.Runtime.Serialization;
     14 
     15 
     16     [System.Diagnostics.DebuggerStepThroughAttribute()]
     17     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
     18     [System.Runtime.Serialization.DataContractAttribute(Name = "Request", Namespace = "http://schemas.datacontract.org/2004/07/Server.Domain")]
     19     public partial class Request : object, System.Runtime.Serialization.IExtensibleDataObject
     20     {
     21 
     22         private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
     23 
     24         private string actionField;
     25 
     26         private string dataField;
     27 
     28         private string methodField;
     29 
     30         public System.Runtime.Serialization.ExtensionDataObject ExtensionData
     31         {
     32             get
     33             {
     34                 return this.extensionDataField;
     35             }
     36             set
     37             {
     38                 this.extensionDataField = value;
     39             }
     40         }
     41 
     42         [System.Runtime.Serialization.DataMemberAttribute()]
     43         public string action
     44         {
     45             get
     46             {
     47                 return this.actionField;
     48             }
     49             set
     50             {
     51                 this.actionField = value;
     52             }
     53         }
     54 
     55         [System.Runtime.Serialization.DataMemberAttribute()]
     56         public string data
     57         {
     58             get
     59             {
     60                 return this.dataField;
     61             }
     62             set
     63             {
     64                 this.dataField = value;
     65             }
     66         }
     67 
     68         [System.Runtime.Serialization.DataMemberAttribute()]
     69         public string method
     70         {
     71             get
     72             {
     73                 return this.methodField;
     74             }
     75             set
     76             {
     77                 this.methodField = value;
     78             }
     79         }
     80     }
     81 
     82     [System.Diagnostics.DebuggerStepThroughAttribute()]
     83     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
     84     [System.Runtime.Serialization.DataContractAttribute(Name = "Result", Namespace = "http://schemas.datacontract.org/2004/07/Server.Domain")]
     85     public partial class Result : object, System.Runtime.Serialization.IExtensibleDataObject
     86     {
     87 
     88         private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
     89 
     90         private string dataField;
     91 
     92         private string errorsField;
     93 
     94         private string msgField;
     95 
     96         private string sqlField;
     97 
     98         private bool successField;
     99 
    100         public System.Runtime.Serialization.ExtensionDataObject ExtensionData
    101         {
    102             get
    103             {
    104                 return this.extensionDataField;
    105             }
    106             set
    107             {
    108                 this.extensionDataField = value;
    109             }
    110         }
    111 
    112         [System.Runtime.Serialization.DataMemberAttribute()]
    113         public string data
    114         {
    115             get
    116             {
    117                 return this.dataField;
    118             }
    119             set
    120             {
    121                 this.dataField = value;
    122             }
    123         }
    124 
    125         [System.Runtime.Serialization.DataMemberAttribute()]
    126         public string errors
    127         {
    128             get
    129             {
    130                 return this.errorsField;
    131             }
    132             set
    133             {
    134                 this.errorsField = value;
    135             }
    136         }
    137 
    138         [System.Runtime.Serialization.DataMemberAttribute()]
    139         public string msg
    140         {
    141             get
    142             {
    143                 return this.msgField;
    144             }
    145             set
    146             {
    147                 this.msgField = value;
    148             }
    149         }
    150 
    151         [System.Runtime.Serialization.DataMemberAttribute()]
    152         public string sql
    153         {
    154             get
    155             {
    156                 return this.sqlField;
    157             }
    158             set
    159             {
    160                 this.sqlField = value;
    161             }
    162         }
    163 
    164         [System.Runtime.Serialization.DataMemberAttribute()]
    165         public bool success
    166         {
    167             get
    168             {
    169                 return this.successField;
    170             }
    171             set
    172             {
    173                 this.successField = value;
    174             }
    175         }
    176     }
    177 }
    178 
    179 
    180 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    181 [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "IAppService")]
    182 public interface IAppService
    183 {
    184 
    185     [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IAppService/HeartBeat", ReplyAction = "http://tempuri.org/IAppService/HeartBeatResponse")]
    186     string HeartBeat(string echo);
    187 
    188     [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IAppService/Login", ReplyAction = "http://tempuri.org/IAppService/LoginResponse")]
    189     bool Login(string UserName, string Password);
    190 
    191     [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IAppService/AppCall", ReplyAction = "http://tempuri.org/IAppService/AppCallResponse")]
    192     Server.Domain.Result AppCall(Server.Domain.Request request);
    193 }
    194 
    195 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    196 public interface IAppServiceChannel : IAppService, System.ServiceModel.IClientChannel
    197 {
    198 }
    199 
    200 [System.Diagnostics.DebuggerStepThroughAttribute()]
    201 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    202 public partial class AppServiceClient : System.ServiceModel.ClientBase<IAppService>, IAppService
    203 {
    204 
    205     public AppServiceClient()
    206     {
    207     }
    208 
    209     public AppServiceClient(string endpointConfigurationName) :
    210         base(endpointConfigurationName)
    211     {
    212     }
    213 
    214     public AppServiceClient(string endpointConfigurationName, string remoteAddress) :
    215         base(endpointConfigurationName, remoteAddress)
    216     {
    217     }
    218 
    219     public AppServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
    220         base(endpointConfigurationName, remoteAddress)
    221     {
    222     }
    223 
    224     public AppServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
    225         base(binding, remoteAddress)
    226     {
    227     }
    228 
    229     public string HeartBeat(string echo)
    230     {
    231         return base.Channel.HeartBeat(echo);
    232     }
    233 
    234     public bool Login(string UserName, string Password)
    235     {
    236         return base.Channel.Login(UserName, Password);
    237     }
    238 
    239     public Server.Domain.Result AppCall(Server.Domain.Request request)
    240     {
    241         return base.Channel.AppCall(request);
    242     }
    243 }
    244 
    245 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    246 [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "IMessageService", CallbackContract = typeof(IMessageServiceCallback))]
    247 public interface IMessageService
    248 {
    249 
    250     [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IMessageService/RegisterClient", ReplyAction = "http://tempuri.org/IMessageService/RegisterClientResponse")]
    251     void RegisterClient();
    252 }
    253 
    254 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    255 public interface IMessageServiceCallback
    256 {
    257 
    258     [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IMessageService/SendMessage")]
    259     void SendMessage(string message);
    260 }
    261 
    262 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    263 public interface IMessageServiceChannel : IMessageService, System.ServiceModel.IClientChannel
    264 {
    265 }
    266 
    267 [System.Diagnostics.DebuggerStepThroughAttribute()]
    268 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    269 public partial class MessageServiceClient : System.ServiceModel.DuplexClientBase<IMessageService>, IMessageService
    270 {
    271 
    272     public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance) :
    273         base(callbackInstance)
    274     {
    275     }
    276 
    277     public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName) :
    278         base(callbackInstance, endpointConfigurationName)
    279     {
    280     }
    281 
    282     public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) :
    283         base(callbackInstance, endpointConfigurationName, remoteAddress)
    284     {
    285     }
    286 
    287     public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
    288         base(callbackInstance, endpointConfigurationName, remoteAddress)
    289     {
    290     }
    291 
    292     public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
    293         base(callbackInstance, binding, remoteAddress)
    294     {
    295     }
    296 
    297     public void RegisterClient()
    298     {
    299         base.Channel.RegisterClient();
    300     }
    301 }
    View Code
     1        public static AppServiceClient AppService;
     2         public static ServiceHearBeat HeartBeat;
     3         /// <summary>
     4         /// 连接是否正常
     5         /// </summary>
     6         public static bool IsAlive
     7         {
     8             get { return HeartBeat.IsAlive; }
     9         }
    10         /// <summary>
    11         /// 是否已经弹出过提示
    12         /// </summary>
    13         public static bool HasNotice
    14         {
    15             get { return HeartBeat.HasNotice; }
    16             set { HeartBeat.HasNotice = value; }
    17         }
    18 
    19 
    20          //连接到应用服务
    21           if (!ConnectToAppServer())
    22           {
    23                 Comm.MessageBox.Info("连接服务端失败,请检查服务端是否已经启动。");
    24                  return;
    25            }
    26 
    27 //连接到应用服务
    28         public static bool ConnectToAppServer()
    29         {
    30             try
    31             {
    32                 //如果服务存在,则尝试关闭链接
    33                 if (AppService != null)
    34                 {
    35                     try
    36                     {
    37                         AppService.Close();
    38                     }
    39                     catch (Exception)
    40                     {
    41                     }
    42                 }
    43                 //创建新的服务对象,并进行连接和登录
    44                 AppService = new AppServiceClient();
    45                 AppService.Open();
    46                 if (!AppClient.AppService.Login(Encrypt.EncryptDES("Server", Const.EncryptKey), Encrypt.EncryptDES("123456", Const.EncryptKey)))
    47                 {
    48                     return false;
    49                 }
    50                 return true;
    51             }
    52             catch (EndpointNotFoundException)
    53             {
    54                 Log.Error("连接服务端失败,服务端IP端口配置错误或者是服务端尚未启动");
    55             }
    56             catch (SocketException)
    57             {
    58                 Log.Error("连接服务端失败,服务端IP端口配置错误或者是服务端尚未启动");
    59             }
    60             catch (Exception e)
    61             {
    62                 Log.Error("连接服务端出错:" + e.ToString());
    63             }
    64             return false;
    65 
    66         }
    View Code

    以上即可完成对客户端连接服务端了,基本上完成以后步骤可以说完成了WCF的通信,实现了客户端连接服务端。

    服务端打开的效果:

    客户端打开的效果:

    如对权限管理系统有兴趣可加QQ群:186841119,可参与相关话题讨论。相互学习交流,共同进步。

  • 相关阅读:
    2
    1
    nginx隐藏版本号
    全面对比主流 .NET 报表控件 (转)
    前端的发展和未来趋势
    NPM初学者指南 (转)
    一文解读MySQL事务
    如何高效的学习技术
    重新统一的 .NET平台-.NET 5
    为啥要有微服务?啥是微服务?
  • 原文地址:https://www.cnblogs.com/luoyuhao/p/4128503.html
Copyright © 2020-2023  润新知