当前位置: 代码迷 >> .NET相关 >> WCF+Socket实现Java和.Net智能停车系统交互
  详细解决方案

WCF+Socket实现Java和.Net智能停车系统交互

热度:653   发布时间:2016-04-24 02:46:07.0
【原创】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.Xml;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服务端收到停车场的计费信息,就会发送给云平台,从而完成整个过程,其他两个接口方法原理也是类似.

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

 

7楼wyd1520
即然你是用byte -gt;String 还有你的包里面有lt;EOFgt;,那你就干脆再加个lt;BOFgt;DATAlt;EOFgt; ,然后在StateObject 加个string Buffer做缓冲区,把所有的Recive过来的Data转成 string,state.Buffer+=Data;,//,while(state.Find()) //查找lt;BOFgt;lt;EOFgt; ,{, string= state.Queue() //出队, CallHandler()//呼叫你的业务。
6楼dark89757
看到ProcessCmd我就笑了,一个粘包都都没有!,Send也有没有线程并发处理!!
Re: 枫伶忆
@dark89757,新手嘛,请教下要如何优化了....
5楼查克拉的觉醒
项目就是不一样,很综合的说..
Re: 枫伶忆
@查克拉的觉醒,学习就需要分享,分享出来了,你要是没做过的你也可以学到一些东西,如果我有什么不足,你也可以给我指出来,这样才能共同进步是吧...感谢支持
4楼技术_菜鸟
不错,顶一下
Re: 枫伶忆
@技术_菜鸟,感谢支持
3楼Figgy
这么厉害,顶一下!
Re: 枫伶忆
@Figgy,感谢支持
2楼敷衍不起
好早啊。
Re: 枫伶忆
@敷衍不起,那像你可以搂着老婆美美的睡大觉,我们这样的穷屌丝,只有起来撸代码,才有机会逆袭女神....
1楼domaom
还不如直接用signalr+Web API,Web API直接返回的就是json或者xml了
Re: 枫伶忆
@domaom,这里不仅仅是要返回json数据就可以了,最只要的是移动端的APP,微信公众号,需要Java云平台提供稳定的接口,而和我们公司合作的停车场很多,目前有20几家吧,每个停车场的收费规则也不一样,停车场A也许停车一分钟1毛钱,停车场B也许是停车一分钟1.2毛钱,如果这样的话,用户在支付的时候,java云平台就需要连接停车场,获取停车费用,在这个过程中,java那边会掉用我们.net这边的WCF, Socket只是起到一个中间转发的作用,Java那边可能有更好的办法,项目比较急的时候,经理就叫我写的个Socket,我能力也是有限,只能写出这个样子,,,signalr+Web API可以实现我这样的需要?要是能够的话,跪求一个demo,再次感谢大神
  相关解决方案