最近遇到一个新项目,需要与硬件结合,进行读取信息并保存在数据库中。业务要求也在昨天发布一个问题,当然感谢许多园内的朋友出谋划策,截图有真相!

关于这个问题,我做了如下假设。目前处于测试状态,代码比较简单,具体功能已经实现。

1、首先一张比较丑的图片表名业务逻辑关系。


用户customer 他可以去A  B  C  D 四个办事处去登记信息。这样假设每个办事处有一个登记人员,假设customer 选择了 A ,(可能是离A比较近,他不想跑了)

登记人员说出示的卡。登记人员就把的卡往Arecorder 一放,点击鼠标,用户的信息就可以显示到web界面上了。看到这里是不是感觉很简单,不就是Arecorder 把customer的信息发送给web页面了吗?

你说的没有错,就是这么简单。那简单咱就技术实现吧。

技术实现:需要考虑哪些问题。

      1》  A recorder 只是一台具有连接网络或者局域网的计算机。 web 服务管理也不是部署在 A recorder 计算机上的,当然大家知道是部署在服务器上的。那么问题来了。要实现web服务器与Arecorder之间的通信怎么实现呢?

这也难不倒你,网络传输tcp socket编程。。。不难。这里对于这个问题,我们不做深入探究。我使用的是WCF技术。

2》  好了,web服务与A recorder 通信的问题解决了,那就写程序白。。。。。,半个小时过去了,你的编码速度很牛啊,service端和client的代码都搞定了,现在就测试可不可以呢。说道这里,service端的代码发布到与web服务IIS上面去,client代码当然去监控A recorder了,这里本来没有任何问题,我们知道service 的程序时一直运行的,它们之间的关系可以简单一张图表示,当然只是简单的 request-response模式。

看到这里,你可能发现问题。我应该何时请求呢,我贴卡的时候去Request,这是个好主意,Request 发送到哪里呢,肯定是service呀,不然还能发送到哪了,哈,那么问题来了? web服务管理不是给你一个人使用的,也就是说有好多人都在使用这套管理系统,可能赵四 王五 都在 登记用户信息,好你拿着custmoer的卡一刷,Request 就发送出去了,那么它会发送到你打开的web 页上吗???,或者发送到 赵四、或者王五的打开的页面上呢,那么这样这么多不确定性,确实不好办呢。怎么办???赶紧想呀,经理崔项目呢。。。

3》 时间一点一点过去,你想呀,突然脑袋灵光一现,为什么我非要等到customer刷卡的时,去Request呢,我为什么不能使登记人员去把握Request呢。而 A recorder 成为service呢。这样之间的关系不就清楚了吗。是呀到这里,恭喜你。那还等什么赶紧code呀。。。。,测试下,果然不错。哈哈哈。

4》经理说,我们不是需要一个A recorder,而是有 B C D 。。。,你一个都搞定了,多加几个也是没有问题的吧。瞬间整个人都不好了。。。,经理说了那也上呀,多个录卡器,多个工作登记人员,要想实现信息登录的正确性,怎么办,web服务又是大家共享的,顺着思路想下去,。。。。,多个Recorder,那就要区分每个Recorder,那好办,每个都绑定一个固定的IP不就可以了吗? 然后让web request ,好呀,干嘛,code呀。。。。,不对,我web request 了,那我应该需要的是哪个recorder的信息呢,怎么办? 这可能会造成我把别的customer的信息请求过来的。要是事先能知道Request哪一个就好了,怎么办,那就让登记人员,在请求的时候把选中那个recorder。不就可以了吗。是呀,如图:

5》到这里,通过分析已经找到了,解决方案,那么接下来要看编程技术了,这里只是简单的分享下。

coding: Recorder 端的代码。wcf基本结构四层结构;

Contract:

1---》IOctorpusService.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace DataWorld.Octorpus.Contract
{
[ServiceContract]
[ServiceKnownType(typeof(RecordMintor))]
public interface IOctorpusService
{
[OperationContract]
[FaultContract(typeof(OctorException))]
string GetOctorpusNo();
}
}

2----》OctorException.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace DataWorld.Octorpus.Contract
{
[DataContract]
public class OctorException
{
#region 私有类
private string _operation;
private string _errorMessage;
#endregion
#region 构造函数
public OctorException(string operation, string errorMessage)
{
this._operation = operation;
this._errorMessage = errorMessage;
}
#endregion
#region 公共方法
[DataMember]
public string Operation
{
get { return _operation; }
set { _operation = value; }
}
[DataMember]
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value; }
}
#endregion }
}

3----》RecordMintor.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace DataWorld.Octorpus.Contract
{
[DataContract]
public class RecordMintor
{
#region 私有字段
private string _CarNo;
private string _OctorpusNo;
#endregion
#region 构造函数
public RecordMintor(string carno, string octorpusno)
{
this._CarNo = carno;
this._OctorpusNo = octorpusno;
}
#endregion
#region 公共属性
[DataMember]
public string CarNo
{
get { return _CarNo; }
set { _CarNo = value; }
}
[DataMember]
public string OctorpusNo
{
get { return _OctorpusNo; }
set { _OctorpusNo = value; }
}
#endregion
}
}

