你的位置:首页 > ASP.net教程

[ASP.net教程]【原创】WCF+Socket实现Java和.Net智能停车系统交互

1.前言

 公司的一个项目,智能停车系统,我负责的主要是微信公众平台的开发,和socket异步通讯这块,来完成云平台和停车收费软件之间的交互。

 

车辆出场处理流程图【点击查看】【图片太大存放相册里面】

2.WCF

移动终端发起支付请求的时候,云平台会调用我这边的wcf,废话不多说,之间上代码。

  // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“ICalculationService”。  [ServiceContract]  public interface ICalculationService  {    [OperationContract]     string Calculation(string orderid, string parkId);    [OperationContract]    void PayNotify(string parkId, string orderid, string fee, string paytime, string actualFee);    [OperationContract]    string CarUpdate(string parkId, string carNo, string carTypeId, string startTime, string outTime, string recordTye,string key);  }

 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“CalculationService”。  public class CalculationService : ICalculationService  {    public static AsynchronousSocketListener socketListener = null;    /// <summary>    ///请求计费    /// </summary>    public string Calculation(string orderid, string parkId)    {      string result = Service1.socketListener.Calculation(int.Parse(parkId), orderid);      return result;    }    /// <summary>    /// 停车费支付通知    /// </summary>    /// <returns></returns>    public void PayNotify(string parkId, string orderid, string fee, string paytime, string actualFee)    {      Service1.socketListener.PayNotify(int.Parse(parkId), orderid,fee,paytime,actualFee);    }    /// <summary>    /// 车辆信息同步    /// </summary>    public string CarUpdate(string parkId, string carNo, string carTypeId, string startTime, string outTime, string recordTye,string key)    {      string result = Service1.socketListener.CarUpdate(int.Parse(parkId),carNo,carTypeId,startTime,outTime,recordTye,key);      return result;    }  }

 在来看一下,我们的这个公共帮助类关于WCF的一些配置帮助类。

using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Runtime.Serialization;using System.ServiceModel;using System.ServiceModel.Description;using System.ServiceModel.Security;using System.ServiceModel.Dispatcher;using System.Text;using System.namespace GoSunCN.OECD.CommunicationService.Common{  /// <summary>  /// 传输参数方式  /// </summary>  public enum EnumHttpBindingType  {    Small = 0,    Normal = 1  }  /// <summary>  /// WCF 配置的帮助类  /// </summary>  public static class WcfConfigHelper  {    /// <summary>    /// 获取bassHTTP绑定    /// </summary>    /// <returns></returns>    public static BasicHttpBinding GetBasicHttpBinding(EnumHttpBindingType bindingType)    {      BasicHttpBinding ws = new BasicHttpBinding(BasicHttpSecurityMode.None);      ws.CloseTimeout = new TimeSpan(0, 5, 0);      ws.OpenTimeout = new TimeSpan(0, 5, 0);      ws.ReceiveTimeout = new TimeSpan(0, 20, 0);      ws.SendTimeout = new TimeSpan(0, 5, 0);      ws.AllowCookies = false;      ws.BypassProxyOnLocal = false;      ws.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;      ws.MaxBufferSize = 2147483647;      ws.MaxBufferPoolSize = 2147483647;      ws.MaxReceivedMessageSize = 2147483647;      ws.MessageEncoding = WSMessageEncoding.Text;      ws.TextEncoding = Encoding.UTF8;      ws.TransferMode = TransferMode.Buffered;      ws.UseDefaultWebProxy = true;      ws.AllowCookies = false;       ws.ReaderQuotas.MaxDepth = 2147483647;      ws.ReaderQuotas.MaxStringContentLength = 2147483647;      ws.ReaderQuotas.MaxArrayLength = 2147483647;      ws.ReaderQuotas.MaxBytesPerRead = 2147483647;      ws.ReaderQuotas.MaxNameTableCharCount = 2147483647;      ws.Security.Mode = BasicHttpSecurityMode.None;      ws.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;      ws.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;      ws.Security.Transport.Realm = "";      ws.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;      ws.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;      return ws;    }    /// <summary>    /// 获取默认HTTP绑定    /// </summary>    /// <returns></returns>    public static WSHttpBinding GetWsHttpBinding(EnumHttpBindingType bindingType)    {      WSHttpBinding ws = new WSHttpBinding(SecurityMode.None);      ws.CloseTimeout = new TimeSpan(0, 5, 0);      ws.OpenTimeout = new TimeSpan(0, 5, 0);      ws.ReceiveTimeout = new TimeSpan(0, 20, 0);      ws.SendTimeout = new TimeSpan(0, 5, 0);      ws.BypassProxyOnLocal = false;      ws.TransactionFlow = false;      ws.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;      ws.MaxBufferPoolSize = 2147483647;// 524288;      ws.MaxReceivedMessageSize = 2147483647;      ws.MessageEncoding = WSMessageEncoding.Text;      ws.TextEncoding = Encoding.UTF8;      ws.UseDefaultWebProxy = true;      ws.AllowCookies = false;      ws.ReaderQuotas.MaxDepth = 2147483647;      ws.ReaderQuotas.MaxStringContentLength = 2147483647;      ws.ReaderQuotas.MaxArrayLength = 2147483647;      ws.ReaderQuotas.MaxBytesPerRead = 2147483647;      ws.ReaderQuotas.MaxNameTableCharCount = 2147483647;      ws.ReliableSession.Ordered = true;      ws.ReliableSession.InactivityTimeout = new TimeSpan(23, 59, 0);      ws.ReliableSession.Enabled = true;      ws.Security.Mode = SecurityMode.None;      ws.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;      ws.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;      ws.Security.Transport.Realm = "";      ws.Security.Message.ClientCredentialType = MessageCredentialType.Windows;      ws.Security.Message.NegotiateServiceCredential = true;      ws.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;      ws.Security.Message.EstablishSecurityContext = false;      return ws;    }    /// <summary>    /// 获取默认HTTP绑定(双工通信)    /// </summary>    /// <returns></returns>    public static WSDualHttpBinding GetWsDualHttpBinding(EnumHttpBindingType bindingType)    {      WSDualHttpBinding ws = new WSDualHttpBinding(WSDualHttpSecurityMode.Message);      ws.CloseTimeout = new TimeSpan(0, 5, 0);      ws.OpenTimeout = new TimeSpan(0, 5, 0);      ws.ReceiveTimeout = new TimeSpan(0, 20, 0);      ws.SendTimeout = new TimeSpan(0, 5, 0);      ws.BypassProxyOnLocal = false;      ws.TransactionFlow = false;      ws.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;      ws.MaxBufferPoolSize = 2147483647;// 524288;      ws.MaxReceivedMessageSize = 2147483647;      ws.MessageEncoding = WSMessageEncoding.Text;      ws.TextEncoding = Encoding.UTF8;      ws.UseDefaultWebProxy = true;      ws.ReaderQuotas.MaxDepth = 2147483647;      ws.ReaderQuotas.MaxStringContentLength = 2147483647;      ws.ReaderQuotas.MaxArrayLength = 2147483647;      ws.ReaderQuotas.MaxBytesPerRead = 2147483647;      ws.ReaderQuotas.MaxNameTableCharCount = 2147483647;      ws.ReliableSession.Ordered = true;      ws.ReliableSession.InactivityTimeout = new TimeSpan(23, 59, 0);      ws.Security.Message.ClientCredentialType = MessageCredentialType.Windows;      ws.Security.Message.NegotiateServiceCredential = true;      ws.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;      return ws;    }    /// <summary>    /// 获取默认TCP绑定    /// </summary>    /// <returns></returns>    public static NetTcpBinding GetNetTcpBinding()    {      NetTcpBinding nettcp = new NetTcpBinding(SecurityMode.None);      nettcp.CloseTimeout = new TimeSpan(0, 5, 0);      nettcp.OpenTimeout = new TimeSpan(0, 5, 0);      nettcp.ReceiveTimeout = new TimeSpan(0, 20, 0);      nettcp.SendTimeout = new TimeSpan(0, 5, 0);      nettcp.TransactionFlow = false;      nettcp.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;      nettcp.MaxBufferPoolSize = 1073741824;      nettcp.MaxBufferSize = 1073741824;      nettcp.MaxReceivedMessageSize = 1073741824;      nettcp.ReaderQuotas.MaxDepth = 6553600;      nettcp.ReaderQuotas.MaxStringContentLength = 2147483647;      nettcp.ReaderQuotas.MaxArrayLength = 6553600;      nettcp.ReaderQuotas.MaxBytesPerRead = 6553600;      nettcp.ReaderQuotas.MaxNameTableCharCount = 6553600;      nettcp.ReliableSession.Ordered = true;      nettcp.ReliableSession.InactivityTimeout = new TimeSpan(23, 59, 0);      nettcp.ReliableSession.Enabled = false;      nettcp.Security.Mode = SecurityMode.None;      nettcp.Security.Message.ClientCredentialType = MessageCredentialType.Windows;      nettcp.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;      return nettcp;    }    /// <summary>    /// 获取默认TCP绑定(双工通信)    /// </summary>    /// <returns></returns>    public static NetTcpBinding GetDuplexBinding()    {      NetTcpBinding nettcp = new NetTcpBinding(SecurityMode.None);      nettcp.CloseTimeout = new TimeSpan(0, 5, 0);      nettcp.OpenTimeout = new TimeSpan(0, 5, 0);      nettcp.ReceiveTimeout = new TimeSpan(0, 20, 0);      nettcp.SendTimeout = new TimeSpan(0, 5, 0);      nettcp.TransactionFlow = false;      nettcp.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;      nettcp.MaxBufferPoolSize = 1073741824;      nettcp.MaxBufferSize = 1073741824;      nettcp.MaxReceivedMessageSize = 1073741824;      nettcp.ReliableSession.Ordered = true;      nettcp.ReliableSession.InactivityTimeout = new TimeSpan(23, 59, 0);      nettcp.ReliableSession.Enabled = false;      nettcp.Security.Mode = SecurityMode.None;      nettcp.Security.Message.ClientCredentialType = MessageCredentialType.Windows;      nettcp.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;      return nettcp;    }    /// <summary>    /// 获取默认命名管道绑定    /// </summary>    /// <returns></returns>    public static NetNamedPipeBinding GetNetPipeBinding()    {      //NetNamedPipeBinding      NetNamedPipeBinding netnamepipe = new NetNamedPipeBinding();      netnamepipe.CloseTimeout = new TimeSpan(0, 5, 0);      netnamepipe.OpenTimeout = new TimeSpan(0, 5, 0);      netnamepipe.ReceiveTimeout = new TimeSpan(0, 20, 0);      netnamepipe.SendTimeout = new TimeSpan(0, 5, 0);      netnamepipe.TransactionFlow = false;      netnamepipe.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;      netnamepipe.MaxBufferPoolSize = 1073741824;      netnamepipe.MaxBufferSize = 1073741824;      netnamepipe.MaxReceivedMessageSize = 1073741824;      return netnamepipe;    }    /// <summary>    /// 内部元数据行为    /// 配置文件:<serviceMetadata httpGetEnabled="true" />    /// </summary>    /// <returns></returns>    public static ServiceMetadataBehavior GetWsMetaBehavior()    {      ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();      // 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点      behavior.HttpGetEnabled = true;      // behavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;      return behavior;    }    /// <summary>    /// 内部调试行为    /// 配置文件:<serviceDebug includeExceptionDetailInFaults="true" />    /// </summary>    /// <returns></returns>    public static ServiceDebugBehavior GetserviceDebugBehavior()    {      ServiceDebugBehavior behavior = new ServiceDebugBehavior();      // 要接收故障异常详细信息以进行调试,请将下值设置为 true。在部署前设置为 false 以避免泄漏异常信息      behavior.IncludeExceptionDetailInFaults = true;      return behavior;    }    /// <summary>    /// 内部流作用行为    /// 配置文件:<serviceThrottling maxConcurrentCalls ="100" maxConcurrentSessions ="100" maxConcurrentInstances ="100"/>    /// </summary>    /// <returns></returns>    public static ServiceThrottlingBehavior GetserviceThrottlingBehavior()    {      ServiceThrottlingBehavior behavior = new ServiceThrottlingBehavior();      behavior.MaxConcurrentCalls = 100;      behavior.MaxConcurrentSessions = 100;      behavior.MaxConcurrentInstances = 100;      return behavior;    }    /// <summary>    /// 内部系列化参数设置    /// 配置文件:<dataContractSerializer maxItemsInObjectGraph="2147483647" />    /// </summary>    /// <returns></returns>    public static void SetdataContractSerializer(ServiceHost hostTemp)    {      Type t = hostTemp.GetType();      object obj = t.Assembly.CreateInstance("System.ServiceModel.Dispatcher.DataContractSerializerServiceBehavior",        true, BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { false, Int32.MaxValue }, null, null);      IServiceBehavior myServiceBehavior = obj as IServiceBehavior;      if (myServiceBehavior != null)      {        hostTemp.Description.Behaviors.Add(myServiceBehavior);      }    }  }}

WcfConfigHelper

 3.接口说明

Calculation:请求计费

PayNotify:停车费支付通知

CarUpdate:车辆信息同步

4.Windos服务

由于windos服务比较稳定,在这里我们把他做成windos服务,一直在服务器上面运行。其中核心代码如下:

  public partial class Service1 : ServiceBase  {    static ILog log = log4net.LogManager.GetLogger("MidServerLog");    private System.Timers.Timer timerDelay;    protected override void OnStart(string[] args)    {      try      {        timerDelay = new System.Timers.Timer(3000);        timerDelay.Elapsed += new System.Timers.ElapsedEventHandler(timerDelay_Elapsed);        timerDelay.Start();      }      catch (Exception ex)      {        log.Debug("OnStart:" + ex.ToString());      }    }    void timerDelay_Elapsed(object sender, System.Timers.ElapsedEventArgs e)    {      timerDelay.Enabled = false;      timerDelay.Close();      DoWork();    }    public static AsynchronousSocketListener socketListener = null;    private static ServiceHost m_ServiceHost = null;    public static bool ServiceRuning    {      get      {        if (m_ServiceHost == null)          return false;        else if (m_ServiceHost.State != CommunicationState.Opened)          return false;        else          return true;      }    }    public Service1()    {      InitializeComponent();    }    private static void DoWork()    {      socketListener = new AsynchronousSocketListener();      Thread thread = new Thread(socketListener.StartListening);      thread.Start();      try      {        string ServiceUrl = string.Empty;        ServiceUrl = System.Configuration.ConfigurationManager.AppSettings["wcf"].ToString();        //服务地址        Uri baseAddress = new Uri(ServiceUrl);        m_ServiceHost = new ServiceHost(typeof(CalculationService), new Uri[] { baseAddress });        m_ServiceHost.AddServiceEndpoint(typeof(ICalculationService), 
WcfConfigHelper.GetBasicHttpBinding(EnumHttpBindingType.Normal),
""); if (m_ServiceHost.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null) { System.ServiceModel.Description.ServiceMetadataBehavior svcMetaBehavior =
new System.ServiceModel.Description.ServiceMetadataBehavior();
svcMetaBehavior.HttpGetEnabled = true; svcMetaBehavior.HttpGetUrl = new Uri(ServiceUrl + "/Mex"); m_ServiceHost.Description.Behaviors.Add(svcMetaBehavior); } m_ServiceHost.Opened += new EventHandler(delegate(object obj, EventArgs e) { log.Debug("DoWork:" + "服务已经启动!"); }); m_ServiceHost.Open(); } catch (Exception e) { log.Debug("WCF服务启动失败:" + e.Message); } } static void HostFaulted(object sender, EventArgs e) { log.Error("通信机WCF遇到问题:" + e.ToString()); } protected override void OnStop() { AsynchronousSocketListener.StopListening(); if ((m_ServiceHost != null) && (m_ServiceHost.State != CommunicationState.Closed)) { m_ServiceHost.Close(); m_ServiceHost = null; } } }

5.接收物业公司客户端发送的数据

  public class Bussiness  {    static ILog log = log4net.LogManager.GetLogger("MidServerLog");    public static Dictionary<string, orders> dicOrder = new Dictionary<string, orders>();    public static Dictionary<string, ParkMsg> dicParkMsg = new Dictionary<string, ParkMsg>();    public static void ProcessMethod(string content)    {      JObject jo = (JObject)JsonConvert.DeserializeObject(content);      string method = jo["method"].ToString();      string param = content;      switch (method)      {        case "calculation":          CallBackCalculation(jo);          break;        case "payNotify":          CallBackPayNotify(jo);          break;        case "carUpdate":          CallBackCarUpdate(jo);          break;        default:          break;      }    }    /// <summary>    /// 请求计费    /// </summary>    private static void CallBackCalculation(JObject jo)    {      log.Debug("CallBackCalculation:" + "调用");      log.Debug("CallBackCalculation:" + "Jo的值:"+jo);      double fee = double.Parse(jo["fee"].ToString());      double actualFee = double.Parse(jo["actualFee"].ToString());      string orderId = jo["orderid"].ToString();      if (dicOrder.ContainsKey(orderId))      {        orders model = model = dicOrder[orderId];        if (model != null)        {          model.total_price = (decimal)fee;          model.payablefee = (decimal)actualFee;           model.updateTime = DateTime.Now;          model.end_time = jo["time"].ToString();          log.Debug("CallBackCalculation:" + "调用结果,更新成功");        }      }    }    /// <summary>    /// 支付通知回调函数    /// </summary>    private static void CallBackPayNotify(JObject jo)    {      log.Debug("CallBackPayNotify:" + "调用");      log.Debug("CallBackPayNotify:" + "Jo的值:" + jo);      string code = jo["code"].ToString();      string orderId = jo["orderid"].ToString();      if (dicOrder.ContainsKey(orderId))      {        orders model = model = dicOrder[orderId];        if (model != null)        {          model.updateTime = DateTime.Now;          log.Debug("CallBackCalculation:" + "调用结果,更新成功");        }      }       log.Debug("CallBackCalculation:" + "调用结果,更新成功");    }    /// <summary>    /// 车辆信息同步    /// </summary>    private static void CallBackCarUpdate(JObject jo)    {      log.Debug("CallBackCarUpdate:" + "调用");      log.Debug("CallBackCarUpdate:" + "Jo的值:" + jo);      string code = jo["code"].ToString();      string parkId = jo["parkId"].ToString();      if (dicParkMsg.ContainsKey(parkId))      {        ParkMsg model = model = dicParkMsg[parkId];        if (model != null)        {          model.UpdateTime = DateTime.Now;          log.Debug("CallBackCarUpdate:" + "调用结果,更新成功");        }      }    }
}

 6.Socket核心代码

public class AsynchronousSocketListener
{

    static ILog log = log4net.LogManager.GetLogger("MidServerLog");    private Dictionary<string, Socket> clientList = new Dictionary<string, Socket>();    public static ManualResetEvent allDone = new ManualResetEvent(false);    private static Socket listener;    private int _port = 10000;    public static void StopListening()    {      listener.Close();    }
public int Port { set { _port = value; } }
public bool IsStart { get { return listener.IsBound; } }

    public void StartListening()    {      byte[] bytes = new Byte[1024];      string serverIP = System.Configuration.ConfigurationManager.AppSettings["ServerIP"];      IPAddress ipAddress = IPAddress.Parse(serverIP);      IPEndPoint localEndPoint = new IPEndPoint(ipAddress, _port);      listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);      listener.Bind(localEndPoint);      listener.Listen(100);      while (true)      {        allDone.Reset();        listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);        log.Info("启动监听!");        allDone.WaitOne();      }    }

