• 【C#】【Demo】消息队列RabbitMQ,和TCP监听Demo。


    注意连接队列服务器时,参数必须和服务器配置一致

      private string queue;//队列名
            private bool durable;//持久化
            private bool exclusive;//独占
            private bool autoDelete;//自动删除

    默认帐号guest不能远程。

    默认访问队列端口是5672,后台网站端口默认是15672。

    1、实现发送和接收,类RabbitMQServerT

    using System;
    using MQServer;
    using RabbitMQ.Client;
    using System.Text;
    using System.Configuration;
    using RabbitMQ.Client.Events;
    using Newtonsoft.Json;
    
    namespace MQServer
    {
        /// <summary>
        /// RabbitMQ消息队列类
        /// </summary>
        public class RabbitMQServerT 
        {
            protected readonly Action<string, object> receive;//接收回调
            private object penetrate;//接收回调透传参数
            private string queue;//队列名
            private bool durable;//持久化
            private bool exclusive;//独占
            private bool autoDelete;//自动删除
            private bool isBeginInvoke;//接收后业务是否异步,异步的话消息可能在确认前被其他线程读走,造成重复读。//不异步就阻塞。//异步请独占
    
            //接收消息对象
            private IConnection connection;
            private IModel channel;
    
            public bool IsReceive;
    
            private ConnectionFactory factory;
            private RabbitMQServerT()
            {
            }
    
            /// <summary>
            /// 使用默认配置参数
            /// </summary>
            /// <param name="_receive">消费事件,空则不消费</param>
            /// <param name="_queue">消息路径最后一层名字,可用于区分业务</param>
            /// <param name="_penetrate">接收回调透传参数</param>
            public RabbitMQServerT(Action<string, object> _receive, string _queue = @"hello", object _penetrate = null)
            {
                queue = _queue;
                receive = _receive;
                penetrate = _penetrate;
                isBeginInvoke = false;
    
                durable = bool.Parse(ConfigurationManager.AppSettings["RabbitMQ_durable"].ToString());//
                exclusive = bool.Parse(ConfigurationManager.AppSettings["RabbitMQ_exclusive"].ToString());//
                autoDelete = bool.Parse(ConfigurationManager.AppSettings["RabbitMQ_autoDelete"].ToString());//
    
                factory = new ConnectionFactory();
                factory.HostName = ConfigurationManager.AppSettings["RabbitMQHostName"];//RabbitMQ服务器
                factory.UserName = ConfigurationManager.AppSettings["RabbitMQUserName"];//用户名
                factory.Password = ConfigurationManager.AppSettings["RabbitMQPassword"];//密码
                factory.Port = int.Parse(ConfigurationManager.AppSettings["RabbitMQPort"].ToString());//
                if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["RabbitMQVirtualHost"]))
                {
                    factory.VirtualHost = ConfigurationManager.AppSettings["RabbitMQVirtualHost"];//
                }
            }
    
            /// <summary>
            /// 使用手动参数
            /// </summary>
            /// <param name="_receive">消费事件,空则不消费</param>
            /// <param name="_queue">消息路径最后一层名字,可用于区分业务</param>
            /// <param name="_penetrate">接收回调透传参数</param>
            /// <param name="factory">连接队列服务器</param>
            /// <param name="durable">持久化</param>
            /// <param name="exclusive">独占</param>
            /// <param name="autoDelete">自动删除</param>
            /// <param name="isBeginInvoke">接收是否异步//异步请独占,否则异常</param>
            public RabbitMQServerT(Action<string, object> _receive, string _queue, object _penetrate, ConnectionFactory factory
                ,bool durable,bool exclusive, bool autoDelete,bool isBeginInvoke)
            {
                queue = _queue;
                receive = _receive;
                penetrate = _penetrate;
    
                this.factory = factory;
                this.durable = durable;
                this.exclusive = exclusive;
                this.autoDelete = autoDelete;
                this.isBeginInvoke = isBeginInvoke;
    
                //异步请独占,不然会重复读
                if (isBeginInvoke == true && exclusive == false) 
                {
                    throw new Exception("接收消息队列对象RabbitMQServerT参数isBeginInvoke=true异步执行接收业务,如果要异步执行业务,请独占该消息exclusive=true,否则会被其他线程重复读取。");
                }
            }
    
            /// <summary>
            /// 发送消息
            /// </summary>
            /// <param name="message"></param>
            public void Send(string message)
            {
                //发送消息队列
                try
                {
                    using (var connection = factory.CreateConnection())
                    {
                        using (var channel = connection.CreateModel())
                        {
                            channel.QueueDeclare(queue, durable, exclusive, autoDelete, null);//创建一个消息队列
                            var body = Encoding.UTF8.GetBytes(message);
                            channel.BasicPublish("", queue, null, body); //开始传递
                            //TLogHelper.Info(message, "RabbitMQServerTSend");//发送的内容写进TXT
                        }
                    }
                }
                catch (Exception ex)
                {
                    TLogHelper.Error(ex.Message, "发送消息队列异常RabbitMQServerTSend:
    " + message);
                }
            }
            /// <summary>
            /// 发送消息
            /// </summary>
            /// <param name="message"></param>
            public void Send(RabbitMQMsgModel model)
            {
                //发送消息队列
                string message = JsonConvert.SerializeObject(model);
                Send(message);
            }
    
            /// <summary>
            /// 进行接收消息队列
            /// </summary>
            public void Receive()
            {
                if (receive == null)
                {
                    return;
                }
                IsReceive = true;
                try
                {
                    connection = factory.CreateConnection();
                    channel = connection.CreateModel();
                  
                    channel.QueueDeclare(queue, durable, exclusive, autoDelete, null);
                    channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
    
                    var consumer = new EventingBasicConsumer(channel);
                    consumer.Received += (model, ea) =>
                    {
                        try
                        {
                            var body = ea.Body.ToArray();
                            var message = Encoding.UTF8.GetString(body);
    
                            //接收后业务
                            if (isBeginInvoke)
                            {
                                receive?.BeginInvoke(message, penetrate,(e)=>{
                                    //确认消息
                                    channel.BasicAck(ea.DeliveryTag, false);
                                },null);
                            }
                            else 
                            {
                                receive?.Invoke(message, penetrate);
                                //确认消息
                                channel.BasicAck(ea.DeliveryTag, false);
                            }
                        }
                        catch (Exception ex)
                        {
                            TLogHelper.Error(ex.Message, "接收消息队列业务异常Received:"+queue);
                        }
                        finally
                        {
                            //再次生成接收
                            Receive();
                        }
                    };
                    channel.BasicConsume(queue, true, consumer);
                }
                catch (Exception ex)
                {
                    TLogHelper.Error(ex.Message, "接收消息队列异常Receive");
                }
            }
    
            /// <summary>
            /// 取消接收
            /// </summary>
            public void EndReceive()
            {
                IsReceive=false;
                channel.Dispose();
                connection.Dispose();
            }
        }
    }
    View Code

    消息格式RabbitMQMsgModel

    namespace MQServer
    {
        public class RabbitMQMsgModel
        {
            /// <summary>
            /// 业务名
            /// </summary>
            public string BLLName { get; set; }
    
            /// <summary>
            /// 业务数据
            /// </summary>
            public object Data { get; set; }
        }
    }
    View Code

    2、BLL实现消息业务

    BaseMQBLL

    using System;
    
    namespace MQServer
    {
        /// <summary>
        /// 使用队列业务基类
        /// </summary>
        public abstract class BaseMQBLL : IDisposable
        {
            public bool IsReceive { get { return MQ.IsReceive; } }
    
            protected readonly RabbitMQServerT MQ;
    
            private BaseMQBLL(){ }
    
            protected BaseMQBLL(string queue,object _penetrate) 
            {
                
                MQ = new MQServer.RabbitMQServerT((string source, object o) => {
                    try
                    {
                        ReceiveBack(source, _penetrate);
                        ////test
                        //throw new Exception("测试消息异常");
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }, queue, _penetrate: null);
            }
            /// <summary>
            /// 开启接收
            /// </summary>
            public void Receive()
            {
                MQ.Receive();
            }
    
            /// <summary>
            /// 关闭接收
            /// </summary>
            public void EndReceive()
            {
                MQ.EndReceive();
            }
    
            /// <summary>
            /// 声明必须重写的接收回调
            /// </summary>
            /// <param name="source"></param>
            /// <param name="receiveO"></param>
            protected abstract void ReceiveBack(string source, object receiveO);
    
            public void Dispose() 
            {
                EndReceive();
            }
        }
    }
    View Code

    MQTestHello: BaseMQBLL

    using MQServer;
    using Newtonsoft.Json;
    
    namespace BLL
    {
        public class MQTestHello : BaseMQBLL
        {
            public MQTestHello()
                : base("hello", null)
            {
            }
    
            /// <summary>
            /// 重写接收回调
            /// </summary>
            /// <param name="source"></param>
            /// <param name="receiveO"></param>
            protected override void ReceiveBack(string source, object receiveO)
            {
                //解析source,根据source中的BLLName方法名,执行不同业务
                RabbitMQMsgModel model = JsonConvert.DeserializeObject<RabbitMQMsgModel>(source);
    
                switch (model.BLLName)
                {
                    case "Hello":
                        Hello(model.Data);
                        break;
                    default:
                        break;
                }
            }
    
            /// <summary>
            /// 发送Hello消息
            /// </summary>
            public void SendHello(string msg)
            {
                MQ.Send(new RabbitMQMsgModel() { BLLName = "Hello", Data = msg });
            }
    
            /// <summary>
            /// 接收到Hello消息回调
            /// </summary>
            /// <param name="data"></param>
            public void Hello(object data)
            {
                TLogHelper.Info(JsonConvert.SerializeObject(data), "读取消息在MQTestHello");
            }
        }
    }
    View Code

    3、记录日志

    TLogHelper

    using Newtonsoft.Json;
    using System;
    using System.IO;
    using System.Messaging;
    using System.Text;
    
    namespace MQServer.Log
    {
        public class TLogHelper
        {
            public static object _lock = new object();
            public static void MQ(Message myMessage,  string detail = "") 
            {
                string msg = JsonConvert.SerializeObject(myMessage.Body);
    
                Write(msg, detail, "MessageQueue");
            }
    
            public static void Info(string msg, string detail = "")
            {
                Write(msg, detail, "Info");
            }
            public static void Info(object msg, string detail = "")
            {
                Write(JsonConvert.SerializeObject(msg), detail, "Info");
            }
    
            public static void Error(string msg, string detail = "")
            {
                Write(msg, detail, "Error");
            }
    
            private static void Write(string msg,string detail="", string title = "Info") 
            {
                DateTime now = DateTime.Now;
                string logPath = System.Configuration.ConfigurationManager.AppSettings["MQServerTLogPath"];
    
                if (!Directory.Exists(logPath))
                {
                    Directory.CreateDirectory(logPath);
                }
    
                logPath += now.ToString("yyyyMMdd") + ".txt";
                lock (_lock)
                {
                    FileStream fs = new FileStream(@logPath, FileMode.OpenOrCreate, FileAccess.Write);
    
                    StreamWriter m_streamWriter = new StreamWriter(fs);
    
                    m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
    
                    m_streamWriter.WriteLine();
                    m_streamWriter.WriteLine(now.ToString("yyyyMMddHHmmssfff") + " " + title);
                    if (!string.IsNullOrWhiteSpace(detail))
                    {
                        m_streamWriter.WriteLine(detail);
                    }
    
                    m_streamWriter.WriteLine(msg);
    
                    m_streamWriter.Flush();
    
                    m_streamWriter.Close();
    
                    fs.Close();
                }
                
    
            }
    
            public static string Read() 
            {
                string res = "";
                string logPath = System.Configuration.ConfigurationManager.AppSettings["MQServerTLogPath"];
                
                logPath += DateTime.Now.ToString("yyyyMMdd") + ".txt";
                lock (_lock)
                {
                    StreamReader fs = new StreamReader(@logPath, Encoding.UTF8);
                    res = fs.ReadToEnd();
                    fs.Dispose();
                }
                return res;
            }
        }
    }
    View Code

    4、Form窗体测试

     RabbitMQForm : Form

    using BLL;
    using Newtonsoft.Json;
    using System;
    using System.Windows.Forms;
    
    namespace WinFormActiveMQ
    {
        public partial class RabbitMQForm : Form
        {
            static MQTestHello hello;
            static TCPTestHello tcpHello;
            static TCPTestHello tcpHello2;
            private Label la_main;
            private Timer tim;
            private System.Threading.Thread thrListener;
            private System.Threading.Thread thrListener2;
            public RabbitMQForm()
            {
                InitializeComponent();
    
                la_main = new Label();
                la_main.Name = "la_main";
                la_main.Width = 282;
                la_main.TabIndex = 0;
                Controls.Add(la_main);
    
                tim = new Timer();
                tim.Interval = 1000;
                tim.Tick += CheckReceive;
                tim.Start();
    
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                textBox1.ScrollBars = ScrollBars.Vertical;
                la_main.Text = "RabbitMQ消息队列,点击开启接收。";
                TCPIp1.Text = "127.0.0.1";
                TCPPort1.Text = "90";
                TCPIp2.Text = "127.0.0.1";
                TCPPort2.Text = "91";
    
                hello = new MQTestHello(); 
            }
    
            /// <summary>
            /// 守护线程
            /// 检测接收线程是否还在,不在了重新接收
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void CheckReceive(object sender, EventArgs e)
            {
                //测试Hello队列
                if (TestHello.Checked)
                {
                    if (hello!=null && !hello.IsReceive)
                    {
                        hello.Receive();
                    }
                }
    
                if (TCPHello.Checked)
                {
                    if (tcpHello != null && !tcpHello.IsListening)
                    {
                        thrListener = tcpHello.ListenStart(ListenClientBack);
                    }
                }
                
                if (TCPListen2.Checked)
                {
                    if (tcpHello2 != null && !tcpHello2.IsListening)
                    {
                        thrListener2 = tcpHello2.ListenStart(ListenClientBack);
                    }
                }
    
            }
    
            /// <summary>
            /// 开启接收Hello队列,并发送一条测试消息
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void TestHello_CheckedChanged(object sender, EventArgs e)
            {
                if (TestHello.Checked)
                {
                    //开启接收
                    if (!hello.IsReceive)
                    {
                        hello.Receive();
                    }
    
                    //测试发送
                    hello.SendHello("测试第一消息");
                }
                else
                {
                    //关闭接收
                    hello.EndReceive();
                }
            }
    
            /// <summary>
            /// 开启接收TCP请求,hello业务的
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void TCPHello_CheckedChanged(object sender, EventArgs e)
            {
                //设置ip端口输入
                TCPIp1.Enabled = !TCPHello.Checked;
                TCPPort1.Enabled = !TCPHello.Checked;
    
                if (TCPHello.Checked)
                {
                    int port = 0;
                    try
                    {
                        port = int.Parse(TCPPort1.Text);
                    }
                    catch (Exception)
                    {
                        TCPHello.Checked = !TCPHello.Checked;
                        TCPIp1.Enabled = !TCPHello.Checked;
                        TCPPort1.Enabled = !TCPHello.Checked;
                        MessageBox.Show("请输入正确端口号");
                        return;
                    }
    
                    tcpHello = new TCPTestHello(TCPIp1.Text, port, "", port);
                    ///开启监听
                    thrListener = tcpHello.ListenStart(ListenClientBack);
                }
                else
                {
                    //关闭监听
                    tcpHello.CloseListen();
                }
            }
    
            /// <summary>
            /// 收到终端的TCP请求后回调显示
            /// </summary>
            private string ListenClientBack(object obj)
            {
                if (obj == null) 
                {
                    //监听执行回调出错
                    changeListenText("
      监听执行回调出错");
    
                    //用选择框改变事件关闭监听
                    TCPHello_CheckedChanged(null,null);
                    return "";
                }
    
                string res = JsonConvert.SerializeObject(obj);
                changeListenText("
    收到终端的请求在Form:" + res);
                return res;
            }
    
            //修改主线程文本框值
            private delegate void SetTextCallback(string sssext);
            /// <summary>
            /// 修改主线程文本框值
            /// </summary>
            /// <param name="text"></param>
            private void changeListenText(string text)
            {
                if (this.textBox1.InvokeRequired)   //InvokeRequired会比较调用线程ID和创建线程ID
                {   //如果它们不相同则返回true
                    SetTextCallback sss = new SetTextCallback(changeListenText);//类似于重载,调用自己
                    this.Invoke(sss, new object[] { text });
                }
                else
                {
                    this.textBox1.Text = text + this.textBox1.Text;
                }
            }
    
            /// <summary>
            /// 测试发送TCP请求
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void TestRequestTcp_Click(object sender, EventArgs e)
            {
                try
                {
                    if (tcpHello == null) 
                    {
                        MessageBox.Show("请先打开监听");
                        return;
                    }
                    tcpHello.SendHello("测试发送TCP请求:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
                }
                catch (Exception)
                {
                }
            }
    
            /// <summary>
            /// 监听2
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void TCPListen2_CheckedChanged(object sender, EventArgs e)
            {
    
                //设置ip端口输入
                TCPIp2.Enabled = !TCPListen2.Checked;
                TCPPort2.Enabled = !TCPListen2.Checked;
    
                if (TCPListen2.Checked)
                {
                    int port = 0;
                    try
                    {
                        port = int.Parse(TCPPort2.Text);
                    }
                    catch (Exception)
                    {
                        TCPListen2.Checked = !TCPListen2.Checked;
                        TCPIp2.Enabled = !TCPListen2.Checked;
                        TCPPort2.Enabled = !TCPListen2.Checked;
                        MessageBox.Show("请输入正确端口号");
                        return;
                    }
    
                    ///开启监听2 
                    tcpHello2 = new TCPTestHello(TCPIp2.Text, port, "", port);
                    thrListener2 = tcpHello2.ListenStart(ListenClientBack2);
                     
                }
                else
                {
                    tcpHello2.CloseListen();
                }
            }
    
            /// <summary>
            /// 收到终端的TCP请求后回调显示2
            /// </summary>
            private string ListenClientBack2(object obj)
            {
                if (obj == null)
                {
                    //监听执行回调出错
                    changeListenText("
    监听2执行回调出错");
    
                    //用选择框改变事件关闭监听
                    TCPListen2_CheckedChanged(null, null);
                    return "";
                }
    
                string res = JsonConvert.SerializeObject(obj);
                changeListenText("
    收到终端2的请求在Form:" + res);
                return res;
            }
    
            private void SentTCP2_Click(object sender, EventArgs e)
            {
                try
                {
                    if (tcpHello2 == null)
                    {
                        MessageBox.Show("请先打开监听2");
                        return;
                    }
                    tcpHello2.SendHello("测试发送TCP请求222:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
                }
                catch (Exception)
                {
                }
            }
        }
    }
    View Code

    RabbitMQForm

    namespace WinFormActiveMQ
    {
        partial class RabbitMQForm
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.TestHello = new System.Windows.Forms.CheckBox();
                this.TCPHello = new System.Windows.Forms.CheckBox();
                this.textBox1 = new System.Windows.Forms.TextBox();
                this.TestRequestTcp = new System.Windows.Forms.Button();
                this.TCPListen2 = new System.Windows.Forms.CheckBox();
                this.TCPIp1 = new System.Windows.Forms.TextBox();
                this.label1 = new System.Windows.Forms.Label();
                this.TCPPort1 = new System.Windows.Forms.TextBox();
                this.label2 = new System.Windows.Forms.Label();
                this.TCPIp2 = new System.Windows.Forms.TextBox();
                this.TCPPort2 = new System.Windows.Forms.TextBox();
                this.SentTCP2 = new System.Windows.Forms.Button();
                this.SuspendLayout();
                // 
                // TestHello
                // 
                this.TestHello.AutoSize = true;
                this.TestHello.Location = new System.Drawing.Point(12, 12);
                this.TestHello.Name = "TestHello";
                this.TestHello.Size = new System.Drawing.Size(129, 19);
                this.TestHello.TabIndex = 0;
                this.TestHello.Text = "接收队列Hello";
                this.TestHello.UseVisualStyleBackColor = true;
                this.TestHello.CheckedChanged += new System.EventHandler(this.TestHello_CheckedChanged);
                // 
                // TCPHello
                // 
                this.TCPHello.AutoSize = true;
                this.TCPHello.Location = new System.Drawing.Point(216, 77);
                this.TCPHello.Name = "TCPHello";
                this.TCPHello.Size = new System.Drawing.Size(123, 19);
                this.TCPHello.TabIndex = 1;
                this.TCPHello.Text = "监听TCPHello";
                this.TCPHello.UseVisualStyleBackColor = true;
                this.TCPHello.CheckedChanged += new System.EventHandler(this.TCPHello_CheckedChanged);
                // 
                // textBox1
                // 
                this.textBox1.Location = new System.Drawing.Point(13, 248);
                this.textBox1.Multiline = true;
                this.textBox1.Name = "textBox1";
                this.textBox1.Size = new System.Drawing.Size(427, 160);
                this.textBox1.TabIndex = 2;
                // 
                // TestRequestTcp
                // 
                this.TestRequestTcp.Location = new System.Drawing.Point(345, 73);
                this.TestRequestTcp.Name = "TestRequestTcp";
                this.TestRequestTcp.Size = new System.Drawing.Size(122, 23);
                this.TestRequestTcp.TabIndex = 3;
                this.TestRequestTcp.Text = "发送TCP请求";
                this.TestRequestTcp.UseVisualStyleBackColor = true;
                this.TestRequestTcp.Click += new System.EventHandler(this.TestRequestTcp_Click);
                // 
                // TCPListen2
                // 
                this.TCPListen2.AutoSize = true;
                this.TCPListen2.Location = new System.Drawing.Point(216, 106);
                this.TCPListen2.Name = "TCPListen2";
                this.TCPListen2.Size = new System.Drawing.Size(67, 19);
                this.TCPListen2.TabIndex = 4;
                this.TCPListen2.Text = "监听2";
                this.TCPListen2.UseVisualStyleBackColor = true;
                this.TCPListen2.CheckedChanged += new System.EventHandler(this.TCPListen2_CheckedChanged);
                // 
                // TCPIp1
                // 
                this.TCPIp1.Location = new System.Drawing.Point(13, 75);
                this.TCPIp1.Name = "TCPIp1";
                this.TCPIp1.Size = new System.Drawing.Size(114, 25);
                this.TCPIp1.TabIndex = 5;
                // 
                // label1
                // 
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(12, 57);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(53, 15);
                this.label1.TabIndex = 6;
                this.label1.Text = "请求ip";
                // 
                // TCPPort1
                // 
                this.TCPPort1.Location = new System.Drawing.Point(144, 74);
                this.TCPPort1.Name = "TCPPort1";
                this.TCPPort1.Size = new System.Drawing.Size(66, 25);
                this.TCPPort1.TabIndex = 7;
                // 
                // label2
                // 
                this.label2.AutoSize = true;
                this.label2.Location = new System.Drawing.Point(141, 56);
                this.label2.Name = "label2";
                this.label2.Size = new System.Drawing.Size(112, 15);
                this.label2.TabIndex = 8;
                this.label2.Text = "请求和监听端口";
                // 
                // TCPIp2
                // 
                this.TCPIp2.Location = new System.Drawing.Point(12, 106);
                this.TCPIp2.Name = "TCPIp2";
                this.TCPIp2.Size = new System.Drawing.Size(114, 25);
                this.TCPIp2.TabIndex = 9;
                // 
                // TCPPort2
                // 
                this.TCPPort2.Location = new System.Drawing.Point(144, 106);
                this.TCPPort2.Name = "TCPPort2";
                this.TCPPort2.Size = new System.Drawing.Size(66, 25);
                this.TCPPort2.TabIndex = 10;
                // 
                // SentTCP2
                // 
                this.SentTCP2.Location = new System.Drawing.Point(345, 108);
                this.SentTCP2.Name = "SentTCP2";
                this.SentTCP2.Size = new System.Drawing.Size(122, 23);
                this.SentTCP2.TabIndex = 11;
                this.SentTCP2.Text = "SentTCP2";
                this.SentTCP2.UseVisualStyleBackColor = true;
                this.SentTCP2.Click += new System.EventHandler(this.SentTCP2_Click);
                // 
                // RabbitMQForm
                // 
                this.ClientSize = new System.Drawing.Size(498, 417);
                this.Controls.Add(this.SentTCP2);
                this.Controls.Add(this.TCPPort2);
                this.Controls.Add(this.TCPIp2);
                this.Controls.Add(this.label2);
                this.Controls.Add(this.TCPPort1);
                this.Controls.Add(this.label1);
                this.Controls.Add(this.TCPIp1);
                this.Controls.Add(this.TCPListen2);
                this.Controls.Add(this.TestRequestTcp);
                this.Controls.Add(this.textBox1);
                this.Controls.Add(this.TCPHello);
                this.Controls.Add(this.TestHello);
                this.Name = "RabbitMQForm";
                this.Text = "RabbitMQForm";
                this.Load += new System.EventHandler(this.Form1_Load);
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
    
            #endregion
    
            private System.Windows.Forms.CheckBox TestHello;
            private System.Windows.Forms.CheckBox TCPHello;
            private System.Windows.Forms.TextBox textBox1;
            private System.Windows.Forms.Button TestRequestTcp;
            private System.Windows.Forms.CheckBox TCPListen2;
            private System.Windows.Forms.TextBox TCPIp1;
            private System.Windows.Forms.Label label1;
            private System.Windows.Forms.TextBox TCPPort1;
            private System.Windows.Forms.Label label2;
            private System.Windows.Forms.TextBox TCPIp2;
            private System.Windows.Forms.TextBox TCPPort2;
            private System.Windows.Forms.Button SentTCP2;
        }
    }
    View Code

    5、默认配置

      <appSettings>
        <add key="MQServerTLogPath" value="d:/WinFormActiveMQLog/" />
        <add key="RabbitMQHostName" value="192.168.0.233" />
        <add key="RabbitMQUserName" value="admin" />
        <add key="RabbitMQPassword" value="123456" />
        <add key="RabbitMQPort" value="5672" />
        <add key="RabbitMQVirtualHost" value="" />
        <add key="RabbitMQ_durable" value="true" />
        <add key="RabbitMQ_exclusive" value="false" />
        <add key="RabbitMQ_autoDelete" value="false" />
      </appSettings>

    TCP监听demo

    6、TCP监听类

    using MQServer;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TCPServer
    {
        public class TCPServerT
        {
    
            /// <summary>
            /// 声明监听回调委托类型
            /// </summary>
            /// <param name="s"></param>
            /// <returns></returns>
            public delegate object ListenBackDelegate(object s);
    
            /// <summary>
            /// 监听状态
            /// </summary>
            public bool IsListening = false;
    
            static Dictionary<string, TCPServerT> tcps;//ip加端口唯一
            string ip; 
            int port;
            private TcpClient tcpClient;
            private Socket listener;
            private TCPServerT()
            {
            }
            private TCPServerT(string ip, int port) 
            {
                this.ip = ip;
                this.port = port;
            }
    
            /// <summary>
            /// 得到TCP服务实例
            /// </summary>
            /// <param name="ip"></param>
            /// <param name="port"></param>
            /// <returns></returns>
            public static TCPServerT Instance(string ip, int port) 
            {
                if (tcps == null) 
                {
                    tcps = new Dictionary<string, TCPServerT>();
                }
                string key = ip + port;
                if (tcps.Keys.Contains(key))
                {
                    return tcps[key];
                }
                else 
                {
                    TCPServerT nowTcpSetvice = new TCPServerT(ip, port);
                    tcps.Add(key, nowTcpSetvice);
                    return nowTcpSetvice;
                }
            }
    
            /// <summary>
            /// 发送TCP消息
            /// </summary>
            /// <param name="data"></param>
            public void Request(string data)
            {
                tcpClient = new TcpClient();
                tcpClient.Connect(IPAddress.Parse(ip), port);
                NetworkStream ntwStream = tcpClient.GetStream();
                if (ntwStream.CanWrite)
                {
                    Byte[] bytSend = Encoding.UTF8.GetBytes(data);
                    ntwStream.Write(bytSend, 0, bytSend.Length);
                }
                else
                {
                    ntwStream.Close();
                    tcpClient.Close();
                    throw new Exception("无法写入互数据流");
                }
                ntwStream.Close();
                tcpClient.Close();
            }
            /// <summary>
            /// 发送TCP消息
            /// </summary>
            /// <param name="data"></param>
            public void Request(TCPServiceMsgModel model)
            {
                Request(JsonConvert.SerializeObject(model));
            }
    
            /// <summary>
            /// 监听数据开始
            /// </summary>
            /// <param name="back">两个监听回调都会执行</param>
            /// <param name="back2">正常时调用back2(obj),失败时调用back2(null)</param>
            public void Listen(ListenBackDelegate back, ListenBackDelegate back2=null)
            {
                if (IsListening) 
                {
                    throw new Exception("端口"+ port +"已处于监听状态,线程中只能存在一个Ip端口连接。");
                }
    
                IsListening = true;
                listener = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);
    
                IPAddress ipAddress;
                if (string.IsNullOrWhiteSpace(ip))
                {
                    ipAddress = IPAddress.Any;
                }
                else 
                {
                    ipAddress = IPAddress.Parse(ip);
                }
    
                listener.Bind(new IPEndPoint(ipAddress, port));
    
                //不断监听端口
                while (IsListening)
                {
                    try
                    {
                        listener.Listen(0);
                        Socket socket = listener.Accept();
                        NetworkStream ntwStream = new NetworkStream(socket);
                        StreamReader strmReader = new StreamReader(ntwStream);
                        var objs = new object[] { strmReader.ReadToEnd() };
                        try
                        {
                            back.Invoke(objs);
                            if (back2 != null)
                            {
                                back2.Invoke(objs);
                            }
                        }
                        catch (Exception ex)
                        {
                            //回调失败时,执行back2传空,判断为空处理回调失败
                            if (back2 != null)
                            {
                                back2.Invoke(null);
                            }
    
                            TLogHelper.Error(ex.Message, "回调失败");
    
                            ////执行失败时是否终止监听
                            //CloseListen();
                            throw ex;
                        }
                        finally 
                        {
                            socket.Close();
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
                CloseListen();
            }
    
            /// <summary>
            /// 关闭监听
            /// </summary>
            public void CloseListen ()
            {
                if (listener != null)
                {
                    try
                    {
                        listener.Shutdown(SocketShutdown.Both);
                    }
                    catch (Exception)
                    {
                    }
                    listener.Dispose();
                    listener.Close();
                }
                IsListening = false;
            }
        }
    }
    View Code

    数据格式类

    namespace TCPServer
    {
        public class TCPServiceMsgModel
        {
            /// <summary>
            /// 业务名
            /// </summary>
            public string BLLName { get; set; }
    
            /// <summary>
            /// 业务数据
            /// </summary>
            public object Data { get; set; }
        }
    }
    View Code

    7、BLL业务

    BaseTCPBLL

    using System;
    using System.Threading;
    namespace TCPServer
    {
        public abstract class BaseTCPBLL: IDisposable
        {
            public bool IsListening
            {
                get
                {
                    if (tcp == null)
                    {
                        return false;
                    }
                    return tcp.IsListening;
                }
            }
    
            private TCPServerT tcp;
            private TCPServerT tcpSend;
            private TCPServerT.ListenBackDelegate back2;//启动监听动作的线程的回调,由启动监听方法传入
            private Thread thrListener;
            private BaseTCPBLL(){}
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="requestIp">请求ip</param>
            /// <param name="requestPort">请求端口</param>
            /// <param name="listenIp">监听ip</param>
            /// <param name="listenPort">监听端口</param>
            protected BaseTCPBLL(string requestIp,int requestPort, string listenIp,int listenPort)
            {
                //实例化Tcp服务
                tcp = TCPServerT.Instance(listenIp, listenPort);
                tcpSend = TCPServerT.Instance(requestIp, requestPort);
            }
            #region  TCP服务
            /// <summary>
            /// 开始监听客户请求处理业务
            /// ,正常时调用back2(obj),失败时调用back2(null)
            /// </summary>
            public Thread ListenStart(TCPServerT.ListenBackDelegate back2 = null)
            {
                if (IsListening) 
                {
                    return thrListener;
                }
    
                this.back2 = back2;
                thrListener = new Thread(new ThreadStart(Listen));
                thrListener.Start();
    
                return thrListener;
            }
    
            /// <summary>
            /// 监听执行
            /// </summary>
            private void Listen()
            {
                tcp.Listen(ListenClientBack, back2);
            }
    
            /// <summary>
            /// 关闭监听
            /// </summary>
            public void CloseListen()
            {
                tcp.CloseListen();
            }
    
            /// <summary>
            /// 收到终端的请求后回调
            /// </summary>
            protected abstract string ListenClientBack(object obj);
            #endregion
    
            /// <summary>
            /// 发送请求
            /// </summary>
            protected void Request(TCPServiceMsgModel model)
            {
                tcpSend.Request(model);
            }
    
            public void Dispose() 
            {
                tcp.CloseListen();
                tcpSend.CloseListen();
            }
        }
    }
    View Code

    TCPTestHello:BaseTCPBLL

    using MQServer;
    using Newtonsoft.Json;
    using TCPServer;
    
    namespace BLL
    {
        public class TCPTestHello:BaseTCPBLL
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="requestIp">请求ip,本机"127.0.0.1"</param>
            /// <param name="requestPort">请求端口</param>
            /// <param name="listenIp">监听ip,本机""</param>
            /// <param name="listenPort">监听端口</param>
            public TCPTestHello(string requestIp, int requestPort, string listenIp, int listenPort)
                :base(requestIp, requestPort, listenIp, listenPort)
            {
            }
            #region  TCP服务 
    
            /// <summary>
            /// 收到终端的请求后回调
            /// </summary>
            protected override string ListenClientBack(object obj)
            {
                var res = JsonConvert.SerializeObject(obj);
                //解析source,根据source中的BLLName方法名,执行不同业务
    
                TCPServiceMsgModel model;
                try
                {
                    res = JsonConvert.DeserializeObject<string[]>(res)[0];
                    model = JsonConvert.DeserializeObject<TCPServiceMsgModel>(res);
                }
                catch (System.Exception)
                {
                    throw new System.Exception("TCP接收到对象不是本模块接受的格式!"+ res);
                }
    
                switch (model.BLLName)
                {
                    case "Hello":
                        Hello(model.Data);
                        break;
                    default:
                        break;
                }
                return res;
            }
            #endregion
    
            /// <summary>
            /// 发送Hello请求
            /// </summary>
            public void SendHello(object data)
            {
                Request(new TCPServiceMsgModel() { BLLName = "Hello", Data = data });
            }
    
            public void Hello(object data)
            {
                TLogHelper.Info(JsonConvert.SerializeObject(data), "接收到消息在TCPTestHello");
            }
    
        }
    }
    View Code
  • 相关阅读:
    JS调试工具
    什么是Web Service?
    win7怎么安装消息队列 MSMQ
    死锁产生的原因及四个必要条件
    项目管理模式之如何去除SVN标记
    AJAX中的请求方式以及同步异步的区别
    敏捷软件开发模型--SCRUM
    堆和栈
    UI产品设计流程中的14个要点
    Android中dp和px之间进行转换
  • 原文地址:https://www.cnblogs.com/lanofsky/p/13814269.html
Copyright © 2020-2023  润新知