Electron + Websoket 通讯
Electron + WebSocket + node.js 通信
描述
本文主要介绍了结合 Electron 和 node.js 进行 Websocket 通讯的一个简单例子。
项目结构
- main.js:程序入口文件
- websocket.html:web视图
- websocket.js :Websocket通讯脚本
技术
Node.js os 模块
提供基本的系统操作函数。 ( 参考:Node.js 工具模块 )
- 引入:
var os = require("os");
-
属性
属性 描述 os.EOL
操作系统的行尾符的常量 -
方法
方法 描述 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
: IPv4
或IPv6
。mac
: 网络接口的 MAC 地址。 internal
: 如果网络接口是不可远程访问的环回接口或类似接口,则为 true
,否则为false
。scopeid
: 数值型的 IPv6 作用域 ID(仅当 family
为IPv6
时指定)。cidr
: 以 CIDR 表示法分配的带有路由前缀的 IPv4 或 IPv6 地址。如果 netmask
无效,则此属性会被设为null
。
测试:
//已分配网络地址的网络接口 var networkArr = os.networkInterfaces(); console.log(networkArr);
结果:
Websocket
-
Websocket是什么?
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议 。
浏览器和服务器只需要完成一次握手,就可以创建持久性的连接,并进行双向数据传输。
-
为何要选Websock?
很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是指每隔一个特定时间,浏览器会向服务器发送一次HTTP请求,然后服务器返回数据给客户端的浏览器。这种模式的缺点是浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,这样会浪费很多的带宽等资源。
WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
-
Websocket 创建
var Socket = new WebSocket(url, [protocol] );
url 必选,连接的 url。
protocol 可选,指定了可接受的子协议。
-
Websocket 属性
属性 描述 Socket.readyState
只读属性 readyState 表示连接状态。0 - 连接未建立;1 - 连接已建立;2 - 连接正在进行关闭;3 - 连接已经关闭或者不能打开。 Socket.bufferedAmount
只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。 -
Websocket 事件
事件 事件处理程序 描述 open Socket.onopen 连接建立时触发 message Socket.onmessage 客户端接收服务端数据时触发 error Socket.onerror 通信发生错误时触发 close Socket.onclose 连接关闭时触发 -
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>