StartListening()
    public Socket GetParkSocket(int parkId)    {      lock (clientList)      {        foreach (KeyValuePair<string, Socket> kvp in clientList)        {          if (kvp.Key.StartsWith(parkId.ToString() + "-"))          {            return kvp.Value;          }        }        return null;      }     }

    private void AcceptCallback(IAsyncResult ar)    {      allDone.Set();      Socket listener = (Socket)ar.AsyncState;      Socket handler = listener.EndAccept(ar);      StateObject state = new StateObject();      state.workSocket = handler;      try      {        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,          new AsyncCallback(ReadCallback), state);      }      catch(Exception ex)      {        log.Debug("AcceptCallback:" + ex.ToString());      }    }

AcceptCallback(IAsyncResult ar)
private void ReadCallback(IAsyncResult ar)    {      StateObject state = (StateObject)ar.AsyncState;      Socket handler = state.workSocket;      int bytesRead = 0;      if (handler.Connected)      {        try        {          bytesRead = handler.EndReceive(ar);        }        catch (Exception ex)        {          log.Debug("ReadCallback:"+ex.ToString());          handler.Close();        }        if (bytesRead > 0)        {          String content = String.Empty;          content = Encoding.UTF8.GetString(state.buffer, 0, bytesRead);          if (content.Length > 0)          {            ProcessCmd(handler, content);            try            {              handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,                new AsyncCallback(ReadCallback), state);            }            catch (Exception ex)            {              log.Debug("ReadCallback:" + ex.ToString());            }          }          else          {            try            {              handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,                new AsyncCallback(ReadCallback), state);            }            catch (Exception ex)            {              log.Debug("ReadCallback:" + ex.ToString());            }          }        }      }    }

