WCF 同一个代理共享全局变量
我们用VS默认创建一个WCF服务,定义一个全局变量,如
private string _appName = string.Empty;
假如我们在服务端创建两个方法,第一个方法给_appName赋值,第二个方法读取_appName:
public void SetValue(string name) { _appName = name; } public string GetValue() { return _appName; }
同样,用VS创建一个代理来调用这个服务,先赋值再取值
NServices.LogServiceClient client = new NServices.LogServiceClient(); client.SetValue("OK"); string s = client.GetValue();
这时,我们发现,调用GetValue方法的返回值竟然是空的!!!这是怎么回事?
问了园子里的大牛Artech,答曰:采用PerSession实例化模式 + 开启Session + 采用支持Session的绑定
于是,自己就逐个击破。
服务有三种实例模式:分别是PerSession、PerCall、Single ,关于这些模式的区别可以看这篇文
http://www.cnblogs.com/tyb1222/archive/2012/10/12/2721252.html
其实服务的默认模式就是PerSession,要显示的将服务改PerSession模式成只要在服务的类前面加一个
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
默认情况下,服务也是会启动会话的,显示的做法则在每个方法接口前加下面这两个属性:
[OperationContract(IsTerminating = false, IsInitiating = true)]
所以,罪魁祸首还是服务的绑定。
VS自建的默认服务绑定是basicHttpBinding ,而basicHttpBinding不支持会话。所以,每调用一次方法完成后,会话都会结束掉,调用另一个方法又要重新实例化。
关于哪些绑定支持会话,可以看这篇文章:http://www.cnblogs.com/jillzhang/archive/2008/02/03/1063406.html,里面有一个很全面直观的表。
要让服务支持会话,要称在服务接口中加一个属性:
[ServiceContract(SessionMode=SessionMode.Required,Name="LogServices")] public interface ILogService {}
然后再修改服务的配置文件:
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 --> <serviceMetadata httpGetEnabled="true" /> <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="metadataBehavior" name="LogServices.LogService"> <endpoint binding="wsHttpBinding" contract="LogServices.ILogService" /> </service> </services> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel>
这里我采用的是wsHttpBinding.
这样就成功解决这个问题了。
如果我的文章对你有帮助,就点一下推荐吧.(*^__^*)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步