CEF+ChromiumWebBrowser+vue+elementUI 先後端交互(注意:有後端非前端主動觸發回調前端vue前端)

項目背景:

  項目技術方案定的是先後端分離,採用framework4.0+vue+elementUI  客戶端須要加殼(使用CEF+ChromiumWebBrowser),避免客戶端多樣,致使環境不支持;前端

  而且客戶端須要調用微軟硬件(鍵盤、語音)接口進行業務操做;vue

所遇到的場景:

  • 語音

    客戶端(前端)須要觸發調用;操做系統語音外設播報語音;chrome

  • 鍵盤

    客戶端(前端)須要監聽鍵盤輸入按鍵,並在回車的時候,回調前端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>                
相關文章
相關標籤/搜索