设为首页 收藏本站
查看: 1252|回复: 0

[经验分享] .Net环境下操作IBM WebShpere MQ

[复制链接]

尚未签到

发表于 2015-10-3 14:19:16 | 显示全部楼层 |阅读模式
.Net环境下操作IBM WebShpere MQ


大约在两年前项目使用了IBM MQ,本人积累了部分在.Net环境下操作IBM MQ的经验。现将经验与大家分享。

IBM WebShpere MQ 简单介绍:
具体的详细信息大家可以在IBM的网站和网上有许多的学习资料。
IBM MQ是实现了消息队列的一个中间件,它可以运行在现在所有流行的平台上。在我们的项目中主要使用的是AS400和UNIX平台上。
在IBM MQ中主要分为以下几个对象:

Queue Manager
队列管理器
主要负责管理队列、通道等,类似与Oracle中的Oracle实例的概念,在一台服务器中可以定义多个Queue Manager。
Queue
队列
是存放Message的对象,是我们主要操作的对象。类似与Oracle中的表的概念。
Message
消息
实际放入Queue中的消息,该消息可以存储字符串、Stream等对象。
Channel
通道
是我们的应用以及两个Queue Manager操作的链接对象
Process
过程


Queue的分类:
Local Queue
本地队列
主要存储消息的对象
Remote Queue
远程队列
和另外一个Queue Manager通讯的队列
Mode Queue
模板队列
建立一个队列模板,通过这个模板可以建立与模板相同属性的动态队列。
Dynamic Queue
动态对了(临时队列)
可以在程序中创建和删除的临时队列

Channel类型:
在我们介绍中只使用了类型为SVRCONN的通道。



.Net连接Queue Manager的关键要素:
.Net的程序需要以下几个关键要素才能连接的一个Queue Manager上。
1、  Address & Port
MQ的服务器地址以及要连接的Queue Manager的监听端口,默认端口1414。
2、  Queue Manager Name
要连接的Queue Manager的名字,区分大小写,默认全部大写。
3、  Channel Name
SVRCONN类型的Channel的名字,需要注意的是该Channel的属性MCAUSER必须设置为一个足够权限的系统用户,否则不能连接成功。
4、  CCSID
CCSID是Queue Manager的编码字符集,需要Queue Manager的CCSID与你的.Net操作系统的CCSID互相兼容或者一致才能成功连接。默认情况下UNIX平台的Queue Manager的CCSID为819,而简体中文版的Windows的CCSID为1381。这两个编码字符集是不能兼容的,所以需要调整。
调整有两种方式:
1)  调整Queue Manager的CCSID,调整成与1381兼容的即可,不一定需要调整成1381
2)  在不能调整Queue Manager时需要配置Windows的环境变量,在Windows的环境变量中增加MQCCSID的环境变量,值需要与Queue Manager的CCSID一致或兼容。

在我们介绍的例子中使用环境如下:

Server:Sun OS 5.9
Address
192.168.128.115
Port
1414(默认端口)
Queue Manager Name
SGS.MGR
Channel Name
SGS.CHANNEL

Queue Manager的属性如下(注意红色部分):
Display Queue Manager details.
   DESCR( )                                DEADQ( )
   DEFXMITQ( )                             CHADEXIT( )
   CLWLEXIT( )                             CLWLDATA( )
   REPOS( )                                REPOSNL( )
   COMMANDQ(SYSTEM.ADMIN.COMMAND.QUEUE)    QMNAME(SGS.MGR)
   CRDATE(2007-04-02)                      CRTIME(16.24.23)
   ALTDATE(2007-04-02)                     ALTTIME(16.24.23)
   QMID(SGS.MGR_2007-04-02_16.24.23)       TRIGINT(999999999)
   MAXHANDS(256)                           MAXUMSGS(10000)
   AUTHOREV(DISABLED)                      INHIBTEV(DISABLED)
   LOCALEV(DISABLED)                       REMOTEEV(DISABLED)
   PERFMEV(DISABLED)                       STRSTPEV(ENABLED)
   CHAD(DISABLED)                          CHADEV(DISABLED)
   CLWLLEN(100)                            MAXMSGL(4194304)
   CCSID(819)                              MAXPRTY(9)
   CMDLEVEL(510)                           PLATFORM(UNIX)
   SYNCPT                                  DISTL(YES)

Channel的属性如下(注意红色部分):
Display Channel details.
   CHANNEL(SGS.CHANNEL)                    CHLTYPE(SVRCONN)
   TRPTYPE(TCP)                            DESCR( )
   SCYEXIT( )                              MAXMSGL(4194304)
   SCYDATA( )                              HBINT(300)
   MCAUSER(mqm)                            ALTDATE(2007-04-02)
   ALTTIME(16.30.23)
   SENDEXIT( )
   RCVEXIT( )
   SENDDATA( )
   RCVDATA( )

