目录

权限管理系统系列之序言 

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

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

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

客户端的配置文件:

 <?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<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">
<readerQuotas maxDepth="32" maxStringContentLength="10485760" maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
<message clientCredentialType="Windows"/>
</security>
</binding> <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">
<readerQuotas maxDepth="32" maxStringContentLength="10485760" maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
<message clientCredentialType="Windows"/>
</security>
</binding> </netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:9090/AppService" binding="netTcpBinding" bindingConfiguration="TcpBinding_AppService" contract="IAppService" name="TcpBinding_AppService"/> <endpoint address="net.tcp://localhost:7070/MessageService" binding="netTcpBinding" bindingConfiguration="TcpBinding_MessageService" contract="IMessageService" name="TcpBinding_MessageService"/>
</client>
</system.serviceModel>
</configuration>

服务端的配置文件:

 <?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="Service.Behavior" name="Server.AppService">
<endpoint address="AppService" binding="netTcpBinding" bindingConfiguration="AppServiceBinding" name="TcpBinding_AppService" contract="Server.IAppService" />
<endpoint address="AppService/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9090" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="Service.Behavior" name="Server.MessageService">
<endpoint address="MessageService" binding="netTcpBinding" bindingConfiguration="MessageServiceBinding" name="TcpBinding_MessageService" contract="Server.IMessageService" />
<endpoint address="MessageService/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:7070" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="AppServiceBinding" maxBufferSize="10485760" maxReceivedMessageSize="10485760">
<readerQuotas maxDepth="32" maxStringContentLength="10485760"
maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None" />
</binding>
<binding name="MessageServiceBinding" maxBufferSize="10485760" maxReceivedMessageSize="10485760">
<readerQuotas maxDepth="32" maxStringContentLength="10485760"
maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="Service.Behavior">
<serviceMetadata />
<serviceDebug includeExceptionDetailInFaults="true" />
<!--会话最大数量(并发会话)-->
<serviceThrottling maxConcurrentSessions="100" />
<!--数据序列最大量-->
<dataContractSerializer maxItemsInObjectGraph="10485760" />
</behavior>
<behavior name="mexConfig">
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

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

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

 [ServiceContract(Name = "IAppService", SessionMode = SessionMode.Allowed, Namespace = "http://tempuri.org/")]
public interface IAppService
{
//心跳
[OperationContract]
string HeartBeat(string echo); //登录
[OperationContract]
bool Login(string UserName, string Password); //统一的应用业务请求调用,用于会话控制和调用转发
[OperationContract]
Result AppCall(Request request);
} #region * 推送消息
[ServiceContract(CallbackContract = typeof(IPushClient))]
public interface IMessageService
{
[OperationContract]
void RegisterClient();
} public interface IPushClient
{
[OperationContract(IsOneWay = true)]
void SendMessage(string message);
}
#endregion

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

