一、简单WCF服务TCP和HTTP传输协议
二、实例管理
1、实例管理-单调服务
介绍:单调服务的一个实例创建于每个方法调用之前,调用完成后会立即销毁该服务实例。
2、实例管理-会话
介绍:一个配置了私有会话的服务通常无法支持多达几十个(或者上百个)独立的客户端,只因为创建专门的服务实例的代价太大。
3、实例管理-单例服务
介绍:一种极端的共享服务,单例服务会在创建宿主时创建,且它的生命周期是无限的,只有在关闭宿主时,单例服务才会被释放。
4、实例管理-限流
介绍:并发会话数,默认值为处理器计数(或内核)的100倍;并发调用最大数,默认值为
处理器计数(或内核
)的16倍;并发实例的最大数量,默认等于最大并发调用的数目和最大并发会话数目(单个处理器116个会话)的和
三、操作
1、回调操作
介绍:客户端调用接口完成后,服务端通过回调方式调用客户端方法
四、事务
1、事务-ConcurrentMode.Single
介绍:一次只允许一个调用者进入,如果同时有多个并发调用,那么调用请求会进入一个队列里等待服务处理。
2、事务-ConcurrentMode.Multiple
介绍:不会为服务实例提供同步访问机制,不会队列化客户端请求,而是在消息到达时就立即发送出去。
附:
非同步访问事务
3、事务-ConcurrentMode.Reentrant
介绍:是对concurrentMode.Single模式的改进。
五、队列服务
1、简单使用
2、最终客户端Web.config文件
新建项目:WCFDemo
引入命名空间:
using System.ServiceModel;
using System.Runtime.Serialization;
using System.Runtime.Serialization;
添加接口:IUserContract(服务契约)
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract]
public interface IUserContract
{
[OperationContract]
bool Login(string userName, string pwd);
}
}
{
[ServiceContract]
public interface IUserContract
{
[OperationContract]
bool Login(string userName, string pwd);
}
}
添加类:UserContract
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WCFDemo
{
public class UserContract : IUserContract
{
public bool Login(string userName, string pwd)
{
if (userName == "x" && pwd == "x")
{
return true;
}
return false;
}
}
}
{
public class UserContract : IUserContract
{
public bool Login(string userName, string pwd)
{
if (userName == "x" && pwd == "x")
{
return true;
}
return false;
}
}
}
添加类:UserInfo(数据契约)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace WCFDemo
{
[DataContract]
public class UserInfo
{
[DataMember]
public string UserName { get; set; }
{
[DataContract]
public class UserInfo
{
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Pwd { get; set; }
}
}
public string Pwd { get; set; }
}
}
Program类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
namespace WCFDemo
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(UserContract));
ServiceMetadataBehavior metadataBehavior;
metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
var httpUri = new Uri("http://192.168.1.104:8002/WCFDemo/UserContract");
var tcpUri = new Uri("net.tcp://192.168.1.104:8001/WCFDemo/UserContract");
if (metadataBehavior == null)
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
}
NetTcpBinding tcpBinding = new NetTcpBinding();
WSHttpBinding wsBinding = new WSHttpBinding();
//以管理员方式运行CMD输入:netsh http add urlacl url=http://+:8002/WCFDemo/UserContract/ user=Everyone
host.AddServiceEndpoint(typeof(IUserContract), wsBinding, httpUri);
host.AddServiceEndpoint(typeof(IUserContract), wsBinding, httpUri);
tcpBinding.MaxBufferPoolSize = 52428800;
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
host.AddServiceEndpoint(typeof(IUserContract), tcpBinding, tcpUri);
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "net.tcp://192.168.1.104:8001/service/");//TCPBindding时,一定要有
host.Open();
Console.WriteLine("服务已启用");
Console.ReadKey();
}
}
}
}
}
}
新建MVCWeb项目:WCFWeb
添加服务引用:
net.tcp://192.168.1.104:8001/service/【注意】
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WCFWeb.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
ServiceReference1.UserContractClient client = new ServiceReference1.UserContractClient("NetTcpBinding_IUserContract");
bool b = client.Login("x", "x");
{
ServiceReference1.UserContractClient client = new ServiceReference1.UserContractClient("NetTcpBinding_IUserContract");
bool b = client.Login("x", "x");
return View();
}
}
}
}
}
web.config文件:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IUserContract">
<security mode="None" />
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IUserContract" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.1.104:8002/WCFDemo/UserContract"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IUserContract"
contract="ServiceReference1.IUserContract" name="WSHttpBinding_IUserContract">
<identity>
<userPrincipalName value="AdministratorPC\john" />
</identity>
</endpoint>
<endpoint address="net.tcp://192.168.1.104:8001/WCFDemo/UserContract"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IUserContract"
contract="ServiceReference1.IUserContract" name="NetTcpBinding_IUserContract" />
</client>
</system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IUserContract">
<security mode="None" />
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IUserContract" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.1.104:8002/WCFDemo/UserContract"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IUserContract"
contract="ServiceReference1.IUserContract" name="WSHttpBinding_IUserContract">
<identity>
<userPrincipalName value="AdministratorPC\john" />
</identity>
</endpoint>
<endpoint address="net.tcp://192.168.1.104:8001/WCFDemo/UserContract"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IUserContract"
contract="ServiceReference1.IUserContract" name="NetTcpBinding_IUserContract" />
</client>
</system.serviceModel>
使用WCFclient测试:
(VS2012自带WcfTestClient.exe测试工具,文件位置:C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE)
单调服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
{
[ServiceContract]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WCFDemo
{
{
//配置为单调
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MonotoneContract : IMonotoneContract, IDisposable
{
private int count = 0;
public int Add()
{
count++;
return count;
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MonotoneContract : IMonotoneContract, IDisposable
{
private int count = 0;
public int Add()
{
count++;
return count;
}
public void Dispose()
{
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
namespace WCFDemo
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(MonotoneContract));
ServiceMetadataBehavior metadataBehavior;
metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
var httpUri = new Uri("http://192.168.1.104:8002/WCFDemo/MonotoneContract");
var tcpUri = new Uri("net.tcp://192.168.1.104:8001/WCFDemo/MonotoneContract");
if (metadataBehavior == null)
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
}
NetTcpBinding tcpBinding = new NetTcpBinding();
WSHttpBinding wsBinding = new WSHttpBinding();
//以管理员方式运行CMD输入:netsh http add urlacl url=http://+:8002/WCFDemo/MonotoneContract/ user=Everyone
host.AddServiceEndpoint(typeof(IMonotoneContract), wsBinding, httpUri);
host.AddServiceEndpoint(typeof(IMonotoneContract), wsBinding, httpUri);
tcpBinding.MaxBufferPoolSize = 52428800;
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
host.AddServiceEndpoint(typeof(IMonotoneContract), tcpBinding, tcpUri);
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "net.tcp://192.168.1.104:8001/service/");//TCPBindding时,一定要有
host.Open();
Console.WriteLine("服务已启用");
Console.ReadKey();
}
}
}
}
}
}
未配置单调服务测试:点击11次,显示效果如下
配置为单调服务:
点击11次,显示效果如下
操作-会话
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract(SessionMode=SessionMode.Required)]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
{
[ServiceContract(SessionMode=SessionMode.Required)]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MonotoneContract : IMonotoneContract, IDisposable
{
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MonotoneContract : IMonotoneContract, IDisposable
{
private int count = 0;
public int Add()
{
count++;
return count;
}
{
count++;
return count;
}
public void Dispose()
{
}
}
}
}
}
主程序Program同上
配置为会话:
点击11次,显示效果如下
操作-单例服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract(SessionMode=SessionMode.Required)]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
{
[ServiceContract(SessionMode=SessionMode.Required)]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MonotoneContract : IMonotoneContract, IDisposable
{
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MonotoneContract : IMonotoneContract, IDisposable
{
private int count = 0;
public int Add()
{
count++;
return count;
}
{
count++;
return count;
}
public void Dispose()
{
}
}
}
}
}
配置为会话:打开两个WCFTestClient,分别点击Invoke一次
,显示效果如下
实例管理-限流
添加类:ServiceThrottleHelper
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace WCFDemo
{
public static class ServiceThrottleHelper
{
public static void SetThrottle(this ServiceHost host, int maxCalls, int maxSessions, int maxInstances)
{
ServiceThrottlingBehavior serviceThrottle = new ServiceThrottlingBehavior();
serviceThrottle.MaxConcurrentCalls = maxCalls;
serviceThrottle.MaxConcurrentSessions = maxSessions;
serviceThrottle.MaxConcurrentInstances = maxInstances;
host.SetThrottle(serviceThrottle);
}
{
public static class ServiceThrottleHelper
{
public static void SetThrottle(this ServiceHost host, int maxCalls, int maxSessions, int maxInstances)
{
ServiceThrottlingBehavior serviceThrottle = new ServiceThrottlingBehavior();
serviceThrottle.MaxConcurrentCalls = maxCalls;
serviceThrottle.MaxConcurrentSessions = maxSessions;
serviceThrottle.MaxConcurrentInstances = maxInstances;
host.SetThrottle(serviceThrottle);
}
public static void SetThrottle(this ServiceHost host, ServiceThrottlingBehavior serviceThrottle, bool overrideConfig)
{
if (host.State == CommunicationState.Opened)
{
throw new InvalidOperationException("Host is already opended");
}
ServiceThrottlingBehavior throttle = host.Description.Behaviors.Find<ServiceThrottlingBehavior>();
if (throttle == null)
{
host.Description.Behaviors.Add(serviceThrottle);
return;
}
if (overrideConfig == false)
{
return;
}
host.Description.Behaviors.Remove(throttle);
host.Description.Behaviors.Add(serviceThrottle);
}
{
if (host.State == CommunicationState.Opened)
{
throw new InvalidOperationException("Host is already opended");
}
ServiceThrottlingBehavior throttle = host.Description.Behaviors.Find<ServiceThrottlingBehavior>();
if (throttle == null)
{
host.Description.Behaviors.Add(serviceThrottle);
return;
}
if (overrideConfig == false)
{
return;
}
host.Description.Behaviors.Remove(throttle);
host.Description.Behaviors.Add(serviceThrottle);
}
public static void SetThrottle(this ServiceHost host, ServiceThrottlingBehavior serviceThrottle)
{
host.SetThrottle(serviceThrottle, false);
}
}
}
{
host.SetThrottle(serviceThrottle, false);
}
}
}
主程序:Program
host.SetThrottle(12, 34, 56);//限流(最大并发调用、最大并发会话数、最大并发实例)
操作-回调操作
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
interface IMonotoneContractCallback
{
[OperationContract]
void OnCallback();
}
}
{
interface IMonotoneContractCallback
{
[OperationContract]
void OnCallback();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract(CallbackContract = typeof(IMonotoneContractCallback))]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
{
[ServiceContract(CallbackContract = typeof(IMonotoneContractCallback))]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
//ConcurrencyMode = ConcurrencyMode.Reentrant 配置重入已支持回调
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class MonotoneContract : IMonotoneContract
{
static List<IMonotoneContractCallback> m_Callbacks = new List<IMonotoneContractCallback>();
{
//ConcurrencyMode = ConcurrencyMode.Reentrant 配置重入已支持回调
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class MonotoneContract : IMonotoneContract
{
static List<IMonotoneContractCallback> m_Callbacks = new List<IMonotoneContractCallback>();
private int count = 0;
public int Add()
{
count++;
{
count++;
/*
IMonotoneContractCallback callbacks = OperationContext.Current.GetCallbackChannel<IMonotoneContractCallback>();
if (m_Callbacks.Contains(callbacks) == false)
{
m_Callbacks.Add(callbacks);
}
CallClients();
*/
OperationContext.Current.GetCallbackChannel<IMonotoneContractCallback>().OnCallback();
IMonotoneContractCallback callbacks = OperationContext.Current.GetCallbackChannel<IMonotoneContractCallback>();
if (m_Callbacks.Contains(callbacks) == false)
{
m_Callbacks.Add(callbacks);
}
CallClients();
*/
OperationContext.Current.GetCallbackChannel<IMonotoneContractCallback>().OnCallback();
return count;
}
}
public static void CallClients()
{
Action<IMonotoneContractCallback> invoke = callback => callback.OnCallback();
{
Action<IMonotoneContractCallback> invoke = callback => callback.OnCallback();
m_Callbacks.ForEach(invoke);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
namespace WCFDemo
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(MonotoneContract));
ServiceMetadataBehavior metadataBehavior;
metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
var httpUri = new Uri("http://192.168.1.104:8002/WCFDemo/MonotoneContract");
var tcpUri = new Uri("net.tcp://192.168.1.104:8001/WCFDemo/MonotoneContract");
if (metadataBehavior == null)
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
}
NetTcpBinding tcpBinding = new NetTcpBinding();
WSHttpBinding wsBinding = new WSHttpBinding();
//以管理员方式运行CMD输入:netsh http add urlacl url=http://+:8002/WCFDemo/MonotoneContract/ user=Everyone
//host.AddServiceEndpoint(typeof(IMonotoneContract), wsBinding, httpUri);(不支付回调)
//host.AddServiceEndpoint(typeof(IMonotoneContract), wsBinding, httpUri);(不支付回调)
tcpBinding.MaxBufferPoolSize = 52428800;
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
host.AddServiceEndpoint(typeof(IMonotoneContract), tcpBinding, tcpUri);
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "net.tcp://192.168.1.104:8001/service/");//TCPBindding时,一定要有
host.SetThrottle(12, 34, 56);//限流
host.Open();
Console.WriteLine("服务已启用");
Console.ReadKey();
}
}
}
}
}
}
客户端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WCFWeb.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
MonotoneContractCallback monotoneContractCallback = new MonotoneContractCallback();
System.ServiceModel.InstanceContext context = new System.ServiceModel.InstanceContext(monotoneContractCallback);
{
MonotoneContractCallback monotoneContractCallback = new MonotoneContractCallback();
System.ServiceModel.InstanceContext context = new System.ServiceModel.InstanceContext(monotoneContractCallback);
ServiceReference1.MonotoneContractClient client = new ServiceReference1.MonotoneContractClient(context, "NetTcpBinding_IMonotoneContract");
var b = client.Add();
var b = client.Add();
return View();
}
}
}
class
MonotoneContractCallback :
WCFWeb.ServiceReference1.IMonotoneContractCallback
{
public void OnCallback()
{
string a = "b";
}
}
}
{
public void OnCallback()
{
string a = "b";
}
}
}
运行效果:
事务-Transactions
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract]
public interface IMonotoneContract
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
int Add();
}
}
{
[ServiceContract]
public interface IMonotoneContract
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
int Add();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.SqlClient;
namespace WCFDemo
{
[Serializable]
[ServiceBehavior(ReleaseServiceInstanceOnTransactionComplete = false, InstanceContextMode = InstanceContextMode.PerSession)]
public class MonotoneContract : IMonotoneContract
{
private int count = 0;
{
[Serializable]
[ServiceBehavior(ReleaseServiceInstanceOnTransactionComplete = false, InstanceContextMode = InstanceContextMode.PerSession)]
public class MonotoneContract : IMonotoneContract
{
private int count = 0;
[OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)]
public int Add()
{
count++;
public int Add()
{
count++;
using (System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=test2;Integrated Security=True"))
{
if (con.State != ConnectionState.Open)
{
con.Open();
}
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "insert into Table_1 values('" + Guid.NewGuid() + "','" + count + "');";
cmd.ExecuteNonQuery();
}
{
if (con.State != ConnectionState.Open)
{
con.Open();
}
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "insert into Table_1 values('" + Guid.NewGuid() + "','" + count + "');";
cmd.ExecuteNonQuery();
}
return count;
}
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
namespace WCFDemo
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(MonotoneContract));
ServiceMetadataBehavior metadataBehavior;
metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
var httpUri = new Uri("http://192.168.1.104:8002/WCFDemo/MonotoneContract");
var tcpUri = new Uri("net.tcp://192.168.1.104:8001/WCFDemo/MonotoneContract");
if (metadataBehavior == null)
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
}
NetTcpBinding tcpBinding = new NetTcpBinding();
WSHttpBinding wsBinding = new WSHttpBinding();
//以管理员方式运行CMD输入:netsh http add urlacl url=http://+:8002/WCFDemo/MonotoneContract/ user=Everyone
host.AddServiceEndpoint(typeof(IMonotoneContract), wsBinding, httpUri);//(不支付回调)
host.AddServiceEndpoint(typeof(IMonotoneContract), wsBinding, httpUri);//(不支付回调)
tcpBinding.MaxBufferPoolSize = 52428800;
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
tcpBinding.TransactionFlow = true;
tcpBinding.TransactionProtocol = TransactionProtocol.WSAtomicTransactionOctober2004;
tcpBinding.TransactionProtocol = TransactionProtocol.WSAtomicTransactionOctober2004;
host.AddServiceEndpoint(typeof(IMonotoneContract), tcpBinding, tcpUri);
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "net.tcp://192.168.1.104:8001/service/");//TCPBindding时,一定要有
host.Open();
Console.WriteLine("服务已启用");
Console.ReadKey();
}
}
}
}
}
}
客户端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
namespace WCFWeb.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
{
ServiceReference1.MonotoneContractClient client = new ServiceReference1.MonotoneContractClient("NetTcpBinding_IMonotoneContract");
using (TransactionScope scope = new TransactionScope())
{
var b = client.Add();
}
using (TransactionScope scope = new TransactionScope())
{
var b = client.Add();
}
using (TransactionScope scope = new TransactionScope())
{
var b = client.Add();
scope.Complete();
}
using (TransactionScope scope = new TransactionScope())
{
var b = client.Add();
scope.Complete();
}
return View();
}
return View();
}
}
}
执行结果:(因为只提交了2次事务,因此只有2条记录)
服务并发模式-Single:
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single)]
public class MonotoneContract : IMonotoneContract
public class MonotoneContract : IMonotoneContract
服务并发模式-Multiple:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
{
[ServiceContract]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
namespace WCFDemo
{
[Serializable]
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MonotoneContract : IMonotoneContract
{
private int count = 0;
{
[Serializable]
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MonotoneContract : IMonotoneContract
{
private int count = 0;
//锁住实例
[MethodImpl(MethodImplOptions.Synchronized)]
public int Add()
{
count++;
[MethodImpl(MethodImplOptions.Synchronized)]
public int Add()
{
count++;
return count;
}
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
{
[ServiceContract]
public interface IMonotoneContract
{
[OperationContract]
int Add();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
namespace WCFDemo
{
//事务性非同步服务必须明确将ReleaseServiceInstanceOnTransactionComplete设置为false
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, ReleaseServiceInstanceOnTransactionComplete = false)]
public class MonotoneContract : IMonotoneContract
{
private int count = 0;
{
//事务性非同步服务必须明确将ReleaseServiceInstanceOnTransactionComplete设置为false
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, ReleaseServiceInstanceOnTransactionComplete = false)]
public class MonotoneContract : IMonotoneContract
{
private int count = 0;
[OperationBehavior(TransactionScopeRequired = true)]
public int Add()
{
count++;
return count;
}
}
}
public int Add()
{
count++;
return count;
}
}
}
列列服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
namespace WCFDemo
{
[ServiceContract]
public interface IMonotoneContract
{
//使用消息队列,只能是单向的,不能有返回值
[OperationContract(IsOneWay = true)]
void Add();
}
}
{
[ServiceContract]
public interface IMonotoneContract
{
//使用消息队列,只能是单向的,不能有返回值
[OperationContract(IsOneWay = true)]
void Add();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;
using System.Data;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
namespace WCFDemo
{
public class MonotoneContract : IMonotoneContract
{
private int count = 0;
{
public class MonotoneContract : IMonotoneContract
{
private int count = 0;
public void Add()
{
count++;
{
count++;
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Messaging;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Messaging;
namespace WCFDemo
{
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(MonotoneContract));
ServiceMetadataBehavior metadataBehavior;
metadataBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
var httpUri = new Uri("http://192.168.1.104:8002/WCFDemo/MonotoneContract");
var tcpUri = new Uri("net.tcp://192.168.1.104:8001/WCFDemo/MonotoneContract");
var msqUri = new Uri("net.msmq://192.168.1.104/private/MyServiceQueue");
if (metadataBehavior == null)
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
{
metadataBehavior = new ServiceMetadataBehavior();
metadataBehavior.HttpGetEnabled = true;
metadataBehavior.HttpGetUrl = httpUri;
host.Description.Behaviors.Add(metadataBehavior);
}
NetMsmqBinding msqBinding = new NetMsmqBinding();
if (MessageQueue.Exists(@".\private$\MyServiceQueue") == false)
{
MessageQueue.Create(@".\private$\MyServiceQueue", true);
}
msqBinding.Security.Mode =NetMsmqSecurityMode.None ;
{
MessageQueue.Create(@".\private$\MyServiceQueue", true);
}
msqBinding.Security.Mode =NetMsmqSecurityMode.None ;
NetTcpBinding tcpBinding = new NetTcpBinding();
WSHttpBinding wsBinding = new WSHttpBinding();
//以管理员方式运行CMD输入:netsh http add urlacl url=http://+:8002/WCFDemo/MonotoneContract/ user=Everyone
host.AddServiceEndpoint(typeof(IMonotoneContract), wsBinding, httpUri);//(不支付回调)
host.AddServiceEndpoint(typeof(IMonotoneContract), wsBinding, httpUri);//(不支付回调)
tcpBinding.MaxBufferPoolSize = 52428800;
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
tcpBinding.MaxBufferSize = 6553600;
tcpBinding.MaxReceivedMessageSize = 6553600;
tcpBinding.PortSharingEnabled = false;
tcpBinding.Security.Mode = SecurityMode.None;//取消身份验证
host.AddServiceEndpoint(typeof(IMonotoneContract), msqBinding, msqUri);
host.AddServiceEndpoint(typeof(IMonotoneContract), tcpBinding, tcpUri);
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "net.tcp://192.168.1.104:8001/service/");//TCPBindding时,一定要有
host.Open();
Console.WriteLine("服务已启用");
Console.ReadKey();
}
}
}
}
}
}
客户端调用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
namespace WCFWeb.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
{
ServiceReference1.MonotoneContractClient client = new ServiceReference1.MonotoneContractClient(" NetMsmqBinding_IMonotoneContract");
if (MessageQueue.Exists(@".\private$\MyServiceQueue") == false)
{
MessageQueue.Create(@".\private$\MyServiceQueue", true);
}
client.Add();
return View();
}
}
}
}
web.config:
<system.serviceModel>
<bindings>
<netMsmqBinding>
<binding name="NetMsmqBinding_IMonotoneContract">
<security mode="None" />
</binding>
</netMsmqBinding>
<netTcpBinding>
<binding name="NetTcpBinding_IMonotoneContract">
<security mode="None" />
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IMonotoneContract" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.1.104:8002/WCFDemo/MonotoneContract"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMonotoneContract"
contract="ServiceReference1.IMonotoneContract" name="WSHttpBinding_IMonotoneContract">
<identity>
<userPrincipalName value="AdministratorPC\john" />
</identity>
</endpoint>
<endpoint address="net.msmq://192.168.1.104/private/MyServiceQueue"
binding="netMsmqBinding" bindingConfiguration="NetMsmqBinding_IMonotoneContract"
contract="ServiceReference1.IMonotoneContract" name="NetMsmqBinding_IMonotoneContract" />
<endpoint address="net.tcp://192.168.1.104:8001/WCFDemo/MonotoneContract"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMonotoneContract"
contract="ServiceReference1.IMonotoneContract" name="NetTcpBinding_IMonotoneContract" />
</client>
</system.serviceModel>
<bindings>
<netMsmqBinding>
<binding name="NetMsmqBinding_IMonotoneContract">
<security mode="None" />
</binding>
</netMsmqBinding>
<netTcpBinding>
<binding name="NetTcpBinding_IMonotoneContract">
<security mode="None" />
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IMonotoneContract" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.1.104:8002/WCFDemo/MonotoneContract"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMonotoneContract"
contract="ServiceReference1.IMonotoneContract" name="WSHttpBinding_IMonotoneContract">
<identity>
<userPrincipalName value="AdministratorPC\john" />
</identity>
</endpoint>
<endpoint address="net.msmq://192.168.1.104/private/MyServiceQueue"
binding="netMsmqBinding" bindingConfiguration="NetMsmqBinding_IMonotoneContract"
contract="ServiceReference1.IMonotoneContract" name="NetMsmqBinding_IMonotoneContract" />
<endpoint address="net.tcp://192.168.1.104:8001/WCFDemo/MonotoneContract"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IMonotoneContract"
contract="ServiceReference1.IMonotoneContract" name="NetTcpBinding_IMonotoneContract" />
</client>
</system.serviceModel>