所以我花了这么多天试图解决这个似乎已被遗忘的事情,因为两个PECL扩展中没有一个(SAM和mqseries)已经更新了很长时间。我已经尝试过两者并且mqseries似乎让我在这一点上最远,因为SAM拒绝让我连接,即使MQ从命令行完美运行。我已经成功创建了与QueueManager的连接,并且在下一步(MQOPEN)中我失败了:
$mqcno = array(
'Version' => MQSERIES_MQCNO_VERSION_2,
'Options' => MQSERIES_MQCNO_STANDARD_BINDING,
'MQCD' => array('ChannelName' => '[channel]',
'ConnectionName' => '[ipnumber]([port])',
'TransportType' => MQSERIES_MQXPT_TCP)
);
mqseries_connx('MQED', $mqcno, $conn, $comp_code,$reason);
if ($comp_code !== MQSERIES_MQCC_OK) {
printf("Connx CompCode:%d Reason:%d Text:%s<br>\n", $comp_code, $reason, $reason);
exit;
}
$mqods = array('ObjectName'=>'MYPUTQUEUE', 'ObjectType'=>MQOT_Q, 'ObjectQMgrName'=>'MYQUEUEMANAGER');
mqseries_open($conn, $mqods,
MQSERIES_MQOO_FAIL_IF_QUIESCING | MQSERIES_MQOO_OUTPUT,
$obj, $comp_code,$reason);
这导致$ reason被填充为2044,转换为MQRC_OD_ERROR,或者英文:'在MQOPEN或MQPUT1调用上,对象描述符MQOD无效'。
所以问题是,我的MQOD出了什么问题?
更新#1:此时此问题尚未解决。我从头开始重建项目,以便在构建时解决任何问题。我仍然坚持MQOPEN返回2044.样本仍然从CLI运行完美,所以这绝对与PECL扩展的安装有关。如果有人在最近的64位PHP5环境中成功安装并运行PHP对MQ,请告诉我...
更新#2:MQPUT1完美地解决了我无法收到回复的问题。在这一点上,它只是MQOPEN不起作用。问题是;什么导致MQOPEN在MQPUT1工作时返回2044,我理解包括MQOPEN?
答案 0 :(得分:1)
cmqch文件中的MQOD如下所示:
/****************************************************************/
/* MQOD Structure -- Object Descriptor */
/****************************************************************/
typedef struct tagMQOD MQOD;
typedef MQOD MQPOINTER PMQOD;
typedef PMQOD MQPOINTER PPMQOD;
struct tagMQOD {
MQCHAR4 StrucId; /* Structure identifier */
MQLONG Version; /* Structure version number */
MQLONG ObjectType; /* Object type */
MQCHAR48 ObjectName; /* Object name */
MQCHAR48 ObjectQMgrName; /* Object queue manager name */
MQCHAR48 DynamicQName; /* Dynamic queue name */
MQCHAR12 AlternateUserId; /* Alternate user identifier */
/* Ver:1 */
MQLONG RecsPresent; /* Number of object records
present */
MQLONG KnownDestCount; /* Number of local queues opened
successfully */
MQLONG UnknownDestCount; /* Number of remote queues opened
successfully */
MQLONG InvalidDestCount; /* Number of queues that failed to
open */
MQLONG ObjectRecOffset; /* Offset of first object record
from start of MQOD */
MQLONG ResponseRecOffset; /* Offset of first response record
from start of MQOD */
MQPTR ObjectRecPtr; /* Address of first object record */
MQPTR ResponseRecPtr; /* Address of first response
record */
/* Ver:2 */
MQBYTE40 AlternateSecurityId; /* Alternate security identifier */
MQCHAR48 ResolvedQName; /* Resolved queue name */
MQCHAR48 ResolvedQMgrName; /* Resolved queue manager name */
/* Ver:3 */
MQCHARV ObjectString; /* Object long name */
MQCHARV SelectionString; /* Message Selector */
MQCHARV ResObjectString; /* Resolved long object name*/
MQLONG ResolvedType; /* Alias queue resolved object type */
/* Ver:4 */
};
#define MQOD_DEFAULT {MQOD_STRUC_ID_ARRAY},\
MQOD_VERSION_1,\
MQOT_Q,\
{""},\
{""},\
{"AMQ.*"},\
{""},\
0,\
0,\
0,\
0,\
0,\
0,\
NULL,\
NULL,\
{MQSID_NONE_ARRAY},\
{""},\
{""},\
{MQCHARV_DEFAULT},\
{MQCHARV_DEFAULT},\
{MQCHARV_DEFAULT},\
MQOT_NONE
我想知道模块是否填写默认值并让你用哈希覆盖它。如果是这样,'DeviceName'真的是正确的键吗?我认为它会匹配WMQ字段名称或常量。
更新:在提供的链接上按the example,哈希键确实与cmqc.h中的字段名匹配。
更新#2回应评论:cmqc.h中定义的对象类型是:
/* Object Types */
#define MQOT_NONE 0
#define MQOT_Q 1
#define MQOT_NAMELIST 2
#define MQOT_PROCESS 3
#define MQOT_STORAGE_CLASS 4
#define MQOT_Q_MGR 5
#define MQOT_CHANNEL 6
#define MQOT_AUTH_INFO 7
#define MQOT_TOPIC 8
#define MQOT_CF_STRUC 10
#define MQOT_LISTENER 11
#define MQOT_SERVICE 12
#define MQOT_RESERVED_1 999
我对PHP,Perl和大多数其他类似工作的理解是它们是一个非常薄的C API包装器。 Perl只是直接从cmqc.h和其他C包含文件生成大部分代码,因此所有字段名称和默认值都与那些包含文件完全匹配。该模块似乎采用了类似的方法,我希望在需要的地方使用定义的名称和字段默认值。
我在想:
$mqods = array(
'StrucID'=>'OD ',
'Version'=>1.
'ObjectType'=>1,
'ObjectName'=>'MYPUTQUEUE',
'ObjectQMgrName'=>'MYQUEUEMANAGER'
'DynamicQName'='',
'AlternateUserId'='',
'RecsPresent'=>0,
'KnownDestCount'=>0,
'UnknownDestCount'=>0,
'InvalidDestCount'=>0,
'ObjectRecOffset'=>0,
'ResponseRecOffset'=>0,
'ObjectRecPtr'=>NULL,
'ResponseRecPtr'=>NULL
);
更新#3回应其他评论:
Q Mgr将接受任何版本的MQOD,但将回退到该级别的功能。如果您使用v1,您可以测试它是否有效。如果要使用更高版本的MQOD,则需要将其他字段添加到散列中。
2009年是“连线破碎”。基本上QMgr不喜欢什么并终止你的连接。通常,返回代码的有意义错误消息位于/var/mqm/qmgrs/<qmgrname>/errors/AMQEER01.LOG
。