以上函数实现逻辑:

  //每个会话一个实例,同一个会话下的多线程并发
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class AppService : IAppService
{
//记录是否登录
bool IsLogined = false;
Context context = new Context(); private static readonly string _username = "Server";
private static readonly string _password = ""; //心跳请求,维持链路正常
public string HeartBeat(string echo)
{
Log.Log.Debug("收到请求:" + echo);
return "Re:" + echo;
} //用于登录
public bool Login(string UserName, string Password)
{
Log.Log.Debug("收到请求:" + UserName + ";" + Password);
if (_username.Equals(Encrypt.DecryptDES(UserName, Const.EncryptKey)) && _password.Equals(Encrypt.DecryptDES(Password, Const.EncryptKey)))
{
IsLogined = true;
context.UserName = UserName;
return IsLogined;
}
else
{
IsLogined = false;
context.UserName = "";
return IsLogined;
}
} //统一的业务请求调用代理
delegate Result ActionDelegate(string reqdata);
//统一的应用业务请求调用,用于会话控制和调用转发
public Result AppCall(Request request)
{
if (!string.IsNullOrEmpty(request.data))
{
if (request.data.Contains(JSON.CompressionFlag))
{
Log.Log.Debug("收到请求:" + Compression.DecompressString(request.data.Replace(JSON.CompressionFlag, JSON.ReplaceFlag)));
}
else
{
Log.Log.Debug("收到请求:" + request.data);
}
}
if (!IsLogined)
{
Result result = new Result() { success = false, errors = "用户未登录,请登录后再提交请求!" };
Log.Log.Info("Server.AppService.AppCall(Request request):" + JSON.Object2Json(result, false));
return result;
} if (request.action == null || request.method == null)
{
Result result = new Result() { success = false, errors = "请求数据格式不正确{request.action==null || request.method==null},请检查!" };
Log.Log.Error("Server.AppService.AppCall(Request request)出错:" + JSON.Object2Json(result, false));
return result; }
try
{
Type type = Type.GetType("Server.Action." + request.action);
object action = Activator.CreateInstance(type, new object[] { this.context });
ActionDelegate doAction = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), action, request.method);
Result result = doAction(request.data);
return result;
}
catch (Exception e)
{
Log.Log.Error("Server.AppService.AppCall(Request request)异常:" + e.ToString());
return new Result() { success = false, errors = "执行业务请求错误!" };
}
}
} #region * 推送消息
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MessageService : IMessageService, IDisposable
{
public static List<IPushClient> ClientCallbackList { get; set; }
public MessageService()
{
ClientCallbackList = new List<IPushClient>();
} public void RegisterClient()
{
var client = OperationContext.Current.GetCallbackChannel<IPushClient>();
var id = OperationContext.Current.SessionId;
//Console.WriteLine("{0}registered.", id);
Log.Log.Info(string.Format("{0}registered.", id));
OperationContext.Current.Channel.Closing+=new EventHandler(Channel_Closing);
ClientCallbackList.Add(client);
} private void Channel_Closing(object sender, EventArgs e)
{
lock (ClientCallbackList)
{
ClientCallbackList.Remove((IPushClient)sender);
}
} public void Dispose()
{
ClientCallbackList.Clear();
}
}
#endregion
}

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

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

