本文将详细讲解用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. Print Common Nodes in Two Binary Search Trees

    Given two Binary Search Trees, find common nodes in them. In other words, find intersection of two B ...

  2. flume与kafka整合

    flume与kafka整合 前提: flume安装和测试通过,可参考:http://www.cnblogs.com/rwxwsblog/p/5800300.html kafka安装和测试通过,可参考: ...

  3. MySQL进程常见的State【转】

    为了查阅方便,做个笔记. 通过show processlist查看MySQL的进程状态,在State列上面的状态有如下这些: Analyzing线程对MyISAM 表的统计信息做分析(例如, ANAL ...

  4. ffmpeg-20160515-git-bin

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...

  5. FIX_前缀后缀_未提交

    问题 B: FIX 时间限制: 1 Sec  内存限制: 64 MB提交: 38  解决: 11[提交][状态][讨论版] 题目描述 如果单词 X 由单词 Y 的前若干个字母构成,我们称 X 是 Y ...

  6. (转)JAVA AJAX教程第四章—AJAX和MVC的简单结合

    这里我们再理解了AJAX后,开始来用实例感受AJAX的力量. 今天我最后要实现的效果,当鼠标放到图片上时会根据,会把数据库库里的数据读出,通过显示框显示出来.这个在很多网上商店都有用到这里效果,我们这 ...

  7. 【leetcode】Minimum Size Subarray Sum(middle)

    Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...

  8. java判断身份证有效性

    import java.util.Calendar; public class CertNoUtil { public static boolean vIDNumByRegex(String idNu ...

  9. Innodb之监控Buffer pool Load progress

    你可以使用PERFORMANCE SCHEMA中的相关信息监控BUFFER POOL状态加载进程. 1. 启用 stage/innodb/buffer pool load instrument: 2. ...

  10. C++异常层次结构图