ReadCallback(IAsyncResult ar)
    private void ProcessCmd(Socket handler, String content)    {      content = content.Replace("\r", "").Replace("\n", "").Replace("<EOF>", "");      JObject jo = null;      try      {        jo = (JObject)JsonConvert.DeserializeObject(content);      }      catch (Exception ex)      {        log.Debug("ProcessCmd:" + ex.ToString());      }      if (jo != null)      {        try        {          string method = jo["method"].ToString();          if (method.ToLower() == "login")          {            JsonLogin jsonLogin = JsonConvert.DeserializeObject<JsonLogin>(content);            Login(jsonLogin, handler);          }          else          {            Bussiness.ProcessMethod(content);          }        }        catch (Exception ex)        {          log.Debug("ProcessCmd:" + ex.ToString());        }      }    }

ProcessCmd(Socket handler, String content)
public void Send(string key, string data)    {      if (clientList.ContainsKey(key))      {        Socket handler = clientList[key];        if (handler != null)        {          try          {            Send(handler, data);          }          catch (Exception ex)          {            log.Debug("Send:" + ex.ToString());          }        }      }    }

Send(string key, string data)
    private static void Send(Socket handler, String data)    {      if (handler != null)      {        byte[] byteData = Encoding.UTF8.GetBytes(data);        try        {          handler.BeginSend(byteData, 0, byteData.Length, 0,            new AsyncCallback(SendCallback), handler);        }        catch (Exception ex)        {          log.Debug("Send:" + ex.ToString());        }      }    }