Service:

1--》OctorpusService.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataWorld.Octorpus.Contract;
namespace DataWorld.Octorpus.Service
{
public class OctorpusService:IOctorpusService
{ public string GetOctorpusNo()
{
// OctorException oe = new OctorException("Server exception", "Restart server"); RecordMintor rm = new RecordMintor(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
//throw new NotImplementedException();
Console.WriteLine(rm.CarNo);
return rm.OctorpusNo;
}
}
}

hosting:

1--》 program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataWorld.Octorpus.Service;
using System.ServiceModel;
namespace DataWorld.Octorpus.Hosting
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(OctorpusService)))
{
host.Opened += delegate { Console.WriteLine("listening..."); };
host.Open();
Console.Read();
}
}
}
}

2--》App.config

 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding">
<security mode="None">
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors> <behavior name="OctorpusServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Company.Octorpus.Service.OctorpusService" behaviorConfiguration="OctorpusServiceBehavior">
<endpoint address="" binding="wsHttpBinding" contract="Company.Octorpus.Contract.IOctorpusService" bindingConfiguration="wsHttpBinding"/>
<host>
<baseAddresses>
<add baseAddress="http://192.168.19.56:9999/Service"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>

client:我写在了web中;

AutoGetCarNO.ashx

 using System;
using System.Collections.Generic;
using System.Web; namespace fairviewweb.Management
{
/// <summary>
/// Summary description for AutoGetCarNO
/// </summary>
public class AutoGetCarNO : IHttpHandler
{
private DateTime _endTime;
private bool _IsEndFlag = false;
private string _msg=null;
private Maticsoft.BLL.t_Recorder tbll = new Maticsoft.BLL.t_Recorder();
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string CarNodroplist = context.Request.QueryString["CarNodroplist"] == null ? string.Empty : context.Request.QueryString["CarNodroplist"].ToString();
Maticsoft.Model.t_Recorder tmodel= tbll.GetModel(CarNodroplist.Trim());
this._endTime=DateTime.Now.AddSeconds();
switch (tmodel.IPADDRESS)
{
case "ServiceReferenceA": try
{
ServiceReference1.OctorpusServiceClient _octorpusNO = new ServiceReference1.OctorpusServiceClient();
this._msg = _octorpusNO.GetOctorpusNo();
while (!_IsEndFlag)
{ if (!string.IsNullOrEmpty(this._msg))
{
_IsEndFlag = true;
}
if (this._endTime <= DateTime.Now)
{
_IsEndFlag = true;
}
}
if (string.IsNullOrEmpty(this._msg))
{
context.Response.Write("timeout");
}
else
{
context.Response.Write(this._msg);
}
}
catch (Exception ex)
{
string msg = ex.Message;
context.Response.Write("timeout");
}
break;
case "ServiceReferenceB": try
{
ServiceReference2.OctorpusServiceClient _octorpusNO = new ServiceReference2.OctorpusServiceClient();
this._msg = _octorpusNO.GetOctorpusNo();
while (!_IsEndFlag)
{ if (!string.IsNullOrEmpty(this._msg))
{
_IsEndFlag = true;
}
if (this._endTime <= DateTime.Now)
{
_IsEndFlag = true;
}
}
if (string.IsNullOrEmpty(this._msg))
{
context.Response.Write("timeout");
}
else
{
context.Response.Write(this._msg);
}
}
catch (Exception ex)
{
string msg = ex.Message;
context.Response.Write("timeout");
}
break;
case "ServiceReferenceC": try
{
ServiceReference1.OctorpusServiceClient _octorpusNO = new ServiceReference1.OctorpusServiceClient();
this._msg = _octorpusNO.GetOctorpusNo();
while (!_IsEndFlag)
{ if (!string.IsNullOrEmpty(this._msg))
{
_IsEndFlag = true;
}
if (this._endTime <= DateTime.Now)
{
_IsEndFlag = true;
}
}
if (string.IsNullOrEmpty(this._msg))
{
context.Response.Write("timeout");
}
else
{
context.Response.Write(this._msg);
}
}
catch (Exception ex)
{
//string msg = ex.Message;
context.Response.Write("timeout");
}
break;
} } public bool IsReusable
{
get
{
return false;
}
}
}
}

最后还给大家来个小贴图把:

前段的;

简单说明下,这个B代表是个Recorder ,然后去请求客户端。页面的实现是采用Ajax异步传输的,这里就不在累赘了。我只是采用这种办法,解决了,这个问题,如果你有更好的办法,可以继续交流。谢谢!

