C# 使用TIBCO中间件通信
一、环境
Tibco Rendezvous 版本 8.4
.net版本 .Net Framework 4.5.2
visual sutido 2022
二、案例演示
三、Form界面类主要代码
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Windows.Forms;
using TIBCO.Rendezvous;
namespace CSharpeDemo.Demo_TibcoRV
{
public partial class Frm_TibcoRV : Form
{
TibcoRVTHelper tibcoRVTHelper;
public Frm_TibcoRV()
{
InitializeComponent();
this.MinimumSize = new System.Drawing.Size(750, 650);
}
private void Frm_TibcoRV_Load(object sender, EventArgs e)
{
ControlStyleUpdata( picBx_ConnectStatu, Color.Gray);
ControlStyleUpdata(picBx_ListenStatu, Color.Gray);
btn_ListenOpen.Enabled = false;
}
#region 事件
/// <summary>
/// 连接按钮
/// </summary>
private void btn_Connect_Click(object sender, EventArgs e)
{
bool isStartConnect = btn_Connect.Text.Equals("连接")?true:false;
//开始连接
if (isStartConnect)
{
tibcoRVTHelper = new TibcoRVTHelper(tbx_Server.Text, tbx_Network.Text, tbx_Daemon.Text,tbx_ListenSubject.Text,tbx_TargetSubject.Text);
tibcoRVTHelper.MessageField = tbx_MessageField.Text;
tibcoRVTHelper.messageReceivedHandler += OnMessageReceived;
tibcoRVTHelper.ListenedStatusHandler += OnListened;
tibcoRVTHelper.ConnectedStatusHandler += OnConnected;
tibcoRVTHelper.ErrorMessageHandler += TibcoRVTHelper_ErrorMessageHandler;
tibcoRVTHelper.StartConnect();
}
//断开连接
else
{
tibcoRVTHelper.DisConnected();
ControlStyleUpdata(picBx_ConnectStatu, Color.Gray);
ControlStyleUpdata(picBx_ListenStatu, Color.Gray);
btn_Connect.Text = tibcoRVTHelper.IsConnected ? "断开" : "连接";
ControlUpdata(true);
}
}
private void TibcoRVTHelper_ErrorMessageHandler(object sender, string message)
{
MessageShow(message);
}
/// <summary>
/// 侦听按钮
/// </summary>
private void btn_ListenOpen_Click(object sender, EventArgs e)
{
//正在连接,可以侦听
if (tibcoRVTHelper.IsConnected)
{
tibcoRVTHelper.TargetSubject = tbx_TargetSubject.Text;
tibcoRVTHelper.ListenSubject = tbx_ListenSubject.Text;
}
//未连接,不允许侦听
else
{
tibcoRVTHelper.messageReceivedHandler -= OnMessageReceived;
}
btn_ListenOpen.Text = tibcoRVTHelper.IsListened ? "停止" : "侦听";
ControlStyleUpdata(picBx_ListenStatu, tibcoRVTHelper.IsListened? Color.LimeGreen: Color.Gray);
}
/// <summary>
/// 发送按钮
/// </summary>
private void btn_SendData_Click(object sender, EventArgs e)
{
if (tibcoRVTHelper.IsConnected)
{
//tibcoRVTHelper.MessageField = "xmlData";
tibcoRVTHelper.Send(rtbx_SendData.Text);
}
}
/// <summary>
/// 客户端、服务端
/// </summary>
private void checkBox_IsClient_CheckedChanged(object sender, EventArgs e)
{
if (tibcoRVTHelper == null ||!tibcoRVTHelper.IsConnected)
{
string temp = tbx_ListenSubject.Text;
tbx_ListenSubject.Text = tbx_TargetSubject.Text;
tbx_TargetSubject.Text = temp;
}
}
#endregion
#region 委托方法
/// <summary>
/// 委托方法:消息接收
/// </summary>
public void OnMessageReceived(object sender, MessageReceivedEventArgs messageReceivedEventArgs)
{
TIBCO.Rendezvous.Message message = messageReceivedEventArgs.Message;
string receiveData = message.GetFieldByIndex(0);
string fieldName = message.GetFieldByIndex(0).Name;
MessageShow($"send subject = {message.SendSubject}\r\n field name = {fieldName}\r\n{receiveData}");
}
/// <summary>
/// 消息显示到控件
/// </summary>
public void MessageShow(string data)
{
rtbx_ReceiveData.Invoke(new Action(() =>
{
rtbx_ReceiveData.AppendText($"{DateTime.Now}】{data}{System.Environment.NewLine}");
}));
}
private void OnListened(object sender,bool listened)
{
btn_ListenOpen.Invoke(new Action(() =>
{
btn_ListenOpen.Text = listened ? "停止" : "侦听";
ControlStyleUpdata(picBx_ListenStatu, listened ? Color.LimeGreen : Color.Gray);
}));
}
private void OnConnected(object sender, bool connected)
{
btn_Connect.Invoke(new Action(() =>
{
btn_Connect.Text = connected ? "断开" : "连接";
ControlStyleUpdata(picBx_ConnectStatu, connected ? Color.LimeGreen : Color.Gray);
bool isConnected = tibcoRVTHelper.IsConnected;
if (isConnected) //连接成功
{
ControlStyleUpdata(picBx_ConnectStatu, Color.LimeGreen);
if (tibcoRVTHelper.IsListened)
{
ControlStyleUpdata(picBx_ListenStatu, Color.LimeGreen);
ControlUpdata(false);
}
btn_Connect.Text = isConnected ? "断开" : "连接";
}
else //连接失败
{
ControlStyleUpdata(picBx_ConnectStatu, Color.Gray);
ControlStyleUpdata(picBx_ListenStatu, Color.Gray);
btn_Connect.Text = isConnected ? "断开" : "连接";
ControlUpdata(true);
}
}));
}
#endregion
#region 控件圆角
#region 控件圆角方法1
public void ControlStyleUpdata(Control control)
{
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(control.ClientRectangle);
Region region = new Region(gp);
control.Region = region;
gp.Dispose();
region.Dispose();
}
public void ControlStyleUpdata(Control control, Color bcColor)
{
control.BackColor = bcColor;
ControlStyleUpdata(control);
}
#endregion
#region 控件圆角方法2
/// <summary>
/// 按钮控件圆角绘制绑定事件
/// </summary>
private void button_Paint(object sender, PaintEventArgs e)
{
Button button = (Button)sender;
Draw(e.ClipRectangle, e.Graphics, 12, false, Color.FromArgb(0, 122, 204), Color.FromArgb(8, 39, 57));
base.OnPaint(e);
Graphics g = e.Graphics;
g.DrawString(button.Text, new Font("微软雅黑", 12, FontStyle.Regular), new SolidBrush(Color.White), new PointF(15, 0));
}
/// <summary>
/// 绘制圆角
/// </summary>
private void Draw(Rectangle rectangle, Graphics g, int _radius, bool cusp, Color begin_color, Color end_color)
{
int span = 2;
//抗锯齿
g.SmoothingMode = SmoothingMode.AntiAlias;
//渐变填充
LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush(rectangle, begin_color, end_color, LinearGradientMode.Vertical);
//画尖角
if (cusp)
{
span = 10;
PointF p1 = new PointF(rectangle.Width - 12, rectangle.Y + 10);
PointF p2 = new PointF(rectangle.Width - 12, rectangle.Y + 30);
PointF p3 = new PointF(rectangle.Width, rectangle.Y + 20);
PointF[] ptsArray = { p1, p2, p3 };
g.FillPolygon(myLinearGradientBrush, ptsArray);
}
//填充
g.FillPath(myLinearGradientBrush, DrawRoundRect(rectangle.X, rectangle.Y, rectangle.Width - span, rectangle.Height - 1, _radius));
}
/// <summary>
/// 设置圆角
/// </summary>
public static GraphicsPath DrawRoundRect(int x, int y, int width, int height, int radius)
{
//四边圆角
GraphicsPath gp = new GraphicsPath();
gp.AddArc(x, y, radius, radius, 180, 90);
gp.AddArc(width - radius, y, radius, radius, 270, 90);
gp.AddArc(width - radius, height - radius, radius, radius, 0, 90);
gp.AddArc(x, height - radius, radius, radius, 90, 90);
gp.CloseAllFigures();
return gp;
}
#endregion
#endregion
#region 其他辅助方法
public void ControlUpdata(bool controlStatus)
{
foreach (Control control in panel_Top.Controls)
{
if (control is TextBox)
{
control.Enabled = controlStatus;
}
}
}
#endregion
private void btn_ClearReceiveData_Click(object sender, EventArgs e)
{
rtbx_ReceiveData.Text = string.Empty;
}
private void btn_ClearSendData_Click(object sender, EventArgs e)
{
rtbx_SendData.Text = string.Empty;
}
}
}
四、辅助类代码
using HslCommunication.Profinet.Panasonic.Helper;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media;
using TIBCO.Rendezvous;
namespace CSharpeDemo.Demo_TibcoRV
{
/*
* 设计思路:
* 连接成功时,触发连接事件:在连接状态事件中执行侦听事件。
* 侦听成功时,触发侦听事件
*/
public class TibcoRVTHelper
{
#region 字段、属性
private string _service; //服务
private string _network; //网络
private string _daemon; //守护进程
private string _messageField; //消息字段
private string _listenSubject; //侦听主题
private string _targetSubject; //目标主题
private bool _isOpen = false; //是否打开环境
private bool _isConnected = false; //是否创建连接
private bool _isListen = false; //是否创建侦听
private string _cmName; //My Name
private Task task = null;
private TIBCO.Rendezvous.NetTransport _transport; //传输对象
private TIBCO.Rendezvous.Listener _listener; //侦听器对象
private TIBCO.Rendezvous.Queue _queue; //消息队列
public bool IsListened { get { return _isListen; } set { _isListen = value; } }
public bool IsOpen { get { return _isConnected; } set { _isConnected = value; } }
public bool IsConnected { get { return _isOpen; } set { _isOpen = value; } }
public string Service { get { return _service; } set { _service = value; } }
public string Network { get { return _network; } set { _network = value; } }
public string Daemon { get { return _daemon; } set { _daemon = value; } }
public string MessageField { get => _messageField; set => _messageField = value; }
public string ListenSubject { get { return _listenSubject; } set { _listenSubject = value; } }
public string TargetSubject { get { return _targetSubject; } set { _targetSubject = value; } }
public string CmName { get => _cmName; set => _cmName = value; }
public TIBCO.Rendezvous.NetTransport Transport { get => _transport; set => _transport = value; }
public TIBCO.Rendezvous.Listener Listener { get => _listener; set => _listener = value; }
public TIBCO.Rendezvous.Queue Queue { get => _queue; set => _queue = value; }
#endregion
#region 构造函数
public TibcoRVTHelper() { }
public TibcoRVTHelper(string server, string network, string daemon)
{
this.Service = server;
this.Network = network;
this.Daemon = daemon;
}
public TibcoRVTHelper(string server, string network, string daemon, string listenSubject, string targetSubject)
{
this.Service = server;
this.Network = network;
this.Daemon = daemon;
this.ListenSubject = listenSubject;
this.TargetSubject = targetSubject;
this.ConnectedStatusHandler += OnConnectCallBack;
}
#endregion
#region 连接
/// <summary>
/// 打开环境
/// </summary>
public bool Open()
{
try
{
TIBCO.Rendezvous.Environment.Open();
IsOpen = true;
string msg = $"打开环境成功!";
ErrorMessageHandler.Invoke(this, msg);
return IsOpen;
}
catch (Exception ex)
{
IsOpen = false;
return IsOpen;
}
}
/// <summary>
/// 外部连接
/// </summary>
public void StartConnect()
{
Connected();
}
/// <summary>
/// 内部连接
/// </summary>
private bool Connected()
{
if (IsOpen)
{
TryCreateConnect();
}
else
{
Open();
TryCreateConnect();
}
return IsConnected;
}
/// <summary>
/// 尝试创建连接,超时时间3s
/// </summary>
private async void TryCreateConnect()
{
string msg = string.Empty;
try
{
Task createTask = Task.Run(() => CreateConnect());
Task timeoutTask = Task.Delay(3000);
Task completedTask = await Task.WhenAny(createTask, timeoutTask);
if (completedTask == timeoutTask)
{
msg = $"\r\n连接超时...\r\nDaemon = {Daemon},Network = {Network} ,Service = {Service}";
ErrorMessageHandler.Invoke(this, msg);
IsConnected = false;
ConnectedStatusHandler.Invoke(this, false);
return;
}
IsConnected = true;
ConnectedStatusHandler.Invoke(this, true);
}
catch (Exception ex)
{
msg = $"\r\n连接异常...\r\nDaemon = {Daemon},Network = {Network} ,Service = {Service}";
IsConnected = false;
ErrorMessageHandler.Invoke(this, msg);
ConnectedStatusHandler.Invoke(this, false);
}
}
/// <summary>
/// 创建连接的方法
/// </summary>
private void CreateConnect()
{
string msg = string.Empty;
try
{
msg = $"正在连接...: Daemon = {Daemon},Network = {Network},Service = {Service}";
ErrorMessageHandler.Invoke(this, msg);
Transport = new NetTransport(Service, Network, Daemon);
IsConnected = true;
msg = $"连接成功...";
ErrorMessageHandler.Invoke(this, msg);
ConnectedStatusHandler.Invoke(this,true);
}
catch (Exception ex)
{
IsConnected = false;
msg = $"连接失败...";
ErrorMessageHandler.Invoke(this, msg);
ConnectedStatusHandler.Invoke(this, false);
}
}
/// <summary>
/// 断开连接
/// </summary>
public void DisConnected()
{
try
{
if (task!=null)
task = null;
this.Listener.MessageReceived -= OnMessageReceivedCallBack;
if (Listener != null) Listener.Destroy();
Listener = null;
if (Transport != null) Transport.Destroy();
Transport = null;
string msg = $"断开连接... : Daemon = {Daemon} ,Network = {Network},Service = {Service}";
TIBCO.Rendezvous.Environment.Open();
TIBCO.Rendezvous.Environment.Close();
IsListened = false;
IsConnected = false;
IsOpen = false;
ErrorMessageHandler.Invoke(this, msg);
ConnectedStatusHandler.Invoke(this, false);
ListenedStatusHandler.Invoke(this, false);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
#region 侦听
/// <summary>
/// 尝试侦听
/// </summary>
private void TryCreateListen()
{
try
{
if (IsConnected && !IsListened)
{
if (Transport == null)
{
string msg = $"transport 为空,未连接,请先连接!!!";
ErrorMessageHandler.Invoke(this, msg);
ListenedStatusHandler.Invoke(this,false);
IsListened = false;
return;
}
Queue = new TIBCO.Rendezvous.Queue();
Listener = new Listener(Queue, Transport, ListenSubject, null);
this.Listener.MessageReceived += OnMessageReceivedCallBack;
IsListened = true;
ListenedStatusHandler.Invoke(this,true);
}
}
catch (Exception ex)
{
IsListened = false;
string msg = $"侦听异常:{ex.Message}";
ErrorMessageHandler.Invoke(this, msg);
ListenedStatusHandler.Invoke(this, false);
}
}
/// <summary>
/// 内部侦听
/// </summary>
private void Listen()
{
try
{
string msg = $"开始侦听...";
ErrorMessageHandler.Invoke(this, msg);
if (!this.IsListened)
{
TryCreateListen();
if (this.IsListened)
{
task = new Task(() =>
{
while (this.IsListened)
{
Queue.Dispatch();
}
});
task.Start();
msg = $"侦听成功!!!";
ErrorMessageHandler.Invoke(this, msg);
}
}
}
catch (Exception ex)
{
this.IsListened = false;
string msg = $"侦听异常:{ex.Message}";
ErrorMessageHandler.Invoke(this, msg);
}
}
#endregion
#region 发送
public void Send(string data)
{
TIBCO.Rendezvous.Message message = new TIBCO.Rendezvous.Message();
message.SendSubject = TargetSubject;
message.AddField(MessageField, data);
Transport.Send(message);
}
public void Send(string field, string data)
{
}
#endregion
public void OnListenCallBack(object sender , bool listenStatu)
{
IsListened = listenStatu;
}
public void OnConnectCallBack(object sender, bool connectStatu)
{
IsConnected = connectStatu;
if (IsConnected)
{
Listen();
}
}
/// <summary>
/// 消息接收
/// </summary>
public void OnMessageReceivedCallBack(object sender, MessageReceivedEventArgs messageReceivedEventArgs)
{
messageReceivedHandler.Invoke(sender, messageReceivedEventArgs);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="messageReceivedEventArgs"></param>
public delegate void MessageReceivedHandler(object sender, MessageReceivedEventArgs messageReceivedEventArgs);
public MessageReceivedHandler messageReceivedHandler;
public event EventHandler<string> ErrorMessageHandler;
public event EventHandler<bool> ConnectedStatusHandler;
public event EventHandler<bool> ListenedStatusHandler;
}
}
总结
项目中用到了TibcoRv中间件作通信。在此过程中,碰到了很多坑,也是自己本身水平一般。在此分享一下TibcoRV通信的Demo。算是作为备份吧。万一哪天忘记了呢。