Send(Socket handler, String data)
    private static void SendCallback(IAsyncResult ar)    {      Socket handler = (Socket)ar.AsyncState;      int bytesSent = handler.EndSend(ar);    }

SendCallback(IAsyncResult ar)
    private void Login(JsonLogin jsonLogin, Socket handler)    {      lock (clientList)      {        if (clientList.ContainsKey(jsonLogin.param.parkId.ToString() + "-" + jsonLogin.param.clientId))        {          clientList.Remove(jsonLogin.param.parkId.ToString() + "-" + jsonLogin.param.clientId);        }        else        {          log.Debug("Login:" + jsonLogin.param.parkId.ToString() + "-" + jsonLogin.param.clientId);        }        try        {          clientList.Add(jsonLogin.param.parkId.ToString() + "-" + jsonLogin.param.clientId, handler);          if (Login(jsonLogin))          {            Send(handler, "{\"method\": \"login\", \"code\": 0,\"msg\": \"登录成功!\"}");            log.Debug("登陆成功:" + jsonLogin.param.parkId.ToString());          }        }        catch (Exception ex)        {          log.Debug("Login:" + ex.ToString());        }      }    }

    private bool Login(JsonLogin jsonLogin)    {      return true;    }

Login(JsonLogin jsonLogin)

用户通过移动端支付的时候,云平台要调用WCF请求支付的方法来请求停车场获取用户停车计费信息。

    internal string Calculation(int parkId, string orderid)    {      lock (Bussiness.dicOrder)      {        log.Debug("Calculation:" + "调用");        string str = "{\"method\":\"calculation\",\"param\":{\"orderid\":\"" + orderid + "\"}}";        orders model = new orders();        model.orderid = orderid;        model.parentid = parkId.ToString();        if (Bussiness.dicOrder.ContainsKey(orderid))        {          Bussiness.dicOrder.Remove(orderid);        }        Bussiness.dicOrder.Add(orderid, model);         AsynchronousSocketListener.Send(GetParkSocket(parkId), str);//通过socket发送数据给物业公司的客户端        log.Info("Send:发送数据:" + str);        for (int i = 0; i <= 12; i++)        {          if (Bussiness.dicOrder.ContainsKey(orderid))          {             orders model2 = Bussiness.dicOrder[orderid];            if (model2 != null && model2.updateTime != null)//此处通过轮询检查是否收到停车场发送过来的json数据            {              string strFee = model2.total_price.ToString() == "" ? "0" : model2.total_price.ToString();              string strpayablefee = model2.payablefee.ToString() == "" ? "0" : model2.payablefee.ToString();              string end_time = model2.end_time;              string result = "{\"fee\": " + strFee + ",\"actualFee\": " + strpayablefee + ",\"end_time\":\"" + end_time + "\"}";              if (Bussiness.dicOrder.ContainsKey(orderid))              {                Bussiness.dicOrder.Remove(orderid);              }              log.Debug("来自" + parkId .ToString()+ "的Calculation:" + "调用结果:" + result);              return result;            }          }           Thread.Sleep(500);        }        if (Bussiness.dicOrder.ContainsKey(orderid))        {          Bussiness.dicOrder.Remove(orderid);        }        log.Debug("来自" + parkId.ToString() + "的Calculation:" + "调用结果:{\"code\":40001,\"msg\":\" token无效或过期\"}");        return "{\"code\":40001,\"msg\":\" token无效或过期\"}";      }    }

用户通过移动端APP或者微信公众号支付成功后,云平台通过调用WCF支付通知方法来通知停车场此用户已经支付成功。
    /// <summary>    /// 支付通知    /// </summary>    /// <returns></returns>    internal void PayNotify(int parkId, string orderid, string fee, string paytime, string actualFee)    {      lock (Bussiness.dicOrder)      {        log.Debug("PayNotify:" + "调用");        string str = "{\"method\":\"payNotify\",\"param\":{\"fee\": \"" + fee + "\",\"paytime\": \"" + paytime + "\",\"actualFee\":\"" + actualFee + "\",\"orderid\": \"" + orderid + "\"}}";        orders model = new orders();        model.orderid = orderid;        model.parentid = parkId.ToString();        if (Bussiness.dicOrder.ContainsKey(orderid))        {          Bussiness.dicOrder.Remove(orderid);        }        Bussiness.dicOrder.Add(orderid, model);        AsynchronousSocketListener.Send(GetParkSocket(parkId), str);        log.Info("Send:发送数据:" + str);           for (int i = 0; i <= 12; i++)        {          if (Bussiness.dicOrder.ContainsKey(orderid))          {            orders model2 = Bussiness.dicOrder[orderid];            if (model2 != null && model2.updateTime != null)            {              string result = "{\"msg\":\"测试支付通知\"}";              if (Bussiness.dicOrder.ContainsKey(orderid))              {                Bussiness.dicOrder.Remove(orderid);              }              log.Debug("来自" + parkId.ToString() + "的PayNotify:" + "调用结果有返回测试成功:" + result);            }          }          Thread.Sleep(500);        }        #endregion        if (Bussiness.dicOrder.ContainsKey(orderid))        {          Bussiness.dicOrder.Remove(orderid);        }        log.Debug("来自" + parkId.ToString() + "的PayNotify:" + "调用结果:无返回测试成功" + str);      }    } 

 管理员通过操作云平台后台管理系统后,需要调用WCF的车辆信息同步方法通知停车场同步消息。

    /// <summary>    /// 车辆信息同步    /// </summary>    /// <returns></returns>    internal string CarUpdate(int parkId,string carNo, string carTypeId, string startTime, string outTime, string recordTye,string key)    {      lock (Bussiness.dicParkMsg)      {        log.Debug("CarUpdate:" + "调用");        string str = "{\"method\":\"CarUpdate\",\"param\":{\"parkId\":\"" + parkId + "\",\"carNo\":\"" + carNo + "\",\"carTypeId\":\"" + carTypeId + "\",\"startTime\":\"" + startTime + "\",\"outTime\":\"" + outTime + "\",\"recordType\":\"" + recordTye + "\",\"key\":\"" + key + "\"}}";        ParkMsg model = new ParkMsg();        model.ParkId = parkId.ToString();        if (Bussiness.dicParkMsg.ContainsKey(parkId.ToString()))        {          Bussiness.dicParkMsg.Remove(parkId.ToString());        }        Bussiness.dicParkMsg.Add(parkId.ToString(), model);        AsynchronousSocketListener.Send(GetParkSocket(parkId), str);        log.Info("Send:发送数据:" + str);        for (int i = 0; i <= 12; i++)        {          if (Bussiness.dicOrder.ContainsKey(parkId.ToString()))          {            ParkMsg model2 = Bussiness.dicParkMsg[parkId.ToString()];            if (model2 != null && model2.UpdateTime != null)            {              string result = "{\"code\":0,\"msg\":\"车辆信息同步成功\"}";              if (Bussiness.dicOrder.ContainsKey(parkId.ToString()))              {                Bussiness.dicOrder.Remove(parkId.ToString());              }              log.Debug("来自" + parkId.ToString() + "的CarUpdate:" + "调用结果:" + result);              return result;            }          }          Thread.Sleep(500);        }        if (Bussiness.dicParkMsg.ContainsKey(parkId.ToString()))        {          Bussiness.dicParkMsg.Remove(parkId.ToString());        }        log.Debug("来自" + parkId.ToString() + "的CarUpdate:" + "调用结果:{\"code\":40001,\"msg\":\" token无效或过期\"}");        return "{\"code\":40001,\"msg\":\" token无效或过期\"}";      }    } 

}


 整个系统中,最重要的是Socket,用户请求付费的时候,手机上面的APP或者微信公众号会调用云平台的请求计费接口,这个时候,云平台也不知道客户的停车费用到底是多少,这个时候,云平台就需要请求我们的Scoket,通过请求WCF暴露出来的方法,来获取客户的停车费用信息,每个停车场的计费信息不一样,每个停车场有一个固定的表示身份的ParkId,Socket会发送消息给停车场,这个请求的整个过程中,停车场和Socket服务端一致保持着连接,这个时候如果Socket服务端收到停车场的计费信息,就会发送给云平台,从而完成整个过程,其他两个接口方法原理也是类似.

公司的项目就不方便上传源码,如果你觉得本文不错,帮我推荐一下,感谢。