zoukankan      html  css  js  c++  java
  • 轻量级通信引擎StriveEngine —— C/S通信demo(附源码)

    前段时间,有几个研究ESFramework的朋友对我说,ESFramework有点庞大,对于他们目前的项目来说有点“杀鸡用牛刀”的意思,因为他们的项目不需要文件传送、不需要P2P、不存在好友关系、也不存在组广播、不需要服务器均衡、不需要跨服务器通信、甚至都不需要使用UserID,只要客户端能与服务端进行简单的稳定高效的通信就可以了。于是,他们建议我,整一个轻量级的通信组件来满足类似他们这种项目的需求。我觉得这个建议是有道理的,于是,花了几天时间,我将ESFramework的内核抽离出来,经过修改封装后,形成了StriveEngine,其最大的特点就是稳定高效、易于使用。通过下面这个简单的demo,我们应该就能上手了。文末有demo源码下载,我们先上Demo截图:

      

    1.Demo简介

    该Demo总共包括三个项目:

    1.StriveEngine.SimpleDemoServer:基于StriveEngine开发的服务端。

    2.StriveEngine.SimpleDemoClient:基于StriveEngine开发的客户端。

    3.StriveEngine.SimpleDemo:直接基于.NET的Socket开发的客户端,其目的是为了演示:在客户端不使用StriveEngine的情况下,如何与基于StriveEngine的服务端进行通信。

    StriveEngine 内置支持TCP/UDP、文本协议/二进制协议,该Demo我们使用TCP、文本格式的消息协议,消息的结束符为""。

    2.Demo服务端

    复制代码
        private ITcpServerEngine tcpServerEngine;
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //初始化并启动服务端引擎(TCP、文本协议)
                this.tcpServerEngine = NetworkEngineFactory.CreateTextTcpServerEngine(int.Parse(this.textBox_port.Text), new DefaultTextContractHelper("")); 
           this.tcpServerEngine.ClientCountChanged += new CbDelegate<int>(tcpServerEngine_ClientCountChanged); this.tcpServerEngine.ClientConnected += new CbDelegate<System.Net.IPEndPoint>(tcpServerEngine_ClientConnected); this.tcpServerEngine.ClientDisconnected += new CbDelegate<System.Net.IPEndPoint>(tcpServerEngine_ClientDisconnected); this.tcpServerEngine.MessageReceived += new CbDelegate<IPEndPoint, byte[]>(tcpServerEngine_MessageReceived); this.tcpServerEngine.Initialize(); this.button1.Enabled = false; this.textBox_port.ReadOnly = true; this.button2.Enabled = true; } catch (Exception ee) { MessageBox.Show(ee.Message); } } void tcpServerEngine_MessageReceived(IPEndPoint client, byte[] bMsg) { string msg = System.Text.Encoding.UTF8.GetString(bMsg); //消息使用UTF-8编码 msg = msg.Substring(0, msg.Length - 1); //将结束标记""剔除 this.ShowClientMsg(client, msg); } void tcpServerEngine_ClientDisconnected(System.Net.IPEndPoint ipe) { string msg = string.Format("{0} 下线", ipe); this.ShowEvent(msg); } void tcpServerEngine_ClientConnected(System.Net.IPEndPoint ipe) { string msg = string.Format("{0} 上线" ,ipe); this.ShowEvent(msg); } void tcpServerEngine_ClientCountChanged(int count) { this.ShowConnectionCount(count); } private void ShowEvent(string msg) { if (this.InvokeRequired) { this.BeginInvoke(new CbDelegate<string>(this.ShowEvent), msg); } else { this.toolStripLabel_event.Text = msg; } } private void ShowClientMsg(IPEndPoint client, string msg) { if (this.InvokeRequired) { this.BeginInvoke(new CbDelegate<IPEndPoint,string>(this.ShowClientMsg),client, msg); } else { ListViewItem item = new ListViewItem(new string[] { DateTime.Now.ToString(), client.ToString(), msg }); this.listView1.Items.Insert(0, item); } } private void ShowConnectionCount(int clientCount) { if (this.InvokeRequired) { this.BeginInvoke(new CbDelegate<int>(this.ShowConnectionCount), clientCount); } else { this.toolStripLabel_clientCount.Text = "在线数量: " + clientCount.ToString(); } } private void comboBox1_DropDown(object sender, EventArgs e) { List<IPEndPoint> list = this.tcpServerEngine.GetClientList(); this.comboBox1.DataSource = list; } private void button2_Click(object sender, EventArgs e) { try { IPEndPoint client = (IPEndPoint)this.comboBox1.SelectedItem; if (client == null) { MessageBox.Show("没有选中任何在线客户端!"); return; } if (!this.tcpServerEngine.IsClientOnline(client)) { MessageBox.Show("目标客户端不在线!"); return; } string msg = this.textBox_msg.Text + "";// "" 表示一个消息的结尾 byte[] bMsg = System.Text.Encoding.UTF8.GetBytes(msg);//消息使用UTF-8编码 this.tcpServerEngine.SendMessageToClient(client, bMsg); } catch (Exception ee) { MessageBox.Show(ee.Message); } }
    复制代码

    关于服务端引擎的使用,主要就以下几点:

    (1)首先调用NetworkEngineFactory的CreateTextTcpServerEngine方法创建引擎(服务端、TCP、Text协议)。

    (2)根据需要,预定引擎实例的某些事件(如MessageReceived事件)。

    (3)调用引擎实例的Initialize方法启动通信引擎。

    (4)调用服务端引擎的SendMessageToClient方法,发送消息给客户端。

    3.Demo客户端

    复制代码
        private ITcpPassiveEngine tcpPassiveEngine;
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                //初始化并启动客户端引擎(TCP、文本协议)
                this.tcpPassiveEngine = NetworkEngineFactory.CreateTextTcpPassiveEngine(this.textBox_IP.Text, int.Parse(this.textBox_port.Text), new DefaultTextContractHelper(""));
                this.tcpPassiveEngine.MessageReceived += new CbDelegate<System.Net.IPEndPoint, byte[]>(tcpPassiveEngine_MessageReceived);
                this.tcpPassiveEngine.AutoReconnect = true;//启动掉线自动重连                
                this.tcpPassiveEngine.ConnectionInterrupted += new CbDelegate(tcpPassiveEngine_ConnectionInterrupted);
                this.tcpPassiveEngine.ConnectionRebuildSucceed += new CbDelegate(tcpPassiveEngine_ConnectionRebuildSucceed);
                this.tcpPassiveEngine.Initialize();
    
                this.button2.Enabled = true;
                this.button3.Enabled = false;
                MessageBox.Show("连接成功!");
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }
    
        void tcpPassiveEngine_ConnectionRebuildSucceed()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbDelegate(this.tcpPassiveEngine_ConnectionInterrupted));
            }
            else
            {
                this.button2.Enabled = true;
                MessageBox.Show("重连成功。");
            }
        }
    
        void tcpPassiveEngine_ConnectionInterrupted()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbDelegate(this.tcpPassiveEngine_ConnectionInterrupted));
            }
            else
            {
                this.button2.Enabled = false;
                MessageBox.Show("您已经掉线。");
            }
        }
    
        void tcpPassiveEngine_MessageReceived(System.Net.IPEndPoint serverIPE, byte[] bMsg)
        {
            string msg = System.Text.Encoding.UTF8.GetString(bMsg); //消息使用UTF-8编码
            msg = msg.Substring(0, msg.Length - 1); //将结束标记""剔除
            this.ShowMessage(msg);
        }       
    
        private void ShowMessage(string msg)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new CbDelegate<string>(this.ShowMessage), msg);
            }
            else
            {
                ListViewItem item = new ListViewItem(new string[] { DateTime.Now.ToString(), msg });
                this.listView1.Items.Insert(0, item);                
            }
        }
    
        private void button2_Click(object sender, EventArgs e)
        {
            string msg = this.textBox_msg.Text + "";// "" 表示一个消息的结尾
            byte[] bMsg = System.Text.Encoding.UTF8.GetBytes(msg);//消息使用UTF-8编码
            this.tcpPassiveEngine.SendMessageToServer(bMsg);
        }
    复制代码

    关于客户端引擎的使用,与服务端类似:

    (1)首先调用NetworkEngineFactory的CreateTextTcpPassiveEngine方法创建引擎(客户端、TCP、Text协议)。

    (2)根据需要,预定引擎实例的某些事件(如MessageReceived、ConnectionInterrupted 事件)。

    (3)根据需要,设置引擎实例的某些属性(如AutoReconnect属性)。

    (4)调用引擎实例的Initialize方法启动通信引擎。

    (5)调用客户端引擎的SendMessageToServer方法,发送消息给服务端。

    4.基于Socket的客户端

    这个客户端直接基于.NET的Socket进行开发,其目演示了:在客户端不使用StriveEngine的情况下(比如客户端是异构系统),如何与基于StriveEngine的服务端进行通信。该客户端只是粗糙地实现了基本目的,很多细节问题都被忽略,像粘包问题、消息重组、掉线检测等等。而这些问题在实际的应用中,是必需要处理的。(StriveEngine中的客户端和服务端引擎都内置解决了这些问题)。
    该客户端的代码就不贴了,大家可以在源码中看到。

    5.源码下载

        文本协议通信demo源码

      附相关系列:  二进制通信demo源码及说明文档

                            打通B/S与C/S通信demo源码与说明文档

     另附:简单即时通讯Demo源码及说明

  • 相关阅读:
    hdu acm 2844 Coins 解题报告
    hdu 1963 Investment 解题报告
    codeforces 454B. Little Pony and Sort by Shift 解题报告
    广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告
    hdu acm 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
    hdu acm 1114 Piggy-Bank 解题报告
    poj 2531 Network Saboteur 解题报告
    数据库范式
    ngnix 配置CI框架 与 CI的简单使用
    Vundle的安装
  • 原文地址:https://www.cnblogs.com/sylone/p/6097073.html
Copyright © 2011-2022 走看看