Electron + WebSocket 通信

    技术2023-06-28  88

    Electron + WebSocket 通信

    描述

    本文主要介绍了结合 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 事件

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

    效果

    Processed: 0.010, SQL: 9