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>

效果

posted @ 2020-07-03 14:21  听卉  阅读(2459)  评论(0编辑  收藏  举报