electron教程(二): http服務器, ws服務器, 子進程管理

個人electron教程系列

electron教程(一): electron的安裝和項目的建立javascript

electron教程(番外篇一): 開發環境及插件, VSCode調試, ESLint + Google JavaScript Style Guide代碼規範html

electron教程(番外篇二): 使用TypeScript版本的electron, VSCode調試TypeScript, TS版本的ESLint前端

electron教程(二): http服務器, ws服務器, 子進程管理java

electron教程(三): 使用ffi-napi引入C++的dllnode

electron教程(四): 使用electron-builder或electron-packager將項目打包爲可執行桌面程序(.exe)jquery

 

引言

 

此次, 咱們一塊兒經過幾個例子, 進一步瞭解node.js+electron.web

 

三個例子:

 

  1.  搭建一個http服務器, 經過web對服務器進行訪問
  2.  搭建一個ws服務器, 經過web向服務器發送消息
  3.  進程管理, 打開/關閉一個外部進程chrome

 

例子1: 一個http服務器

 

1. 部署node.js+electron環境

按步驟完成electron教程(一): electron的安裝和項目的建立所介紹的內容.npm

 

2. 安裝http-server

確保你的cmd工做目錄爲項目根目錄.後端

執行指令:

yarn add http-server --save

 

3. 在main.js中添加http服務器

在main.js的最下方, 添加以下代碼:

// http-server
const httpServer = require('http-server');

httpServer.createServer().listen(8080);

在這段代碼中:

咱們建立了一個httpServer對象

const httpServer = require('http-server');

這個對象是經過http-server模塊建立出來的.

使用httpServer對象, 建立一個http服務器, 而且監聽了8080端口

服務器啓動後, 用戶就能夠經過瀏覽器來訪問咱們的服務器了.

 

4. 啓動程序!

執行指令:

npm start

在本身的瀏覽器中,訪問http://localhost:8080/index.html,就會獲得本地的index.html文件

(這是chrome瀏覽器打開的效果)

 

例子2: 一個ws服務器

 

1. 部署node.js+electron環境

node.js+electron教程(一): 安裝nodejs和electron

 

2. 安裝ws

確保你的cmd工做目錄爲項目根目錄.
執行指令:

yarn add ws --save

 

3. 在main.js中添加ws服務器

在main.js的最下方, 添加以下代碼:

// ws-服務器
const WebSocketServer = require('ws').Server;
wss = new WebSocketServer({port: 12122});
wss.on('connection', (ws) => {
  // 有客戶端鏈接時, 打印一條日誌
  console.log('client connected');
  // 而且建立'message'監聽
  ws.on('message', (message) => {
    // 直接將消息打印出來
    console.log(message);
  });
});

在這段代碼中:

咱們建立了一個WebSocketServer對象

const WebSocketServer = require('ws').Server;

這個對象是經過ws模塊建立出來的.

使用WebSocketServer對象, 建立一個ws服務器叫作wss對象, 而且監聽了12122端口

爲wss對象的兩個事件分別綁定了回調:

connection事件, 有客戶端鏈接時, 打印一條日誌.

message事件, 直接將消息打印出來.

 

4. 在index.html中引入jquery

jquery官網下載jquery庫, 將jquery.min.js放在html目錄下的lib目錄中.

並在index.html的<head></head>塊中, 添加以下代碼:

<script type="text/javascript" src="./lib/jquery.min.js"></script>

 

5. 在index.html中, 添加一個輸入框和按鈕

在index.html的<body></body>塊中的最下方, 添加以下代碼:

<div class="vertical-center">
    <div class="container">
        <p>&nbsp;</p>
        <form role="form" id="chat_form" onsubmit="sendWsMessage(); return false;">
            <div class="form-group">
                <input class="form-control" type="text" name="message" id="message"
                       placeholder="Type text to echo in here" value="" />
            </div>
            <button type="button" id="send" class="btn btn-primary"   
                    onclick="sendWsMessage();"> 
                Send!
            </button>
        </form>
    </div>
</div>

在這段代碼中:

咱們首先定義了一個輸入框即表單form, 該表單包含了input元素, 用戶能夠在該輸入框內填寫字符, 而html能夠經過message來獲取輸入框內的字符.

接着咱們定義了一個按鈕button, 在網頁中按鈕顯示爲send!, 並給該按鈕的左鍵點擊事件onclick綁定了一個函數onclick="sendWsMessage();", 當用戶左鍵點擊這個send!按鈕, 就會觸發sendWsMessage()函數.

 

6. 在index.html中, 定義ws客戶端

在index.html的<script></script>塊中的最下方, 添加以下代碼:

const ws = new WebSocket("ws://localhost:12122");

這段代碼中:

咱們先實例化了一個websocket對象ws, 其參數爲要鏈接的地址, 這裏使用本機localhost的12122端口, 若是你是在局域網內啓動, 也能夠將localhost替換爲你的內網ip.

 

7. 在index.html中, 定義按鈕的sendWsMessage()函數

在index.html的<script></script>塊中的最下方, 添加以下代碼:

function sendWsMessage() {
  ws.send($('#message').val());
}

這段代碼中:
咱們調用了websocket對象wssend()方法, 向目標地址localhost的12122端口發送數據, 數據的內容是經過#message獲取的, 即用戶在輸入框內輸入的數據.

前端流程:

當用戶點擊send!按鈕, 獲取輸入框內的內容, 經過ws, 向localhost的12122端口發送.

 