业务需求那些事,使用WCF如何实现业务需求!的更多相关文章

  1. 如何快速分析一款ios软件或需求的大流程,然后在业务层实现,不牵扯到界面?

    如何快速分析一款ios软件或需求的大流程,然后在业务层实现,不牵扯到界面?

  2. 业务SQL那些事--慎用LIMIT

    业务SQL那些事--慎用LIMIT 在业务中使用LIMIT限制SQL返回行数是很常见的事情,但如果不知道其中可能的坑或者说真正执行逻辑,就可能会使SQL执行非常慢,严重影响性能. LIMIT OFFS ...

  3. 什么是业务运维,企业如何实现互联网+业务与IT的融合

    业务运维并不是一个新概念,针对传统信息架构提出的业务服务管理就是把以业务为核心的IT系统与IT基础设施性能进行整合运维的解决方案.然而随着互联网+转型的不断推进,基础设施的智能化和广泛云化成为IT发展 ...

  4. DDD实战进阶第一波(八):开发一般业务的大健康行业直销系统(业务逻辑条件判断最佳实践)

    这篇文章其实是大健康行业直销系统的番外篇,主要给大家讲讲如何在领域逻辑中,有效的处理业务逻辑条件判断的最佳实践问题. 大家都知道,聚合根.实体和值对象这些领域对象都自身处理自己的业务逻辑.在业务处理过 ...

  5. 第二阶段:4.商业需求文档MRD:6.PRD-其他需求

  6. 业务逻辑审批流、审批流、业务、逻辑、面向对象、工作方式【c#】

    ------需求分析:--------1.先按照实际线下流程说这是什么事情,实际要干什么.2.再转换为面向对象-页面的操作流程,演示demo3.再与相关人员沟通是否可行需要什么地方修正.4.最终:线上 ...

  7. Android组件化

    附:Android组件化和插件化开发 App组件化与业务拆分那些事 Android项目架构之业务组件化 Android组件化核心之路由实现 Android组件化开发实践

  8. 深入浅出面向对象分析与设计读书笔记一&吉他搜索案例&吉他特性锚点集中&委托&重用&业务阶段&需求列表&用例

    案例:吉他搜索Guitar Inventory GuitarSpec需求变化:增加吉他弦数特性原始程序需要的变化: 1.修改GuitarSpec,构造,成员,getter 2.修改Guitar,构造, ...

  9. 我眼中BA(业务需求分析师)的技能广度和深度

    BA,或者称业务分析师,是企业数字能力和业务能力之间的沟通桥梁.随着企业数字转型的进一步深化,相信对BA这样的技能需求会越来越多,只是未必都用“BA/业务分析师”这样的Title. ThoughtWo ...

随机推荐

  1. 顶尖数据挖掘教学案例库(TipDM-C10)产品白皮书

          顶尖数据挖掘教学案例库 (TipDM-C10)           产  品  说  明  书 广州泰迪智能科技有限公司 版权所有 地址: 广州市经济技术开发区科学城232号 网址: ht ...

  2. OAuth2.0基本流程

    用户请求客户端>客户端通过在授权服务器上申请的apikey和apisceret>登录访问资源服务器

  3. Android UI目录

    Android UI目录 序:最近一直想进阶android应用开发,虽然对一些相关的android知识都大体熟悉,但是自己的android知识体系,经不起推敲.经不起高手的垂问.经过几个月的努力学习, ...

  4. C#整理4——循环语句

    一.循环语句  定义:可以反复执行某段代码,直到不满足循环条件为止. 循环的四要素:初始条件.循环条件.状态改变.循环体. 1.初始条件:循环最开始的状态. 2.循环条件:在什么条件下进行循环,不满足 ...

  5. JS中slice,splice,split的区别

    不知道大家对slice,splice,splite是肿么样的感觉,反正我刚接触到这三个函数的时候整个人都懵了,因为一个个长的跟孪生兄弟似的,每次用的时候都会混,于是决定记下来,也给大家当个参考吧. s ...

  6. week 与 strong区别 精辟的解释

    转:http://stackoverflow.com/questions/9262535/explanation-of-strong-and-weak-storage-in-ios5 觉得讲的很容易理 ...

  7. zookeeper_02:zookeeper基础

    ZooKeeper基础概述 ZooKeeper维护一个小型的数据节点,这些节点被称为znode,采用类似于文件系统的层级树状结构进行管理. 针对一个znode,没有数据常常表达了重要的信息.比如,在主 ...

  8. Windows中的句柄

    (一)句柄 在程序设计中,句柄(handle)是一种特殊的智能指针.当一个应用程序要引用其他系统(如数据库.操作系统)所管理的内存块或对象时,就要使用句柄. 句柄与普通指针的区别在于,指针包含的是引用 ...

  9. 多主一从mysql replication同步表的大胆尝试.

    能否将不同机器上的不同库中的表同步到同一个机器的同一个库中?表是不同的.而且对于slave这台机子来说,这些表只用来读.   同步不同库的表很简单了,用 replicate-do-table=db_n ...

  10. nginx解决502错误

    添加一个域名绑定,突然服务器就挂了.由于是接受项目,没看过服务器配置.结果nginx和mysql 都跑不起来. 平滑启动nginx失败. 检查/usr/local/nginx/sbin/nginx - ...