客户调用CS文件:

 //------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.18444
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------ namespace Server.Domain
{
using System.Runtime.Serialization; [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name = "Request", Namespace = "http://schemas.datacontract.org/2004/07/Server.Domain")]
public partial class Request : object, System.Runtime.Serialization.IExtensibleDataObject
{ private System.Runtime.Serialization.ExtensionDataObject extensionDataField; private string actionField; private string dataField; private string methodField; public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
} [System.Runtime.Serialization.DataMemberAttribute()]
public string action
{
get
{
return this.actionField;
}
set
{
this.actionField = value;
}
} [System.Runtime.Serialization.DataMemberAttribute()]
public string data
{
get
{
return this.dataField;
}
set
{
this.dataField = value;
}
} [System.Runtime.Serialization.DataMemberAttribute()]
public string method
{
get
{
return this.methodField;
}
set
{
this.methodField = value;
}
}
} [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name = "Result", Namespace = "http://schemas.datacontract.org/2004/07/Server.Domain")]
public partial class Result : object, System.Runtime.Serialization.IExtensibleDataObject
{ private System.Runtime.Serialization.ExtensionDataObject extensionDataField; private string dataField; private string errorsField; private string msgField; private string sqlField; private bool successField; public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
} [System.Runtime.Serialization.DataMemberAttribute()]
public string data
{
get
{
return this.dataField;
}
set
{
this.dataField = value;
}
} [System.Runtime.Serialization.DataMemberAttribute()]
public string errors
{
get
{
return this.errorsField;
}
set
{
this.errorsField = value;
}
} [System.Runtime.Serialization.DataMemberAttribute()]
public string msg
{
get
{
return this.msgField;
}
set
{
this.msgField = value;
}
} [System.Runtime.Serialization.DataMemberAttribute()]
public string sql
{
get
{
return this.sqlField;
}
set
{
this.sqlField = value;
}
} [System.Runtime.Serialization.DataMemberAttribute()]
public bool success
{
get
{
return this.successField;
}
set
{
this.successField = value;
}
}
}
} [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName = "IAppService")]
public interface IAppService
{ [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IAppService/HeartBeat", ReplyAction = "http://tempuri.org/IAppService/HeartBeatResponse")]
string HeartBeat(string echo); [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IAppService/Login", ReplyAction = "http://tempuri.org/IAppService/LoginResponse")]
bool Login(string UserName, string Password); [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IAppService/AppCall", ReplyAction = "http://tempuri.org/IAppService/AppCallResponse")]
Server.Domain.Result AppCall(Server.Domain.Request request);
} [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IAppServiceChannel : IAppService, System.ServiceModel.IClientChannel
{
} [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class AppServiceClient : System.ServiceModel.ClientBase<IAppService>, IAppService
{ public AppServiceClient()
{
} public AppServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
} public AppServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
} public AppServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
} public AppServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
} public string HeartBeat(string echo)
{
return base.Channel.HeartBeat(echo);
} public bool Login(string UserName, string Password)
{
return base.Channel.Login(UserName, Password);
} public Server.Domain.Result AppCall(Server.Domain.Request request)
{
return base.Channel.AppCall(request);
}
} [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName = "IMessageService", CallbackContract = typeof(IMessageServiceCallback))]
public interface IMessageService
{ [System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IMessageService/RegisterClient", ReplyAction = "http://tempuri.org/IMessageService/RegisterClientResponse")]
void RegisterClient();
} [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IMessageServiceCallback
{ [System.ServiceModel.OperationContractAttribute(IsOneWay = true, Action = "http://tempuri.org/IMessageService/SendMessage")]
void SendMessage(string message);
} [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface IMessageServiceChannel : IMessageService, System.ServiceModel.IClientChannel
{
} [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class MessageServiceClient : System.ServiceModel.DuplexClientBase<IMessageService>, IMessageService
{ public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance) :
base(callbackInstance)
{
} public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName) :
base(callbackInstance, endpointConfigurationName)
{
} public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) :
base(callbackInstance, endpointConfigurationName, remoteAddress)
{
} public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(callbackInstance, endpointConfigurationName, remoteAddress)
{
} public MessageServiceClient(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(callbackInstance, binding, remoteAddress)
{
} public void RegisterClient()
{
base.Channel.RegisterClient();
}
}
        public static AppServiceClient AppService;
public static ServiceHearBeat HeartBeat;
/// <summary>
/// 连接是否正常
/// </summary>
public static bool IsAlive
{
get { return HeartBeat.IsAlive; }
}
/// <summary>
/// 是否已经弹出过提示
/// </summary>
public static bool HasNotice
{
get { return HeartBeat.HasNotice; }
set { HeartBeat.HasNotice = value; }
} //连接到应用服务
if (!ConnectToAppServer())
{
Comm.MessageBox.Info("连接服务端失败,请检查服务端是否已经启动。");
return;
} //连接到应用服务
public static bool ConnectToAppServer()
{
try
{
//如果服务存在,则尝试关闭链接
if (AppService != null)
{
try
{
AppService.Close();
}
catch (Exception)
{
}
}
//创建新的服务对象,并进行连接和登录
AppService = new AppServiceClient();
AppService.Open();
if (!AppClient.AppService.Login(Encrypt.EncryptDES("Server", Const.EncryptKey), Encrypt.EncryptDES("", Const.EncryptKey)))
{
return false;
}
return true;
}
catch (EndpointNotFoundException)
{
Log.Error("连接服务端失败,服务端IP端口配置错误或者是服务端尚未启动");
}
catch (SocketException)
{
Log.Error("连接服务端失败,服务端IP端口配置错误或者是服务端尚未启动");
}
catch (Exception e)
{
Log.Error("连接服务端出错:" + e.ToString());
}
return false; }

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

服务端打开的效果:

客户端打开的效果:

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

权限管理系统系列之WCF通信的更多相关文章

  1. 以WCF安全认证方式调用通用权限管理系统获取基础信息资料

    在B/S开发中,涉及到获取系统基础资料的问题,因为是在不同平台下的开发,采用了WCF方式获取. 下面是一个调用通用权限管理系统(吉日嘎拉)基础信息资料的一个demo供参考 调用原理图: web.con ...

  2. 系列文章--Silverlight与WCF通信

    Silverlight与WCF通信(一) :Silverlight通过httpBinding访问IIS宿主WCF 摘要: 首语本人在学习Silverlight 和 WCF的时候,各种问题层出不穷,在园 ...

  3. Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  4. [Django]用户权限学习系列之设计自有权限管理系统设计思路

    若在阅读本片文章遇到权限操作问题,请查看本系列的前两章! http://www.cnblogs.com/CQ-LQJ/p/5609690.html和http://www.cnblogs.com/CQ- ...

  5. 分享一个html+js+ashx+easyui+ado.net权限管理系统

    EasyUI.权限管理 这是个都快被搞烂了的组合,但是easyui的确好用,权限管理在项目中的确实用.一直以来博客园里也不少朋友分享过,但是感觉好的要不没源码,要不就是过度设计写的太复杂看不懂,也懒得 ...

  6. MVC + EF + Bootstrap 2 权限管理系统入门级(附源码)

    MVC .EF 学习有大半年了,用的还不是很熟练,正好以做这样一个简单的权限管理系统作为学习的切入点,还是非常合适的. 开发环境: VS 2013 + Git + MVC 5 + EF 6 Code ...

  7. Angularjs,WebAPI 搭建一个简易权限管理系统

    Angularjs,WebAPI 搭建一个简易权限管理系统 Angularjs名词与概念(一)   1. 目录 前言 Angularjs名词与概念 权限系统原型 权限系统业务 数据库设计和实现 Web ...

  8. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2 ...

  9. 开篇ASP.NET MVC 权限管理系列

    开篇 [快乐编程系列之ASP.NET MVC 权限管理系列]一.开篇   用了好长一段时间的ASP.NET MVC,感觉MVC真的是很好用,最近一年左右做了两个中小型项目,觉得还是很多地方不是很熟悉的 ...

随机推荐

  1. Eclipse中Git插件使用技巧:还原文件

    如果修改了某个文件并未提交至本地库(add index),那么怎么还原呢?Git插件中并不像Svn插件直接提供有还原方式.其实无论是否提交至本地库或者远程库,还原操作的本质都是将文件的当前版本还原至之 ...

  2. Windows XP with SP3大客户免激活日文版

    原贴地址:http://www.humin.com.cn/ja_windows_xp_professional_with_service_pack_3_x86_dvd_vl_x14-74058-iso ...

  3. 'org.springframework.beans.factory.xml.XmlBeanFactory' is deprecated

    'org.springframework.beans.factory.xml.XmlBeanFactory' is deprecated XmlBeanFactory这个类已经被摒弃了.可以用以下代替 ...

  4. [leetcode]239. Sliding Window Maximum滑动窗口最大值

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  5. discuz的css处理机制

    common/common.css 是一个通用的css文件. common/module.css 是某个功能模块使用的css文件.   module.css中,利用特殊语法: /** 标识 **/ c ...

  6. Boost 库uuid 的使用

    UUID 简介 通用唯一识别码(英语:Universally Unique Identifier,简称UUID)是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分. uuid 版 ...

  7. CMakeList 编写规则 -1

    CMAKE 常见指令 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(XXX) SET(CMAKE_BUILD_TYPE Release) SET(CMAKE_ ...

  8. Vagrant WinNFSd

    Vagrant WinNFSd Manage and adds support for NFS on Windows. Supported Platforms As of version 1.0.6 ...

  9. 13 Maven 编写插件

    Maven 编写插件 Maven 的任何行为都是由插件完成的,包括项目的清理.绵编译.测试以及打包等操作都有其对应的 Maven 插件.每个插件拥有一个或者多个目标,用户可以直接从命令行运行这些插件目 ...

  10. wcf服务契约的重载

    a. 服务端 .服务端 契约用OperationContract的Name实现重载 using System; using System.Collections.Generic; using Syst ...