Electron + Websoket 通信

Electron + WebSocket + node.js 通訊

描述

本文主要介紹告終合 Electron 和 node.js 進行 Websocket 通信的一個簡單例子。javascript

項目結構

  • main.js:程序入口文件
  • websocket.html:web視圖
  • websocket.js :Websocket通信腳本

技術

Node.js os 模塊

提供基本的系統操做函數。 ( 參考:Node.js 工具模塊 )css

  1. 引入:
var os = require("os");
  1. 屬性html

    屬性 描述
    os.EOL 操做系統的行尾符的常量
  2. 方法java

    方法 描述
    os.tmpdir() 返回操做系統的默認臨時文件
    os.endianness() 返回CPU的字節序,多是「BE」或「LE」
    os.hostname() 返回操做系統的主機名
    os.type() 返回操做系統名稱
    os.platform() 返回編譯時的操做系統名
    os.arch() 返回操做系統CPU架構,可能值:「x64」、「arm」、「ia32」
    os.release() 返回操做系統的發行版本
    os.uptime() 返回操做系統運行的時間,單位:秒
    os.loadavg() 返回一個包含 一、五、15 分鐘平均負載的數組。
    os.totalmen() 返回系統內存總量,單位爲字節。
    os.freemem() 返回操做系統空閒內存量,單位是字節。
    os.cpus() 返回一個對象數組,包含所安裝的每一個 CPU/內核的信息:型號、速度(單位 MHz)、時間(一個包含 user、nice、sys、idle 和 irq 所使用 CPU/內核毫秒數的對象)。
    os.networkInterfaces() 得到網絡接口列表。
  • os.networkInterfaces()node

    返回的對象上的每一個鍵都標識了一個網絡接口。 關聯的值是一個對象數組,每一個對象描述了一個分配的網絡地址。jquery

    分配的網絡地址的對象上可用的屬性包括:web

    • address : IPv4或者IPv6地址。
    • netmask : IPv4或者IPv6子網掩碼。
    • family IPv4IPv6
    • mac : 網絡接口的 MAC 地址。
    • internal : 若是網絡接口是不可遠程訪問的環回接口或相似接口,則爲 true,不然爲 false
    • scopeid : 數值型的 IPv6 做用域 ID(僅當 familyIPv6 時指定)。
    • cidr : 以 CIDR 表示法分配的帶有路由前綴的 IPv4 或 IPv6 地址。若是 netmask 無效,則此屬性會被設爲 null

    測試:ajax

    //已分配網絡地址的網絡接口
    var networkArr = os.networkInterfaces();
    console.log(networkArr);

    結果:npm

Websocket
  1. Websocket是什麼?bootstrap

    WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議 。

    瀏覽器和服務器只須要完成一次握手,就能夠建立持久性的鏈接,並進行雙向數據傳輸。

  2. 爲什麼要選Websock?

    不少網站爲了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是指每隔一個特定時間,瀏覽器會向服務器發送一次HTTP請求,而後服務器返回數據給客戶端的瀏覽器。這種模式的缺點是瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,這樣會浪費不少的帶寬等資源。

    WebSocket 協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。

  3. Websocket 建立

    var Socket = new WebSocket(url, [protocol] );

    url 必選,鏈接的 url。

    protocol 可選,指定了可接受的子協議。

  4. Websocket 屬性

    屬性 描述
    Socket.readyState 只讀屬性 readyState 表示鏈接狀態。0 - 鏈接未創建;1 - 鏈接已創建;2 - 鏈接正在進行關閉;3 - 鏈接已經關閉或者不能打開。
    Socket.bufferedAmount 只讀屬性 bufferedAmount 已被 send() 放入正在隊列中等待傳輸,可是尚未發出的 UTF-8 文本字節數。
  5. Websocket 事件

    事件 事件處理程序 描述
    open Socket.onopen 鏈接創建時觸發
    message Socket.onmessage 客戶端接收服務端數據時觸發
    error Socket.onerror 通訊發生錯誤時觸發
    close Socket.onclose 鏈接關閉時觸發
  6. Websocket 方法

    方法 描述
    Socket.send() 使用鏈接發送數據
    Socket.close() 關閉鏈接

實現

websocket.js

