与推送系统集成

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Threading;
using RepairerDispatch.SynthesisServer;
using System.Media;
using System.IO;
using System.Diagnostics;
using System.Collections.Concurrent;
using System.Text.RegularExpressions;
namespace RepairerDispatch
{
    public partial class frmMain : Form
    {

        private Counter _Counter = new Counter();
        private PushClient _PushClient = null;
        protected SynchronizationContext SyncContext { get; set; }
        public ConcurrentQueue<NotifyInfo> NotifyQueue = new ConcurrentQueue<NotifyInfo>();
        public bool HandleEnable = false;
        public int MaxSendCount = int.Parse(ConfigurationManager.AppSettings["RepeatCount"]);
        public int RepeatInterval = int.Parse(ConfigurationManager.AppSettings["RepeatInterval"]);
        public bool MockMode = bool.Parse(ConfigurationManager.AppSettings["Mock"]);
        public bool Quietness = bool.Parse(ConfigurationManager.AppSettings["Quietness"]);
        public static int FirstSendDelay = int.Parse(ConfigurationManager.AppSettings["Delay"]);
        public frmMain()
        {
            InitializeComponent();
            SyncContext = SynchronizationContext.Current;
            this.MaximizeBox = false;

            this.StartPosition = FormStartPosition.CenterScreen;
     

            #region 配置推送
            _PushClient = new PushClient();

            _PushClient.UserId = ConfigurationManager.AppSettings["UserId"];
            _PushClient.OnPushReceived += this.HandleReceivePush;
            _PushClient.Start();
            #endregion
            #region 启动消息处理队列
            HandleEnable = true;
            ThreadPool.QueueUserWorkItem(o => { HandleNotifyQueue(); }, null);
            #endregion
            #region 统计信息
            var timer = new System.Windows.Forms.Timer();
            timer.Interval = 100;
            timer.Tick += (s, e) => 
            {
                try
                {
                    lbl1.Text = string.Format("{0}/{1}/{2}", _Counter.Received, _Counter.SendCount, _Counter.CancelCount);
                    lbl2.Text = string.Format("{0}/{1}", _Counter.SynthesisCount, _Counter.SynthesisedCount);
                    lbl3.Text = _Counter.QueueLength.ToString();
                }
                catch { }
            };
            timer.Start();


            #endregion

        }
        protected override void OnClosing(CancelEventArgs e)
        {
            if (MessageBox.Show("关闭窗体后将无法收到提示,确定关闭吗?", "警告!", MessageBoxButtons.YesNo,MessageBoxIcon.Warning) != System.Windows.Forms.DialogResult.Yes)
            {
                e.Cancel = true;
            }
            base.OnClosing(e);
        }
        protected override void OnClosed(EventArgs e)
        {

            try
            {
                HandleEnable = false;
                if (_PushClient != null)
                {
                    _PushClient.OnPushReceived -= this.HandleReceivePush;
                    _PushClient.Dispose();
                }
            }
            finally { }
            base.OnClosed(e);
        }
        #region 处理推送消息
        private void HandleReceivePush(string msg)
        {

            if (this.InvokeRequired)
            {
           
                SyncContext.Post((ox) => { HandleReceivePush(msg); }, null);
            }
            else
            {
                try
                {
                    Interlocked.Increment(ref _Counter.Received);
                    WriteInfo(msg.Replace(Environment.NewLine,""));
                    var info=  NotifyInfo.Create(msg);
                    if (info == null) return;
                    if (info.VoiceReady)
                    {
                        NotifyQueue.Enqueue(info);
                        _Counter.QueueLength ++;
                    }
                    else
                    {
                        SynthesisVoice(info);
                    }
                }
                catch (Exception ex)
                {
                    WriteInfo(ex.Message);
                }
            }
        }

