本文将详细讲解用C#基于WCF创建TCP的Service供Client端调用的详细过程

1):首先创建一个Windows Service的工程

2):生成的代码工程结构如下所示

3):我们将Service1改名为MainService

4): 添加一个Interface来定义Service的契约

4.1):截图如下所示

4.2):IOrderService.cs的代码如下所示

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks; namespace EricSunService
{
[ServiceContract]
interface IOrderService
{
[OperationContract]
[FaultContract(typeof(ServiceFault))]
AccountLoginResponse AccountLogin(AccountLoginRequest request); [OperationContract]
[FaultContract(typeof(ServiceFault))]
AccountTopUpResponse AccountTopUp(AccountTopUpRequest request);
} [DataContract]
public class ServiceFault
{
[DataMember]
public string CorrelationId { get; set; }
[DataMember]
public string Message { get; set; }
[DataMember]
public string Address { get; set; }
}
}

5):然后添加其他的类实现对应的Service,并且实现对Service的Host

5.1):最终的代码工程截图如下所示(这里的EricSunData工程是用于数据类型的定义,为了更好的逻辑结构分层,这里我们主要以AccountLogin.cs中所实现的OrderService进行讲解)

5.2):AccountLogin.cs的代码如下所示(实现IOrderService中的部分接口)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks; namespace EricSunService
{
public partial class OrderService : IOrderService
{
public AccountLoginResponse AccountLogin(AccountLoginRequest request)
{
// do some logic with account info
AccountLoginResponse loginResponse = new AccountLoginResponse() { AccountBalance = 10000000.00, Status = new AccountLoginStatus() };
return loginResponse;
}
} [DataContract]
public class AccountLoginRequest
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Password { get; set; }
} [DataContract]
public class AccountLoginResponse
{
[DataMember]
public double AccountBalance { get; set; }
[DataMember]
public AccountLoginStatus Status { get; set; }
} public enum AccountLoginStatus
{
NoError = ,
InvalidAccountInfo // Invalid Account Info
}
}

5.3):MainService的代码如下所示 (进行对Service的Host)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks; namespace EricSunService
{
public partial class MainService : ServiceBase
{
private ServiceHost _orderService; public MainService()
{
InitializeComponent();
} protected override void OnStart(string[] args)
{
_orderService = new ServiceHost(typeof(OrderService));
_orderService.Open();
} protected override void OnStop()
{
_orderService.Close();
}
}
}

5.4):Program.cs的代码如下所示 (.exe运行时主入口)

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks; namespace EricSunService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
#if DEBUG
ServiceHost host = new ServiceHost(typeof(OrderService));
host.Open();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MainService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
}
}

6):运行Service时的可能错误以及App.config的配置

6.1):当我们build真个solution之后,到对应的debug目录去运行对应的EricSunService.exe文件时,有可能会出现如下错误,为了解决如下的错误才有了5.4中写法

6.2):App.config文件的配置信息,是对WCF框架下暴露Service的endpoint(ABC)的一个详细配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup> <system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="OrderServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="OrderServiceBehavior" name="EricSunService.OrderService">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:3434/" />
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBindingConfig" contract="EricSunService.IOrderService"/>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingConfig">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel> </configuration>

7):创建一个Asp.Net MVC 的工程作为Client端去调用所提供的Service,之后是添加对OrderService的引用,如下图所示

8):在EricSunService.exe运行起来的状态下,去update此OrderServiceReference,如下图所示

9):点击Show All Files之后会看到如下详细的工程文件信息

10):同时我们发现了如下图的错误信息

11):为了解决这个错误信息,请按下图的步骤进行操作

11.1):鼠标右键点击OrderServiceReference后选择Config Service Reference

11.2):取消对Reuse types in referenced assemblies的勾选

11.3):点击上图中的OK按钮之后,生成了Service所对应Data的详细信息,如下图所示

11.4):最终的工程结构如下图所示

12):Service的引用添加完毕之后,就可以对Service进行调用了,我们这里选择的是ChannelFactory的方式,详细代码如下所示

12.1):OrderServiceClientFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Web;
using EricSunWeb.OrderServiceReference; namespace EricSunWeb.Business
{
public static class OrderServiceClientFactory
{
private static readonly object CRITICAL_SECTION = new object();
private static ChannelFactory<IOrderServiceChannel> s_ChannelFactory = null; public static IOrderServiceChannel CreateClient()
{
if (s_ChannelFactory == null || s_ChannelFactory.State == CommunicationState.Faulted)
{
lock (CRITICAL_SECTION)
{
if (s_ChannelFactory == null)
{
s_ChannelFactory = new ChannelFactory<IOrderServiceChannel>("NetTcpBinding_IOrderService");
}
else if (s_ChannelFactory.State == CommunicationState.Faulted)
{
s_ChannelFactory.Abort();
s_ChannelFactory = new ChannelFactory<IOrderServiceChannel>("NetTcpBinding_IOrderService");
}
}
} return s_ChannelFactory.CreateChannel();
}
}
}

