2020年8月13日星期四

CEF+ChromiumWebBrowser+vue+elementUI 前后端交互(注意:有后端非前端主动触发回调前端vue前端)

CEF VUE 前后端交互

项目背景:

  项目技术方案定的是前后端分离,采用framework4.0+vue+elementUI  客户端需要加壳(使用CEF+ChromiumWebBrowser),避免客户端多样,导致环境不支持;

  并且客户端需要调用微软硬件(键盘、语音)接口进行业务操作;

所遇到的场景:

  • 语音

    客户端(前端)需要触发调用;操作系统语音外设播报语音;

  • 键盘

    客户端(前端)需要监听键盘输入按键,并在回车的时候,回调前端js并将键盘输入的字符传给前端方法执行vue实例下指定方法;

代码实现

  • 语音实现

    后台代码:    

 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Configuration; 5 using System.Data; 6 using System.Drawing; 7 using System.Linq; 8 using System.Net; 9 using System.Text; 10 using System.Threading.Tasks; 11 using System.Windows.Forms; 12 using CardReader; 13 using CefSharp; 14 using CefSharp.WinForms; 15 using FormDLL; 16 using Newtonsoft.Json; 17 using RestSharp; 18 namespace CefSharpOfQueue { 19  public partial class FormMain: Form { 20   public ChromiumWebBrowser chromeBrowser; 21   private Type voiceType; 22   private CardReader.CardReader cardReader; 23   private dynamic spVoice; 24   private string token; 25   public Control activeUserControl; 26   private Panel panelContent; 27   public FormMain() { 28     //初始化语音设备 29     this.voiceType = Type.GetTypeFromProgID("SAPI.SpVoice"); 30     this.spVoice = Activator.CreateInstance(this.voiceType); 31     //初始化winform控件 32     InitializeComponent(); 33     this.FormBorderStyle = FormBorderStyle.None; 34     //winform全屏 35     this.WindowState = FormWindowState.Maximized; 36     //初始化chromium 37     InitializeChromium(); 38     // 注册一个formMainProcess;用于前端调用后台 39     chromeBrowser.RegisterJsObject("formMainProcess", new FormMainProcess(chromeBrowser, this)); 40    } 41    //放在初始化winform控件InitializeComponent 方法中 42   private void FormMain_Load(object sender, EventArgs e) { 43    //this.activeUserControl = this.AddControl(new ScanCard(this)); 44    this.cardReader = new CardReader.CardReader(2); 45    this.cardReader.CardRead += delegate(string cardCode) { 46     if(!string.IsNullOrWhiteSpace(cardCode)) { 47      //将获取到的cardCode回传给前端全局变量 48      try { 49       chromeBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("Vue.prototype.$store.state.isShow=true;Vue.prototype.$store.state.queryCode='" + cardCode + "'"); 50      } catch { 51       //或者写日志 52       throw new Exception("error"); 53      } 54     } 55    }; 56   } 57   public void SpeakTxt(string msg) { 58    this.spVoice.speak(msg, 1); 59   } 60   public void InitializeChromium() { 61    // 获取配置文件里的前端服务地址 62    string url = ConfigurationManager.AppSettings["ServiceAddress"]; 63    //创建chrome对象 64    chromeBrowser = new ChromiumWebBrowser(url); 65    // 将chrome对象添加进winform控制器 66    this.Controls.Add(chromeBrowser); 67    chromeBrowser.Dock = DockStyle.Fill; 68    // Allow the use of local resources in the browser 69    BrowserSettings browserSettings = new BrowserSettings(); 70    browserSettings.FileAccessFromFileUrls = CefState.Enabled; 71    browserSettings.UniversalAccessFromFileUrls = CefState.Enabled; 72    browserSettings.WebSecurity = CefState.Enabled; 73    // browserSettings.LegacyJavascriptBindingEnabled = true; 74    chromeBrowser.BrowserSettings = browserSettings; 75    // 网页开始加载时的处理 76    chromeBrowser.FrameLoadStart += (sender, e) => { 77     string script = @"const loading = this.$loading({ 78     lock: true, 79      text: 'Loading', 80      spinner: 'el-icon-loading', 81      background: 'rgba(0, 0, 0, 0.7)' 82    }); 83   setTimeout(() => { 84    loading.close(); 85   }, 2000); 86   "; 87   e.Frame.ExecuteJavaScriptAsync(script); 88  }; 89  // 网页加载完毕时的处理 90  chromeBrowser.FrameLoadEnd += (sender, e) => { 91   string script = "alert('加载完毕!');"; 92   e.Frame.ExecuteJavaScriptAsync(script); 93  }; 94 } 95 } 96 internal class FormMainProcess { 97  private FormMain _instanceMainForm = null; 98  private ChromiumWebBrowser _instanceBrowser = null; 99  public FormMainProcess(ChromiumWebBrowser originalBrowser, FormMain mainForm) {100    _instanceBrowser = originalBrowser;101    _instanceMainForm = mainForm;102   }103   /// <summary>104   /// 播放语音105   /// </summary>106   /// <param name="message"></param>107  public void speakMsg(string message) {108   this._instanceMainForm.Invoke(new Action(delegate {109    this._instanceMainForm.SpeakTxt(message);110   }));111  }112 }113 }

    前端代码:可在vue界面中script中任意一个方法中 使用后端注册了的formMainProcess 对象,调用对应方法。如下:

 

 1 <template> 2 ... 3 </template> 4 <script> 5 ... 6 methods: { 7  testf(){ 8    //呼叫,播报信息 9     formMainProcess.speakMsg(10      '测试语音ABCD'11     );12  }13 }14 </script>    

 

CEF+ChromiumWebBrowser+vue+elementUI 前后端交互(注意:有后端非前端主动触发回调前端vue前端)锦桥纺织网产品的图片和文案打造义乌跨境出口电商发展论坛-Google专场&Linkedin专场2019年独立站攻略NO5:Shopify如何做站内优化?亚马逊想要做得好,四大理论要记牢!物流小知识!教你查询最新出口美国的豁免清单产品广珠城轨新会站在哪里?春节去哪泡温泉好?春节自驾出行,粤东有什么好路线?

没有评论:

发表评论