最近因公司项目接触了下wcf服务 ,在网上找到的资源对于我们新手来说不是很详细,而且都是一个版本。遂将我最近研究的成果记录下来,希望能对大家有帮助,以下都是个人的理解,肯定有不对或者不全的信息,也希望大家能为我纠正,已帮助更多的人解决实际问题。
公司有个项目需要用到客户端vb6.0的开发环境连接到服务器一个软件接口,于是我采用的做法是vb6.0的程序连接服务端的wcf服务,在通过wcf连接软件接口。
以下是我vb6.0连接wcf实现的三种方法:1、IIS连接方式 2、wsHttp寄宿在Windwos系统服务的连接方式 3、Tcp端口寄宿Windows系统服务的连接方式。
在这里IIS的连接方式我就不细讲,网上很容易搜索到,而且很容易配置起来,不过我只用.net平台上连接测试试过。
我的项目结构如下图
以下展现的方式我没有通过配置文件
2、wsHttp连接方式
服务器端,Windows服务代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
wCFmexAddress = "http://" + ServiceIP + ":" + HttpPort + "/GoldInvPrint";//元数据地址
/// <summary>
/// 服务启动前设置参数
/// </summary>
/// <param name="WCFAddress">终结点地址</param>
/// <param name="WCFMexAddress">元数据地址</param>
private void WCFStartService(String WCFAddress, String WCFMexAddress)
{
host = new ServiceHost(typeof(GoldInvPrintLibrary.GoldInvPrint));
WSHttpBinding WSBinding = new WSHttpBinding();//设置安全通信绑定级别
WSBinding.Security.Mode = SecurityMode.None; //SecurityMode.Message;
WSBinding.Name = "GoldInvPrintServer";//定义binding的名称(GoldInvPrintServer_IGoldInvPrint),如果不定义,则为默认WSHttpBinding_IGoldInvPrint
WSBinding.CloseTimeout = new TimeSpan(00, 05, 00);
WSBinding.OpenTimeout = new TimeSpan(00, 05, 00);
WSBinding.SendTimeout = new TimeSpan(00, 05, 00);
WSBinding.ReceiveTimeout = new TimeSpan(00, 20, 00);
WSBinding.ReliableSession.InactivityTimeout = new TimeSpan(0, 20, 0);
//启用事务传播
host.AddServiceEndpoint(typeof(GoldInvPrintLibrary.IGoldInvPrint), WSBinding, new Uri(WCFAddress));//配置终结点
ServiceThrottlingBehavior serviceThrottling = new ServiceThrottlingBehavior();//设置属性,可以优化服务性能
serviceThrottling.MaxConcurrentCalls = int.MaxValue;
serviceThrottling.MaxConcurrentInstances = int.MaxValue;
serviceThrottling.MaxConcurrentSessions = int.MaxValue;
host.Description.Behaviors.Add(serviceThrottling);
ServiceBehaviorAttribute SBA = new ServiceBehaviorAttribute();//将异常传给客户端
SBA.IncludeExceptionDetailInFaults = true;
//启用元数据交换行为
if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
{
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
//元数据地址
behavior.HttpGetUrl = new Uri(WCFMexAddress);//设置WCF服务的路径
host.Description.Behaviors.Add(behavior);
}
host.Open();//启动
OpFile.WriteLog("服务已启动。");
}
#endregion
这里展现的是服务端Windows服务启动wcf服务前的一些参数设置。
检测服务是否启动或者测试wcf是否能正常通讯。需要通过元数据来访问测试。我设置的元数据地址http://192.168.11.108:8045/GoldInvPrint
如下图
如果输入元数据地址出现上图的内容说明第一步已经成功了,服务可以正常的通讯了。
3、客户端vb6.0的配置
Vb6.0代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Private Sub cmdGetObject_Click()
Dim mexMonikerString As String
'' 服务的地址,可以从配置文件取出
mexMonikerString = "service:mexAddress='http://192.168.11.115:8045/GoldInvPrint'" ''元数据地址配置
mexMonikerString = mexMonikerString + ", address='http://192.168.11.115:8045/'" ''终结点地址配置
mexMonikerString = mexMonikerString + ", binding=GoldInvPrintServer_IGoldInvPrint, bindingNamespace='http://tempuri.org/'"
mexMonikerString = mexMonikerString + ", contract=IGoldInvPrint, contractNamespace='http://tempuri.org/'"
'' 获取对象
Set mexService = GetObject(mexMonikerString)
ShowTip "Get object OK!"
End Sub
可以看到Vb6.0连接wcf服务关键是四句代码:元数据地址、终结点地址、binding和命令空间、wcf协议(可能这四个名字我理解的不太正确。欢迎纠正)
关键这四个参数如何配置、如何来找到这些参数、通过什么来找。下面我会把我的理解和方法详细列出来。希望对大家有帮助。
这些信息都需要通过元数据来确定项目中的参数名称,我的项目元数据的地址http://192.168.11.108:8045/GoldInvPrint
第一个参数解决了。
终结点的地址有两个地方可以找到,第一个是服务端Windwos服务中,在方法的参数中的配置。第二个是通过元数据中最下面。如下图
在元数据的下面,可以找到终结点的地址和Bing的内容。对于命名空间来说一般都是默认的http://tempuri.org/,不过如果在接口文件中自己定义命名空间,那么这里元数据的内容也会随之改变,至于为什么会变,变了后怎么配置,这个我没有研究。。。
协议的内容如下图
这样四个参数都配置好了,那么就可以测试下。最后的结果Get object OK!,如果是这个结果那就恭喜你咯。。。
Tcp的连接方式
服务端Windwos启动wcf服务配置代码如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
wCFmexAddress = "http://" + ServiceIP + ":" + HttpPort + "/GoldInvPrint"; //元数据地址
#region ---- private [void] WCFStartService-----服务启动前设置参数
/// <summary>
/// 服务启动前设置参数
/// </summary>
/// <param name="WCFAddress">终结点地址</param>
/// <param name="WCFMexAddress">元数据地址</param>
private void WCFStartService(String WCFAddress, String WCFMexAddress)
{
host = new ServiceHost(typeof(GoldInvPrintLibrary.GoldInvPrint));
NetTcpBinding NTBinding = new NetTcpBinding();//设置安全通信绑定级别
NTBinding.Security.Mode = SecurityMode.None;
NTBinding.PortSharingEnabled = true;//端口共享
NTBinding.Name = "GoldInvPrintServer";
NTBinding.CloseTimeout = new TimeSpan(00, 05, 00);
NTBinding.OpenTimeout = new TimeSpan(00, 05, 00);
NTBinding.SendTimeout = new TimeSpan(00, 05, 00);
NTBinding.ReceiveTimeout = new TimeSpan(00, 20, 00);
NTBinding.ReliableSession.InactivityTimeout = new TimeSpan(0, 20, 0);
//启用事务传播
host.AddServiceEndpoint(typeof(GoldInvPrintLibrary.IGoldInvPrint), NTBinding, new Uri(WCFAddress));//配置终结点
ServiceThrottlingBehavior serviceThrottling = new ServiceThrottlingBehavior();//设置属性,可以优化服务性能
serviceThrottling.MaxConcurrentCalls = int.MaxValue;
serviceThrottling.MaxConcurrentInstances = int.MaxValue;
serviceThrottling.MaxConcurrentSessions = int.MaxValue;
host.Description.Behaviors.Add(serviceThrottling);
//启用元数据交换行为
if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
{
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
//元数据地址
behavior.HttpGetUrl = new Uri(WCFMexAddress);//设置WCF服务的路径
host.Description.Behaviors.Add(behavior);
}
host.Open();//启动
OpFile.WriteLog("服务已启动。");
}
#endregion
Tcp端口方式终结点的配置与wsHttp方式有点区别。同样这里我也没用到配置文件。
客户端VB6.0连接方式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
'TCP方式调用WCF
Private Sub cmdGetObject_Click()
Dim mexMonikerString As String
'' 服务的地址,可以从配置文件取出
mexMonikerString = "service:mexAddress='http://192.168.11.115:8045/GoldInvPrint'" ''元数据地址配置
mexMonikerString = mexMonikerString + ", address='net.tcp://192.168.11.115:8845/'" ''终结点地址配置
mexMonikerString = mexMonikerString + ", binding=GoldInvPrintServer_IGoldInvPrint, bindingNamespace='http://tempuri.org/'"
mexMonikerString = mexMonikerString + ", contract=IGoldInvPrint, contractNamespace='http://tempuri.org/'"
'' 获取对象
Set mexService = GetObject(mexMonikerString)
ShowTip "Get object OK!"
End Sub
Tcp方式VB6.0客户端配置和wsHttp的方式类似,就不在重复说明了。Tcp服务对机器IP要求很严,如果本机的IP和你配置的Ip不一样,那服务就会启动不了。。。wsHttp的这种方式就不会。
以上就是我最近研究的,希望能给大家带来帮助。(如果有描述的不正确或者错误的,还希望高手指正,能给我们新人指点指点,非常感谢!)