12.2):OrderManager.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EricSunWeb.OrderServiceReference; namespace EricSunWeb.Business
{
public class OrderManager
{
public void AccountLogin(string name, string password)
{
var request = new AccountLoginRequest
{
Name = name,
Password = password
}; AccountLoginResponse response = null;
var client = OrderServiceClientFactory.CreateClient();
response = client.AccountLogin(request); if (response.Status == AccountLoginStatus.NoError)
{ }
else
{ }
}
}
}

12.3):OrderController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using EricSunWeb.Business;
using EricSunWeb.OrderServiceReference; namespace EricSunWeb.Controllers
{
public class OrderController : Controller
{
//
// GET: /Order/ public ActionResult Index()
{
new OrderManager().AccountLogin("EricSun", "password");
return View();
} }
}

OK,整个过程就这样结束了。

用C#基于WCF创建TCP的Service供Client端调用的更多相关文章

  1. Learning WCF Chapter1 Generating a Service and Client Proxy

    In the previous lab,you created a service and client from scratch without leveraging the tools avail ...

  2. 在基于WCF开发的Web Service导出WSDL定义问题及自定义wsdl:port 名称

             在契约优先的Web服务开发过程中,往往是先拿到WSDL服务定义,各家开发各自的服务实现或客户端,然后互相调用.          尽管Web Service的标准已经发布很多年,但各 ...

  3. WCF service 获取 client 端的 IP 和 port (转)

    转帖记录一下,以便日后使用. 主要使用是.NET3.5里的服务端上下文的消息实例的RemoteEndpointMessageProperty属性,获取客户端地址信息.但是限制 的绑定是HTTP.TCP ...

  4. web service client端调用服务器接口

    打开项目的web service client 其中wsdl URL    http://www.51testing.com/html/55/67755-848510.html 去这里面查找一些公开的 ...

  5. 使用WCF 创建 Rest service

    REST SERVICE 允许客户端修改url路径,并且web端功过url 请求数据. 他使用http协议进行通讯,想必大家都知道 . 并且我们可以通过设置进行数据类型转换, 支持XML,JSON 格 ...

  6. 基于Netty和SpringBoot实现一个轻量级RPC框架-Client端请求响应同步化处理

    前提 前置文章: <基于Netty和SpringBoot实现一个轻量级RPC框架-协议篇> <基于Netty和SpringBoot实现一个轻量级RPC框架-Server篇> & ...

  7. 宿主在Windows Service中的WCF(创建,安装,调用) (host到exe,非IIS)

    1. 创建WCF服务 在vs2010中创建WCF服务应用程序,会自动生成一个接口和一个实现类:(IService1和Service1) IService1接口如下:   using System.Ru ...

  8. 【Azure 微服务】基于已经存在的虚拟网络(VNET)及子网创建新的Service Fabric并且为所有节点配置自定义DNS服务

    问题描述 创建新的Service Fabric集群,可以通过门户,Powershell命令,或者是ARM模板.但是通过门户和PowerShell命令时,创建的SF集群都会自动新建一个虚拟网络而无法使用 ...

  9. 基于.Net FrameWork的 RestFul Service

    关于本文 这篇文章的目的就是向大家阐述如何在.net framework 4.0中创建RestFul Service并且使用它. 什么是web Services,什么是WCF 首先讲到的是web Se ...

随机推荐

  1. Windows下安装Maven

    上篇文章刚说到Linux下安装maven的过程,有时候为了适合在本地构建项目开发,然后上传到远程服务器执行,需要在本地构建maven项目,那么一般就是在Windows下构建maven项目并导入到我们的 ...

  2. Effective C++ -----条款27:尽量少做转型动作

    如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts.如果有个设计需要转型动作,试着发展无需转型的替代设计. 如果转型是必要的,试着将它隐藏于某个函数背后.客户随后可以调用该 ...

  3. nyoj116_士兵杀敌(二)_树状数组

    士兵杀敌(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...

  4. C# 对象深度拷贝

    转载 using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using ...

  5. 【linux】学习4

    文件压缩: gzip :压缩   解压缩 zcat: 读取压缩文件 gzip text1  :压缩text1 得到 text1.gz 原文件不见了 gzip -c text1 > text1.g ...

  6. 【Git】自定义Git

    来源:廖雪峰 让Git显示颜色 git config --global color.ui true 忽略特殊文件 有些文件有敏感信息,或者是自动生成的中间文件.不能或不必提交到git,可以用.giti ...

  7. orace 取昨天凌晨的日期

    sysdate 为现在时间sysdate-1为昨天trunc(sysdate-1)为昨天凌晨0:00trunc(sysdate-1)+20/24 为昨天晚上8点select trunc(sysdate ...

  8. SQL常用命令整理

    1.增加字段 alter table docdsp     add dspcodechar(200)2.删除字段     ALTER TABLE table_NAME DROP COLUMNcolum ...

  9. error C2664: 'TextOutW' : cannot convert parameter 4 from const char [5]' to LPCTSTR

    转自:http://blog.sina.com.cn/s/blog_4aa4593d0100odra.html 问题的原因是字符串ANSI和Unicode编码的区别, VC6与VS2003等默认使用A ...

  10. [USACO07MAR]黄金阵容均衡Gold Balanced L…(洛谷 1360)

    题目描述 Farmer John's N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been able to na ...