8. 啓動

執行指令:

npm start

此時的程序界面, 出現了輸入框send!按鈕.

 

回到cmd中, 發現cmd打印了一條日誌

client connected

那是由於咱們在ws服務器(main.js)中, 添加了以下代碼:

wss.on('connection', (ws) => {
  // 有客戶端鏈接時, 打印一條日誌
  console.log('client connected');

當程序啓動的時候, 自動創建了鏈接, 因此打印了這條日誌.

若是你已經完成了例子1, 而且尚未刪除代碼的話, 試着再次從瀏覽器中訪問http://localhost:8080/index.html, 是否又打印出了一條相同的日誌?

 

如今, 咱們試試發送消息的功能:

在程序界面的輸入框內, 輸入一個Hello electron!, 點擊send!

回到cmd中, 成功打印了日誌Hello electron!.

 

前端流程:

當用戶點擊send!按鈕, 獲取輸入框內的內容, 經過ws, 向localhost的12122端口發送.

後端流程:

當ws服務器收到消息的時候, 直接將消息打印出來.

 

例子3: 進程管理

 

1. 部署node.js+electron環境

node.js+electron教程(一): 安裝nodejs和electron

 

2. 在main.js中, 啓動一個外部進程

在main.js中, 添加以下代碼:

const myChildProccess = require('child_process');

// 打開一個子進程notepad++
const mySpawn = myChildProccess.spawn(
    'e:\\Application\\Notepad++\\notepad++.exe');

在這段代碼中:

咱們建立了一個myChildProccess對象

  const myChildProccess = require('child_process');

這個對象是經過child_process模塊建立出來的, 該模塊主要用於建立子進程.

咱們調用這個對象的spwan()方法, 啓動一個子進程. 該方法接受一個字符串參數, 是子進程的路徑, 注意路徑的書寫方式.

 

3. 測試

執行命令:

npm start

在程序啓動後, notepad++也緊跟着啓動了, notepad++就是本程序啓動的子進程.

electron能夠啓動子進程, 天然也能夠關閉子進程, 否則算什麼進程管理?

 

如今咱們關閉程序, 繼續進行下一步.

 

4. 在index.html中, 添加一個按鈕, 關閉子進程

在index.html的<body></body>塊中的最下方, 添加以下代碼:

<button onclick="killChildProcess()">關閉子進程</button>

在這段代碼中, 咱們添加了一個按鈕button, 在網頁中按鈕顯示爲關閉子進程, 並給該按鈕綁定了一個函數killChildProcess()

 

5. 建立renderer.js, 並添加到項目中

在html目錄建立一個renderer.js文件

添加以下代碼:

function killChildProcess() {
  // 發消息,由html的按鈕調用,給主進程發消息,回調中關閉進程
  const ipcRenderer = require('electron').ipcRenderer;
  ipcRenderer.send('kill-child-now', 'get async message');
}

咱們定義了關閉子進程按鈕的點擊函數killChildProcess(), 這個函數只有兩行:

在函數的第一行, 建立了一個ipcRenderer對象

  const ipcRenderer = require('electron').ipcRenderer;

這個對象是經過ipcRenderer模塊建立出來的, w3cschool是這樣解釋的:

ipcRenderer 模塊是一個 EventEmitter 類的實例. 它提供了有限的方法,你能夠從渲染進程向主進程發送同步或異步消息. 也能夠收到主進程的響應.

簡單的說, main.js是主進程, renderes.js是渲染進程, 在渲染進程調用ipcRenderer.send()方法, 能夠發送消息. 在主進程能夠收到消息, 若是你給這個消息綁定了回調, 收到消息後, 就會觸發回調.

 

在函數的第二行, 咱們發送了kill-child-now消息.

如今咱們把renderer.js引入到項目之中

jquery類似, 在index.html的<head></head>塊中, 添加以下代碼:

<script type="text/javascript" src="../dist/renderer.js"></script>

 

6. 在main.js中, 監聽消息, 綁定回調

在main.js的最下方, 添加以下代碼:

// 監聽消息, 關閉子進程
const ipcMain = require('electron').ipcMain;

ipcMain.on('kill-child-now', (e, appUrl)=>{
  // 收到消息, 關閉進程
  mySpawn.kill();
});

在這段代碼中:

咱們建立了一個ipcMain對象

const ipcMain = require('electron').ipcMain;

這個對象是經過ipcMain模塊建立出來的, w3cschool是這樣解釋的:

ipcMain 模塊是類 EventEmitter 的實例.當在主進程中使用它的時候,它控制着由渲染進程(web page)發送過來的異步或同步消息.從渲染進程發送過來的消息將觸發事件.

簡單的說, ipcMain是使用在主進程中的, 負責監遵從渲染進程中發送出來的消息.

( 還記得嗎? 渲染進程是經過ipcRenderer發送消息的. )

咱們用ipcMain對象監聽了消息kill-child-now, 而且綁定了一個回調函數. 一旦收到這個消息, 就會觸發這個回調函數.

回調函數只有一行, 簡單直接:

mySpawn.kill( )

關閉在第三步中建立的子進程notepad++.

 

7. 啓動

執行命令:

npm start

和以前的測試同樣, 在程序啓動後, notepad++也緊跟着啓動了, notepad++就是本程序啓動的子進程.

不同的是, 程序界面上出現了一個按鈕關閉子進程.

點擊這個按鈕試試看!

相關文章
相關標籤/搜索