由于Queue Manager的CCSID使用819,故增加系统的环境变量:


DSC0000.jpg



环境准备:

1、  安装IBM WebSphere MQ Client for Windows。(MQ客户端)
2、  安装WebSphere MQ classes for Microsoft .NET.msi。(.Net插件)
3、  在你的.Net项目中引用 amqmdnet.dll,该dll在.Net插件安装目录中可以找到。

开始编写代码:

连接Queue Manager


DSC0001.gif //MQ管理实例

              private MQQueueManager      mqQMgr=null;// MQQueueManager instance



private void CreateMng()

DSC0002.gif DSC0003.gif                DSC0004.gif {
DSC0005.gif
                     if(this.mqQMgr==null)

DSC0006.gif DSC0007.gif                      {

                            try

                            {     this.log("Create Queue Manager");                     

                                   

                                   //通过MQ管理名创建MQ管理实例

                    //判断是远程连接还是本地连接

                                   if(!this.checkBox1.Checked)  //本地连接 (服务器连接)

                                          this.mqQMgr = new MQQueueManager(this.tbQMng.Text);

                                   else   //远程连接(客户端连接)

                                   {

                                          string hostname = this.tbConnection.Text; //Server地址

                                          string channel = this.tbChannel.Text;   //Channel 名

                                          string qManager = this.tbQMng.Text;   //Queue Manager名



                                          //初始化环境变量

                                          

                                          MQEnvironment.Hostname = hostname;

                                          MQEnvironment.Channel = channel;

                                          MQEnvironment.Port = Int32.Parse(this.textBox1.Text); //端口号

                                          

                                          this.mqQMgr =new MQQueueManager(qManager);

                                          

DSC0008.gif                                    }

                                   

                                   this.log("Create Queue Manager Sucess");

                            }

                            catch(MQException ex)

                            {

                                   this.mqQMgr=null;

                                   this.log("Create Queue Manager Failed!"+ex.Message+"reason:" + Convert.ToString( ex.Reason,16));

                            }

                     }

DSC0009.gif               }


