Electron + Websoket 通訊


Electron + WebSocket + node.js 通信

描述

本文主要介紹了結合 Electron 和 node.js 進行 Websocket 通訊的一個簡單例子。

項目結構

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

技術

Node.js os 模塊

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

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

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

    方法 描述
    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() 返回一個包含 1、5、15 分鍾平均負載的數組。
    os.totalmen() 返回系統內存總量,單位為字節。
    os.freemem() 返回操作系統空閑內存量,單位是字節。
    os.cpus() 返回一個對象數組,包含所安裝的每個 CPU/內核的信息:型號、速度(單位 MHz)、時間(一個包含 user、nice、sys、idle 和 irq 所使用 CPU/內核毫秒數的對象)。
    os.networkInterfaces() 獲得網絡接口列表。
  • os.networkInterfaces()

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

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

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

    測試:

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

    結果:

Websocket
  1. Websocket是什么?

    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>

效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM