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

  • A+
所属分类:.NET技术
摘要

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


项目背景:

  项目技术方案定的是前后端分离,采用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>