美文网首页
Electron+HTML做界面,C#做后台(三)使用Socke

Electron+HTML做界面,C#做后台(三)使用Socke

作者: 黄二狗家的黄二庄 | 来源:发表于2019-01-14 16:16 被阅读0次

    Electron 和 C#控制台程序通信

    Electron+HTML做界面,C#做后台(二) 中简单说了线如何创建C#程序,并启动Electron程序,那么这节就说说两者之间怎么通信【C#使用StriveEngine.dll】或者百度相关信息

    打开前面创建的项目

    1.将debug目录下的 electronApp复制一份到当前的项目目录,

    在这里插入图片描述

    与vs创建的 bin目录同级

    在这里插入图片描述

    2.在vs项目中 包含electronApp目录文件(不要包含node_modules目录,文件太多)

    在这里插入图片描述

    3.继续选中文件,并选中右键属性,复制到输出目录 在这里插入图片描述

    4. 添加类创建 Socket服务 ,类名称 Services.cs【记得添加引用】

    using StriveEngine;
    using StriveEngine.Core;
    using StriveEngine.Tcp.Server;
    using System;
    using System.Diagnostics;
    using System.Net;
    using System.Text;
    using System.Windows.Forms;
    
    namespace ElectronHTMlCSharp
    {
        /// <summary>
        /// 在本地开启服务,监听指定端口
        /// </summary>
        public class Services
        {
            public static Services services;
    
            private ITcpServerEngine SockterServerEngine;
            private bool IsSocketServerInitialized;
            public void StartServer()
            {
                try
                {
                    if (SockterServerEngine == null)
                    {
                        var port = AppTools.Get("port");
                        var _port = port == null || port.Length <= 0 ? 9909 : int.Parse(port);
                        SockterServerEngine = NetworkEngineFactory.CreateTextTcpServerEngine(_port, new DefaultTextContractHelper("\0"));//DefaultTextContractHelper是StriveEngine内置的ITextContractHelper实现。使用UTF-8对EndToken进行编码。 
                    }
                    //判断 相关的监听事件是否注册
                    if (IsSocketServerInitialized)
                    {
                        SockterServerEngine.ChangeListenerState(true);
                    }
                    else
                    {
                        InitializeTcpServerEngine();
                    }
    
                    //this.ShowListenStatus();
                }
                catch (Exception ee)
                {
                    Console.WriteLine(ee.Message);
                    if (ee.Message.IndexOf("there's one StriveEngine server instance running") >= 0)
                    {
                        var res = MessageBox.Show("已打开一个实例或者前面实例的进程为未完全退出,是否重启?\r\n是:重启\r\n否:关闭\r\n取消:不做任何处理", "警告", MessageBoxButtons.YesNoCancel);
                        if (DialogResult.Yes == res)
                        {
                            Application.ExitThread();
                            Application.Exit();
                            Application.Restart();
                            Process.GetCurrentProcess().Kill();
                        }
                        else if (DialogResult.No == res)
                        {
                            Application.ExitThread();
                            Application.Exit();
                            Process.GetCurrentProcess().Kill();
                        }
                    }
                }
                services = this;
            }
            /// <summary>
            /// 为 socket 注册 服务事件
            /// </summary>
            private void InitializeTcpServerEngine()
            {
                //客户端连接数量变化时,触发事件
                SockterServerEngine.ClientCountChanged += new CbDelegate<int>(ClientCountChage);
                //客户端与服务端建立连接时, 触发事件
                SockterServerEngine.ClientConnected += new CbDelegate<IPEndPoint>(ClientConnected);
                //客户端断开连接时, 触发事件
                SockterServerEngine.ClientDisconnected += new CbDelegate<IPEndPoint>(ClientDisconnected);
                //接受消息,触发事件
                SockterServerEngine.MessageReceived += new CbDelegate<IPEndPoint, byte[]>(MessageReceived);
    
                //初始化tcp服务对象
                SockterServerEngine.Initialize();
                //标记tcp 服务已经初始化
                IsSocketServerInitialized = true;
            }
    
            /// <summary>
            ///  客户端连接数量变化时,触发事件
            /// </summary>
            private void ClientCountChage(int count)
            {
                Console.WriteLine("已连接数量" + count);
            }
    
            /// <summary>
            /// 客户端与服务端建立连接时, 触发事件
            /// </summary>
            /// <param name="IPEndPoint"></param>
            private void ClientConnected(IPEndPoint iPEndPoint)
            {
                var msg = string.Format("{0} 上线", iPEndPoint);
                Console.WriteLine(msg);
            }
    
            /// <summary>
            /// 断开服务时, 触发事件
            /// </summary>
            /// <param name="iPEndPoint"></param>
            private void ClientDisconnected(IPEndPoint iPEndPoint)
            {
                var msg = string.Format("{0} 下线", iPEndPoint);
                Console.WriteLine(msg);
            }
    
            /// <summary>
            /// 接受消息,触发事件
            /// </summary>
            /// <param name="client"></param>
            /// <param name="bMsg"></param>
            private void MessageReceived(IPEndPoint client, byte[] bMsg)
            {
                var msg = Encoding.UTF8.GetString(bMsg); //消息使用UTF-8编码
                SendMsgToClient("接收到客户端消息:" + msg, client);
            }
    
            /// <summary>
            /// 发送消息到指定的客户端
            /// </summary>
            /// <param name="msg"></param>
            /// <param name="client"></param>
            public void SendMsgToClient(string msg, IPEndPoint client)
            {
                var bMsg = System.Text.Encoding.UTF8.GetBytes(msg);//消息使用UTF-8编码
                client = client ?? (IPEndPoint)SockterServerEngine.GetClientList()[0];
                SockterServerEngine.SendMessageToClient(client, bMsg);
            }
        }
    }
    
    

    4.2在Program.cs文件的Main方法中调用 Services ,添加如下代码

        var ser = new Services();
        ser.StartServer();
    

    最终如图

    在这里插入图片描述

    5.创建 js文件用于前端socket请求工具类

    5.1在 electronApp目录下创建socket-helper.js

    var top = top || {};
    
    /**
     * 创建 sock实例并发送消息 ,短连接 ,发送一条消息之后就关闭
     * @param {any} ip 发送内容
     * @param {any} port 发送内容
     * @param {any} sendMsg 发送内容
     * @param {any} callGetMsg 得到消息的回调函数
     * @param {any} callOpen 连接之后服务端发送回 消息 执行的回调函数
     * @param {any} cllClose 关闭连接的回调函数,默认自动关闭
     */
    function initSocket(ip, port, sendMsg,callGetMsg,callOpen,cllClose) {
        top.ip = top.ip || ip;
        top.port = top.port || port;
        var host = "ws://" + top.ip + ":" + top.port + "/"
        socket = new WebSocket(host);
        socket.onmessage = function (event) {
            if (typeof callGetMsg == "function")
                callGetMsg(event);
            if (typeof cllClose == "function") {
                    cllClose(socket);
                } else {
                socket.close();
            }
        }
        socket.onopen = function (event) {
            if (typeof callOpen == "function")
                callOpen(event);
            socket.send(sendMsg);
        }
        return socket;
    }
    
    /**
     * 创建 sock实例并发送消息 ,短连接 ,发送一条消息之后就关闭
     * @param {any} sendMsg 发送内容
     * @param {any} callGetMsg 得到消息的回调函数
     * @param {any} callOpen 连接之后服务端发送回 消息 执行的回调函数
     * @param {any} cllClose 关闭连接的回调函数,默认自动关闭
     */
    function initSockets(sendMsg, callGetMsg, callOpen, cllClose) {
        var host = "ws://" + top.ip + ":" + top.port + "/"
        socket = new WebSocket(host);
        socket.onmessage = function (event) {
            if (typeof callGetMsg == "function")
                callGetMsg(event);
            if (typeof cllClose == "function") {
                cllClose(socket);
            } else {
                socket.close();
            }
        }
        socket.onopen = function (event) {
            if (typeof callOpen == "function")
                callOpen(event);
            socket.send(sendMsg);
        }
        return socket;
    }
    
    
    /**
     * 创建 sock实例并发送消息 ,长连接
     * @param {any} sendMsg 发送内容
     * @param {any} callGetMsg 得到消息的回调函数
     * @param {any} callOpen 连接之后服务端发送回 消息 执行的回调函数
     * @param {any} cllClose 关闭连接的回调函数,默认自动关闭
     */
    function initSocketLong(sendMsg, callGetMsg, callOpen, cllClose) {
        var host = "ws://" + top.ip + ":" + top.port + "/"
        socket = new WebSocket(host);
        socket.onmessage = function (event) {
            if (typeof callGetMsg == "function")
                callGetMsg(event);
            if (typeof cllClose == "function") {
                cllClose(socket);
            }
        }
        socket.onopen =  function (event) {
            if (typeof callOpen == "function")
                callOpen(event);
            sendMsg += (sendMsg.indexOf("?") > 0 ? "&" : "?") + "isLong=true";
            socket.send(sendMsg);
        }
        return socket;
    }
    

    5.2创建 socket页面调用 js文件 hander.js

    /***
     * 依赖文件 socket-helper.js
     * */
    
    //配置 通信信息
    function getSocketConf() {
        return {
            ip: '127.0.0.1',
            port: '9909'
        }
    }
    
    ///**
    // * 发送请求,返回后端处理的数据
    // * @param {any} action action!method?par1=1&par2=2&parn=n&....
    // * @param {any} callback 后端返回的回调函数
    // */
    //function Hander(action, callback) {
    //    var con = getSocketConf();
    //    top.ip = !top.ip ? con["ip"] : top.ip;
    //    top.port = !top.port ? con["port"] : top.port;
    //    initSockets(action, callback);
    //}
    
    /**
     * 发送请求,返回后端处理的数据
     * @param {any} action action!method?par1=1&par2=2&parn=n&....
     * @param {any} callback 后端返回的回调函数
     */
    function Hander(action, callback) {
        var con = getSocketConf();
        top.ip = !top.ip ? con["ip"] : top.ip;
        top.port = !top.port ? con["port"] : top.port;
       return initSockets(action, callback, null, function (event) {});
    }
    
    /**
     * 发送请求,返回后端处理的数据 长链接 
     * @param {any} action action!method?par1=1&par2=2&parn=n&....
     * @param {any} callback 后端返回的回调函数
     */
    function HanderLong(action, callback) {
        var con = getSocketConf();
        top.ip = !top.ip ? con["ip"] : top.ip;
        top.port = !top.port ? con["port"] : top.port;
        return initSocketLong(action, callback, null, function (event) { });
    }
    

    创建好的目录如下

    在这里插入图片描述

    创建完两个 js文件之后一定记得 右键属性复制到输出目录

    6之后我们需要在index.html页面上使用socket进行通信,添加如下代码

    <!doctype html>
    <html>
        <head>
            <title>hello Word</title>
        </head>
        <body>
            <h1>这是用Electron创建的程序,这个程序后面将会使用C#来实现数据逻辑处理</h1>
            <div>
                <input type="text" value="测试文字" id="text" />
                <input type="button" id="send" value="发送" />
                接受区域
                <div id="msg" style="width:100%;height:auto;border:1px solid #0094ff;">
    
                </div>
            </div>
            <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
            <script>if (typeof module === 'object') { top.$ = window.jQuery = window.$ = module.exports; };</script>
            <script src="socket-helper.js"></script>
            <script src="hander.js"></script>
            <script>
                $(function () {
                    //侦听 发送按钮 事件,并将返C#端返回的数据 绑定到接受区域
                    $("#send").on("click", function () {
                        var msg = $("#text").val();
                        Hander(msg, function (res) {
                            var html = $("#msg").html();
                            $("#msg").html(html + "<p>"+res.data+"</p>");
                        })
                    });
                });
            </script>
        </body>
    </html>
    
    

    7.启动vs项目

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

    *** 如此前后台就可以通行了,但是要注意 这个 websock框架对发送的字节大小有限制 ***

    后面将会讲述如何通过webSoket ,执行C# 指定类的指定的方法 【使用反射实现

    如果你已经迫不及待,那么请下载整个项目的源代码,代码已放置 GITHUB源码下载,上面有最新的效果图

    相关文章

      网友评论

          本文标题:Electron+HTML做界面,C#做后台(三)使用Socke

          本文链接:https://www.haomeiwen.com/subject/jjhjdqtx.html