Electron + WebSocket 通信

本文详细介绍了如何结合Electron框架与WebSocket技术构建一个简单的通信应用。通过讲解项目结构、涉及的技术,如Node.js的os模块和WebSocket的基本概念,阐述了WebSocket作为全双工通讯协议的优势,并给出了创建WebSocket连接的示例代码。最后展示了运行效果。

Electron + WebSocket 通信

描述

本文主要介绍了结合 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子网掩码。
    • familyIPv4IPv6
    • 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 事件

    事件事件处理程序描述
    openSocket.onopen连接建立时触发
    messageSocket.onmessage客户端接收服务端数据时触发
    errorSocket.onerror通信发生错误时触发
    closeSocket.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>
效果

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值