在線 websoket 測試服務能夠網上隨便找一個就行。

/**
 * TCP/IP 通訊
 * 描述:跟全部相同網段的 ip 進行socket 鏈接
 * 例如:當前ip:192.168.1.100,則與192.168.1.1 ~ 192.168.1.254的設備創建通訊鏈接
 */
// 引入nodejs os模塊
var os = require("os");

//存儲 Websocket 對象數組
var websoketArray = [];

//在Electron中直接使用JQuery
if (typeof module === 'object') {window.jQuery = window.$ = module.exports;};

$(function(){
	start();
});

/**
 * 與相同網段創建通訊鏈接
 */
function start(){
	var ip = getIp();
	if(ip != "localhost"){
		ip = ip.substring(0,10);
		//在線 websoket 測試服務:可直接使用
		websoketArray.push(new createWebsocket("ws://123.207.136.134:9010/ajaxchattest"));
		//與相同網段創建通訊鏈接
		for(var i = 1; i < 255; i++){
			websoketArray.push(new createWebsocket("ws://" + ip + i));
		}
	}
}

/**
 * 獲取本機IP
 */
function getIp(){
	var ip = "";
	try{
		//已分配網絡地址的網絡接口
		var networkArr = os.networkInterfaces();
		for(var network in networkArr){
			var ifaces = networkArr[network];
			for (var i = 0; i < ifaces.length; i++) {
				if(ifaces[i].family === "IPv4" && ifaces[i].address != "127.0.0.1" && !ifaces[i].internal){
					//IPv4地址
					ip = ifaces[i].address;
				}
			}
		}
	}catch(e){
		//TODO handle the exception
		ip = "localhost"
	}
	return ip;
}

/**
 * 定義websocket 對象
 */
function createWebsocket(url){
	
	var ws = new WebSocket(url);
	
	//鏈接成功回調
	ws.onopen = (evt) => {
		console.log("Conenection open ...");
		$("#chartRoom").append(
			$("<p></p>").text("與 " + url + " 創建鏈接--成功")
		);
	}
	
	//消息監聽
	ws.onmessage = (evt) => {
		console.log("msg");
		document.getElementById('receivedMsg').innerHTML = event.data;
	}
	
	//鏈接失敗
	ws.onerror = function(evt){
		$("#chartRoom").append(
			$("<p></p>").text("與 " + url + " 創建鏈接--失敗")
		);
		//關閉鏈接
		ws.close();
		//移除失敗的ws
		websoketArray.splice(websoketArray.indexOf(ws),1);
		console.log("移除 " + url + " 鏈接");
	}
	return ws;
	
}

/**
 * 消息發送
 * 給全部創建成功的鏈接發送消息
 */
function sendMsg(){
	//消息內容
	var msg = document.getElementById("sendMsg").value;
	if(msg !== "" && msg !== undefined){
		for(var i = 0; i < websoketArray.length; i++){
			websoketArray[i].send(msg);
			document.getElementById("sendMsg").value = null;
		}
	}
}
websocket.html
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>WebSocket demo</title>
		<!-- bootstrap 4.5.0 -->
		<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
		<!-- Jquery 3.5 -->
		<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
	</head>
	<body>
		<div class="container-fluid">
			<h3>TCP/IP 協議通訊</h3>
			<div class="row mt-3">
				<div class="col-8">
					<textarea rows="6" id="sendMsg" style="width: 100%;"></textarea>
				</div>
				<div class="col-4">
					<div class="btn-group-vertical">
						<button type="button" class="btn btn-outline-info" onkeydown="sendMsg()" onclick="sendMsg()">發送</button>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col">
					<div ></div>
					<div class="jumbotron jumbotron-fluid">
					  <div class="container" id="chartRoom">
					    <h1 class="display-4">WebSocket 通訊</h1>
						<p class="lead">本機發送消息:<span id="receivedMsg"></span></p>
						<a class="btn btn-primary btn-lg" href="javascript:;" onclick="start()" role="button">刷新鏈接</a>
						<hr class="my-4">
					  </div>
					</div>
				</div>
			</div>
		</div>
		
		<script src="../static/js/websocket.js"></script>	
	</body>
</html>

效果

相關文章
相關標籤/搜索