        /// <summary>
        /// 处理队列里的消息
        /// </summary>
        private void HandleNotifyQueue()
        {
            try
            {

                while (HandleEnable)
                {
                    //WriteInfo("执行通知队列处理" + DateTime.Now);
                    var info=new NotifyInfo();
                    _Counter.QueueLength = NotifyQueue.Count;
                    if (NotifyQueue.TryDequeue(out info))
                    {
                        //符合播放条件
                        if (info.SendTime <= DateTime.Now )
                        {
                            #region 播放
                            using (var ctx = new JL_MFGEntities())
                            {
                                var it = ctx.L_Conn_CallRepair.FirstOrDefault(ent => ent.ID == info.MsgId);
                                if (it == null || it.TicketStatus != "呼叫" || !string.IsNullOrWhiteSpace(it.TakeOverEmpId))
                                {
                                    if (!MockMode)//模拟模式
                                    {
                                        Interlocked.Increment(ref _Counter.CancelCount);
                                        continue;
                                    }

                                }

                            }
                            Interlocked.Increment(ref _Counter.SendCount);
                            if (!Quietness)
                            {
                                using (SoundPlayer soundPlayer = new SoundPlayer(info.WavFile))
                                {
                                    soundPlayer.Stop();
                                    soundPlayer.PlaySync();
                                    Thread.Sleep(1000 * 6);
                                }
                            }
                            info.SendCount++;
                            info.SendTime = info.SendTime.AddMinutes(RepeatInterval);
                            if (info.SendCount < MaxSendCount)
                            {
                                NotifyQueue.Enqueue(info);
                            }
                            #endregion

                        }
                        else
                        {
                            NotifyQueue.Enqueue(info);
                        }
                    }
                    _Counter.QueueLength = NotifyQueue.Count;
                    if (NotifyQueue.Count <= 0)
                    {
                        Thread.Sleep(450);
                    }

                    Thread.Sleep(50);
                }
            }
            catch (Exception ex)
            {
                WriteInfo("错误" + ex.Message);
            }
            finally
            {
                if (HandleEnable)
                {

                    ThreadPool.QueueUserWorkItem(o => { HandleNotifyQueue(); }, null);
                }
            }
        }
        private void SynthesisVoice(NotifyInfo info)
        {
         
                try
                {
                    #region 合成音频并排队
                    using (var svr = new SynthesisService())
                    {
                        WriteInfo(DateTime.Now + ":发起音频合成..." );
                        Interlocked.Increment(ref _Counter.SynthesisCount);
                        svr.Timeout = 1000 * 360;
                        svr.GetVoiceCompleted += (s, e) =>
                        {
                            try
                            {
                                if (_Counter.SynthesisCount > 0)Interlocked.Decrement(ref _Counter.SynthesisCount);
                    

                                if (e.Error != null) throw e.Error;
                                if (e.Cancelled) return;
                                if (e.Result.Code != 0) throw new Exception(e.Result.Msg);
                                var filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VCache/" + info.Postion + ".wav");
                                if(!Directory.Exists(Path.GetDirectoryName( filename)))
                                {
                                    Directory.CreateDirectory(Path.GetDirectoryName(filename));
                                }
                                File.WriteAllBytes(filename, e.Result.Data);
                                info.VoiceReady = true;
                                NotifyQueue.Enqueue(info);
                                Interlocked.Increment(ref _Counter.SynthesisedCount);
                                _Counter.QueueLength ++;
                                WriteInfo(DateTime.Now +":完成音频合成");
                            }
                            catch (Exception ex)
                            {
                                WriteInfo(ex.Message);
                            }


                        };
                        svr.GetVoiceAsync(info.Msg, info);


                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    WriteInfo(ex.Message);
                }
         
        }


        
        #endregion

        private void btnTest_Click(object sender, EventArgs e)
        {
            try
            {
                btnTest.Enabled = false;

                TestOnlineSynthesis();

                #region 保持3秒
                for (int i = 0; i < 30; i++)
                {
                    Thread.Sleep(100);
                    Application.DoEvents();
                }
                #endregion

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                btnTest.Enabled = true;
            }
        }

        private  void TestOnlineSynthesis()
        {
            Action act = () =>
            {
                try
                {
                    #region 在线合成测试

                    Stopwatch sw = new Stopwatch();
                    WriteInfo(DateTime.Now +":发起在线合成测试...");
                    Interlocked.Increment(ref _Counter.SynthesisCount);
                    sw.Start();
                    var svr = new SynthesisService();
                    svr.Timeout = 1000 * 360;
                    var msg = ConfigurationManager.AppSettings["TestText"];
                    var response = svr.GetVoice(msg);
                    //更新计数器
                    if (_Counter.SynthesisCount > 0) Interlocked.Decrement(ref _Counter.SynthesisCount);
                    if (response.Code != 0) throw new Exception(response.Msg);
                    Interlocked.Increment(ref _Counter.SynthesisedCount);
                    using (MemoryStream ms = new MemoryStream(response.Data))
                    {
                        using (SoundPlayer soundPlayer = new SoundPlayer(ms))
                        {
                            soundPlayer.Stop();
                            soundPlayer.Play();

                        }
                    }
                    sw.Stop();
                    
                    WriteInfo(string.Format("{0}:完成在线合成测试,用时{1}毫秒",DateTime.Now,sw.ElapsedMilliseconds));
                    #endregion
                }
                catch (Exception ex)
                {
                    WriteInfo(ex.Message);
                }
            };
            var ar = act.BeginInvoke(null, null);
        }
        private void  WriteInfo(string msg)
        {

            if (InvokeRequired)
            {
                SyncContext.Post(o =>
                {
                    WriteInfo(msg);
                }, null);
            }
            else
            {
                lblTips.Text = msg;
                Console.WriteLine(msg);
            }
          

        }
        public class NotifyInfo
        {
            public long MsgId { get; set; }
            public String Postion { get; set; }
            public String Msg { get; set; }
            public String WavFile { get; set; }
            public DateTime AddTime { get; set; }
            public DateTime SendTime { get; set; }
            public int SendCount { get; set; }
            public bool VoiceReady { get; set; }
            public String EmpName { get; set; }
            public int EmpId { get; set; }
            public String Memo { get; set; }
            public String MachineType { get; set; }
            #region 机台编号对应表
            public static Dictionary<String, String> MachineTypeDic =
                new Dictionary<string, string>()
        {
                {"ZD","自动机"},
                {"YJ","压接"},
                {"ZJ","中间压接"},
                {"DJ","冲床"},
                {"XL","电脑剥线机"},
                {"QD","扩孔机"},
                {"JC","绞缠线"},
                {"BJ","包胶机"},
                {"RS","热缩机"},
                {"YT","一体机"},
                {"SC","超声波"}

        };
            #endregion
            public NotifyInfo()
            {
                AddTime = DateTime.Now;
                SendCount = 0;
                WavFile = "";
                VoiceReady = false;
                SendTime = DateTime.Now;
            }
            
            public static NotifyInfo Create(String msg)
            {
                var info = new NotifyInfo();
                var MsgTemp = ConfigurationManager.AppSettings["MsgTemp"];
                if (msg.IndexOf("呼叫机修通知") < 0) return null;
                //呼叫机修通知:($RecId$)\r\n机台:$Position$\r\n员工:$EmpName$($EmpId$)\r\n备注:$Memo$
                //呼叫机修通知:(5168)  机台:ZD062  员工:杜多婷(170062)  备注:
                var m = Regex.Match(msg, @"^呼叫机修通知:(.*?)机台:(.*?)员工:(.*?)备注:(.*?)$",  RegexOptions.Singleline| RegexOptions.IgnoreCase);
                if(!m.Success)return null;
                info.AddTime = DateTime.Now;
                info.SendTime = DateTime.Now.AddMinutes( frmMain.FirstSendDelay);
                info.MsgId =long.Parse( m.Groups[1].Value.Replace("(", "").Replace(")",""));
                info.Postion = m.Groups[2].Value.Trim().ToUpper();
                //员工与工号
                var empStr=m.Groups[3].Value;
                var index=empStr.IndexOf("(");
                info.EmpName = empStr.Substring(0, index);
                var endIndex=empStr.IndexOf(")");
                info.EmpId= int.Parse(empStr.Substring(index+1, endIndex-index-1));
                info.Memo = m.Groups[4].Value.Trim();
                
                var m2 = Regex.Match(info.Postion, @"([a-zA-Z]*)\d*", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (!m2.Success) return null;
                info.MachineType = m2.Groups[1].Value.Trim();
                var mNum = info.Postion.Replace(info.MachineType, "").TrimStart("0".ToCharArray()).Trim();
                info.Msg =MsgTemp.Replace("$工序$",  MachineTypeDic[info.MachineType]).Replace("$编号$",info.Postion).Replace("$数字$",mNum);

                var filename= Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VCache/" + info.Postion + ".wav");
                info.WavFile = filename;
                info.VoiceReady=File.Exists(filename);
    
                return info;
            }
        }
        public class Counter
        {
            public int SynthesisCount = 0; //正在合成数
            public int SynthesisedCount = 0; //已合成数
            public int Received = 0;
            public int SendCount = 0;
            public int CancelCount = 0;
            public int QueueLength = 0;
        }
    }
}
View Code

相关文章: