.Net 使用SuperSockect實現 TCP服務端與客戶端的實時通信(二)

本章主要實現TCP客戶端功能的實現,服務端功能實現參見https://blog.csdn.net/liwan09/article/details/106320516

一、項目創建

1、VS2017創建winform項目

2、Nuget搜索並安裝SuperSocket.ClientEngine、SuperSocket.ProtoBase

二、客戶端功能實現

1、頁面設計

2、後端代碼

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using SuperSocket.ClientEngine;
using Newtonsoft.Json;
using SockectClient.Model;

namespace SockectClient
{
    public partial class frmMain : Form
    {
        //EasyClient easyClient;
        AsyncTcpSession asyncTcpSession;
        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            this.txtIpAddress.Text = "127.0.0.1";
            this.txtPort.Text = "4141";
            this.btnDisconnect.Enabled = false;
        }

        /// <summary>
        /// 啓動
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConnect_Click(object sender, EventArgs e)
        {
            string ipAddress = txtIpAddress.Text.Trim();
            int port = Convert.ToInt32(txtPort.Text.Trim());

            #region AsyncTcpSession連接方式
            asyncTcpSession = new AsyncTcpSession();
            asyncTcpSession.Closed += client_Closed;
            asyncTcpSession.Connected += client_Connected;
            asyncTcpSession.Error += client_Error;
            asyncTcpSession.DataReceived += client_DataReceived;
            try
            {
                asyncTcpSession.Connect(new IPEndPoint(IPAddress.Parse(ipAddress), port));
                txtLog.Text += "連接成功!\r\n";
                txtIpAddress.Enabled = false;
                txtPort.Enabled = false;
                btnConnect.Enabled = false;
                btnDisconnect.Enabled = true;
            }
            catch(Exception ex)
            {
                txtLog.Text += "連接失敗!\r\n";
            }
            #endregion

            #region EasyClient連接方式
            //easyClient = new EasyClient();
            //easyClient.Closed += client_Closed;
            //easyClient.Connected += client_Connected;
            //easyClient.Error += client_Error;
            //easyClient.Initialize(new ReceiveFilter(), (request) =>
            //{
            //    // handle the received request
            //});
            //var result=easyClient.ConnectAsync(new IPEndPoint(IPAddress.Parse(ipAddress), port));
            //if (result.Result)
            //{
            //    txtLog.Text += "連接成功!\r\n";
            //    txtIpAddress.Enabled = false;
            //    txtPort.Enabled = false;
            //    btnConnect.Enabled = false;
            //    btnDisconnect.Enabled = true;
                
            //}
            //else
            //{
            //    txtLog.Text += "連接失敗!\r\n";
            //}
            #endregion
        }
        /// <summary>
        /// 數據接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void client_DataReceived(object sender, DataEventArgs e)
        {
            string msg = Encoding.Default.GetString(e.Data);
            this.Invoke(new Action(() =>
            {
                txtLog.Text +="【"+DateTime.Now.ToString()+ "】接收的消息:\r\n"+msg+"\r\n";
            }));
        }
        /// <summary>
        /// 服務端關閉事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void client_Closed(object sender,EventArgs e)
        {
            //EasyClient client = sender as EasyClient;
            AsyncTcpSession client = sender as AsyncTcpSession;
            this.Invoke(new Action(() => {
                txtLog.Text += "服務端關閉\r\n";
                //easyClient = null;
                asyncTcpSession = null;
                txtIpAddress.Enabled = true;
                txtPort.Enabled = true;
                btnConnect.Enabled = true;
                btnDisconnect.Enabled = false;
            }));
        }
        /// <summary>
        /// 連接事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void client_Connected(object sender, EventArgs e)
        {
            //EasyClient client = sender as EasyClient;
            AsyncTcpSession client = sender as AsyncTcpSession;
        }
        /// <summary>
        /// 錯誤事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void client_Error(object sender, ErrorEventArgs e)
        {
            //EasyClient client = sender as EasyClient;
            AsyncTcpSession client = sender as AsyncTcpSession;
            this.Invoke(new Action(()=> {
                txtLog.Text += "Error:" + e.Exception + "\r\n";
            }));           
        }
        /// <summary>
        /// 斷開
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            #region asyncTcpSession斷開方式
            try
            {
                asyncTcpSession.Close();              
                txtLog.Text += "斷開成功!\r\n";
                asyncTcpSession = null;
                txtIpAddress.Enabled = true;
                txtPort.Enabled = true;
                btnConnect.Enabled = true;
                btnDisconnect.Enabled = false;
            }
            catch(Exception ex)
            {
                txtLog.Text += "斷開失敗!\r\n";
            }
            #endregion

            #region easyClient斷開方式
            //var result = easyClient.Close();
            //if (result.Result)
            //{
            //    txtLog.Text += "斷開成功!\r\n";
            //    easyClient = null;                
            //    txtIpAddress.Enabled = true;
            //    txtPort.Enabled = true;
            //    btnConnect.Enabled = true;
            //    btnDisconnect.Enabled = false;
            //}
            //else
            //{
            //    txtLog.Text += "斷開失敗!\r\n";
            //}
            #endregion
        }

        private void btnSendLogin_Click(object sender, EventArgs e)
        {
            AppDeviceData appDeviceData = new AppDeviceData();
            appDeviceData.DeviceID =cbDevice.Text.ToString();
            appDeviceData.LoginName = "admin";
            appDeviceData.BatteryLeft = "90%";

            ReceiveData receiveData = new ReceiveData();
            receiveData.MessageType = "1";
            receiveData.MessageContent = JsonConvert.SerializeObject(appDeviceData);
            
            string sendMsg= JsonConvert.SerializeObject(receiveData)+"\r\n";//必須以\r\n結尾
            byte[] bytes = Encoding.Default.GetBytes(sendMsg);
            try
            {
                //easyClient.Send(bytes);//easyClient 消息發送方式
                asyncTcpSession.Send(bytes,0,bytes.Length);//asyncTcpSession 消息發送方式
                txtLog.Text += "【"+DateTime.Now.ToString()+"】發送消息:\r\n" + sendMsg + "\r\n";
            }
            catch(Exception ex)
            {
                txtLog.Text += sendMsg+"消息發送失敗:" + ex.Message+"\r\n";
            }            
        }

        private void btnEquipFault_Click(object sender, EventArgs e)
        {
            EquipmentFault equipmentFault = new EquipmentFault();
            equipmentFault.MessageTitle = "設備故障";
            equipmentFault.MessageUID = Guid.NewGuid().ToString();
            equipmentFault.FaultTime = DateTime.Now;
            equipmentFault.SubAPPName = "weixiu";
            equipmentFault.TargetPhoneID = cbDevice.Text.ToString();
            equipmentFault.EmergenceLevel = "Low";

            ReceiveData receiveData = new ReceiveData();
            receiveData.MessageType = "2";
            receiveData.MessageContent = JsonConvert.SerializeObject(equipmentFault);

            string sendMsg = JsonConvert.SerializeObject(receiveData) + "\r\n";//必須以\r\n結尾
            byte[] bytes = Encoding.Default.GetBytes(sendMsg);
            try
            {
                //easyClient.Send(bytes);//easyClient 消息發送方式
                asyncTcpSession.Send(bytes, 0, bytes.Length);//asyncTcpSession 消息發送方式
                txtLog.Text += "【" + DateTime.Now.ToString() + "】發送消息:\r\n" + sendMsg + "\r\n";
            }
            catch (Exception ex)
            {
                txtLog.Text += sendMsg + "消息發送失敗:" + ex.Message+"\r\n";
            }
        }
    }
}

3、其他相關代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.ProtoBase;

namespace SockectClient
{
    /// <summary>
    /// 帶起止符協議過濾
    /// </summary>
    public class ReceiveFilter : BeginEndMarkReceiveFilter<StringPackageInfo>
    {
        //可選繼承類:
        //TerminatorReceiveFilter 結束符協議
        //BeginEndMarkReceiveFilter 帶起止符的協議
        //FixedHeaderReceiveFilter 頭部格式固定並且包含內容長度的協議 
        //FixedSizeReceiveFilter 固定請求大小的協議
        //CountSpliterReceiveFilter 固定數量分隔符協議
        public ReceiveFilter()
            : base(Encoding.ASCII.GetBytes("#"), Encoding.ASCII.GetBytes("$\r\n"))
        {

        }
        /// <summary>
        /// 經過過濾器,收到的字符串會到這個函數
        /// </summary>
        /// <param name="bufferStream"></param>
        /// <returns></returns>
        public override StringPackageInfo ResolvePackage(IBufferStream bufferStream)
        {
            return null;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SockectClient.Model
{
    /// <summary>
    /// App端傳輸的數據
    /// </summary>
    public class AppDeviceData
    {
        /// <summary>
        /// 登錄設備的ID
        /// </summary>
        public string DeviceID { get; set; }
        /// <summary>
        /// 登錄的賬戶名稱
        /// </summary>
        public string LoginName { get; set; }
        /// <summary>
        /// 剩餘電量
        /// </summary>
        public string BatteryLeft { get; set; }
        /// <summary>
        /// 在線狀態 0:不在線 1在線 默認在線
        /// </summary>
        public int IsOnline { get; set; } = 1;
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SockectClient.Model
{
    /// <summary>
    /// 設備故障信息
    /// </summary>
    public class EquipmentFault
    {
        /// <summary>
        /// 目標手機設備ID
        /// </summary>
        public string TargetPhoneID { get; set; }
        /// <summary>
        /// 故障發生時間
        /// </summary>
        public DateTime FaultTime { get; set; }
        /// <summary>
        /// 消息id
        /// </summary>
        public string MessageUID { get; set; }
        /// <summary>
        /// 消息標題
        /// </summary>
        public string MessageTitle { get; set; }
        /// <summary>
        /// 發送給App(消息類型)
        /// </summary>
        public string SubAPPName { get; set; }
        /// <summary>
        /// 故障等級 Low,Default,High,Emergent
        /// </summary>
        public string EmergenceLevel { get; set; }
        /// <summary>
        /// 是否已讀 0:否 1:是 默認否
        /// </summary>
        public int IsRead { get; set; } = 0;
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SockectClient.Model
{
    /// <summary>
    /// 接收的消息
    /// </summary>
    public class ReceiveData
    {
        /// <summary>
        /// 接收的消息類型 1:App端登錄 2:設備故障信息推送
        /// </summary>
        public string MessageType { get; set; }
        /// <summary>
        /// 消息內容
        /// </summary>
        public string MessageContent { get; set; }
    }
}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章