向本地队列(SGS.IN.01)放入消息:


  

  1private void button1_Click(object sender, System.EventArgs e)
  2
  3              {
  4
  5                     //定义队列
  6
  7                     MQQueue             mqQueue=null;
  8
  9
10
11                     this.CreateMng();  //连接Queue Manager
12
13
14
15                     try
16
17                     {
18
19                            if(this.mqQMgr==null)
20
21                                   return;
22
23
24
25                            this.log("Create MQQueue");
26
27
28
29                            //通过MQ管理创建队列实例
30
31                            mqQueue=this.mqQMgr.AccessQueue(this.tbQName.Text,MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING | MQC.MQOO_INQUIRE);  
32
33//本例中this.tbQName.Text=”SGS.IN.01”
34
35
36
37                           
38
39                            this.log("Create MQQueue Sucess");
40
41
42
43                     }
44
45                     catch(MQException ex)
46
47                     {
48
49                           
50
51                            this.log("Create MQQueue Failed!!"+ex.Message+"reason:" + Convert.ToString( ex.Reason,16));
52
53                            return;
54
55                     }
56
57
58
59                     //要放入队列中的消息
60
61MQMessage mqMsg =null;
62
63                     try
64
65                     {
66
67                            int count=Int32.Parse(this.tbCount.Text);
68
69
70
71                            //创建消息操作实例
72
73                            MQPutMessageOptions mqPutMsgOpts = new MQPutMessageOptions();
74
75
76
77                           
78
79                            for(int i=0;i<count;i++)
80
81                            {
82
83                                   this.log("Create Message");
84
85                                   //创建消息实例
86
87                                   mqMsg = new MQMessage();
88
89                           
90
91                                   System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
92
93                                   doc.Load(this.tbMsg.Text);
94
95                                   string msg=doc.OuterXml;  //以字符串的形式放入一个XML
96
97                                   
98
99                                   mqMsg.WriteString(msg);
100
101                                   //制定消息格式为String
102
103                                   mqMsg.Format = MQC.MQFMT_STRING;
104
105                                   
106
107                                   this.log("Create Message Sucess. Message:"+msg);
108
109
110
111
112
113                                   this.log("Begin Put Message");
114
115                                   //发送消息
116
117                                   mqQueue.Put(mqMsg,mqPutMsgOpts);
118
119                                   this.log("Put Message Sucess");
120
121                                   
122
123                            }
124
125                     }
126
127                     catch (Exception ex)
128
129                     {
130
131                            this.log(ex.Message);
132
133                     }
134
135              }
136
从本地队列(SGS.IN.01)获取消息
            

  1 private void button2_Click(object sender, System.EventArgs e)
  2
  3              {
  4
  5                     //定义队列
  6
  7                     MQQueue             mqQueue=null;
  8
  9
10
11                     this.CreateMng();
12
13
14
15                     try
16
17                     {
18
19                            this.log("Create MQQueue");
20
21                            //通过MQ管理实例创建队列实例,制定队列操作类型
22
23                            mqQueue= this.mqQMgr.AccessQueue(this.tbQName.Text,MQC.MQOO_INPUT_AS_Q_DEF+MQC.MQOO_FAIL_IF_QUIESCING);
24
25                            this.log("Create MQQueue Sucess");
26
27                     }
28
29                     catch (Exception ex)
30
31                     {
32
33                            this.log("Create MQQueue Failed!!"+ex.Message);
34
35                            return;
36
37                     }
38
39
40
41                     //定义队列消息
42
43                     MQMessage mqMsg =null;
44
45                     try
46
47                     {
48
49                            int count=Int32.Parse(this.tbCount.Text);
50
51                            //定义消息操作
52
53                            MQGetMessageOptions mqGetMsgOpts=null;
54
55
56
57                            //队列消息操作类型实例化
58
59                            mqGetMsgOpts = new MQGetMessageOptions();
60
61                            //设置消息操作超时
62
63                            mqGetMsgOpts.WaitInterval=15000;
64
65
66
67                            bool isContinue = true;
68
69                            while(isContinue && count>0)
70
71                            {
72
73                                   //实例化消息
74
75                                   mqMsg = new MQMessage();
76
77                                   try
78
79                                   {
80
81                                          this.log("Begin get message");
82
83                                          //从消息队列得到消息
84
85                                          mqQueue.Get(mqMsg,mqGetMsgOpts);
86
87                                          this.log("Begin get message Success");
88
89
90
91                                          //比较消息格式
92
93                                          if(mqMsg.Format.CompareTo(MQC.MQFMT_STRING) == 0)
94
95                                          {
96
97                                                 //MQC.MQFMT_RF_HEADER_2
98
99                                                 this.log("Message:"+mqMsg.ReadString(mqMsg.MessageLength));
100
101                                          }
102
103                                          else //if (mqMsg.Format.CompareTo(MQC.MQFMT_RF_HEADER_2)==0)
104
105                                          {
106
107                                                 this.log("MessageType:"+mqMsg.Format+"\r\n");
108
109                                                 string msg=mqMsg.ReadString(mqMsg.MessageLength);
110
111                                                
112
113
114
115                                                 this.log(msg);
116
117                                          }
118
119//                                        else
120
121//                                        {
122
123//                                               this.log("MessageType:"+mqMsg.Format+"\r\n");
124
125//                                               byte[] buffer = new byte[mqMsg.MessageLength];
126
127//                                               buffer=mqMsg.ReadBytes(mqMsg.MessageLength);
128
129//
130
131//                                               this.log("byteMessage:"+System.Text.Encoding.UTF8.GetString(buffer));
132
133//                                        }
134
135                                   }
136
137                                   catch (MQException mqe)
138
139                                   {
140
141                                          // 判断异常原因,队列中没有消息
142
143                                          if ( mqe.Reason == MQC.MQRC_NO_MSG_AVAILABLE )
144
145                                          {
146
147                                                 this.log("Have no message  "+mqe.Message);
148
149                                                 isContinue=false;
150
151                                          }
152
153
154
155                                          // treat truncated message as a failure for this sample
156
157                                          if ( mqe.Reason == MQC.MQRC_TRUNCATED_MSG_FAILED )
158
159                                          {
160
161
162
163                                                 isContinue=true;
164
165                                          }
166
167                                   }
168
169
170
171                                   count--;
172
173                            }
174
175                     }
176
177                     catch (Exception ex)
178
179                     {
180
181                            this.log(ex.Message);
182
183                     }
184
185              }
186
187
188
189关闭Queue Manager的连接:
190
191              private void button3_Click(object sender, System.EventArgs e)
192
193              {
194
195                     if (this.mqQMgr!=null)
196
197                     {
198
199                            this.mqQMgr.Disconnect();
200
201                            this.mqQMgr=null;
202
203                     }
204
205              }
206
207

现介绍这些,以后我会对模板对了和动态队列做一些介绍,希望对大家有所帮助。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-122203-1-1.html 上篇帖子: Linux 中的计时 下篇帖子: 终于对你下了手――IBM:老Hu的购机经历
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表