Поэтому я провел последние несколько дней, пытаясь решить эту проблему, которая, кажется, была забыта, поскольку ни одно из двух доступных расширений 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. Если есть кто-то, кто успешно установил и запускает PHP против MQ в довольно недавней 64-битной среде PHP5, пожалуйста, дайте мне знать …
Обновление № 2: MQPUT1 работает безупречно с проблемой, что я не могу получить ответ. На данный момент это просто MQOPEN, что не работает. Вопрос: что заставляет MQOPEN возвращать 2044, когда MQPUT1 работает, что я понимаю, включает MQOPEN?
MQOD в файле cmqch выглядит так:
/****************************************************************/ /* 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.
Обновление: в примере по предоставленной ссылке хэш-ключ действительно соответствует имени поля из 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, и поэтому все имена полей и значения по умолчанию точно соответствуют этим файлам include. Этот модуль, похоже, придерживался аналогичного подхода, и я ожидал бы, когда это необходимо, использовать определенные имена и поля по умолчанию.
Я думаю, что-то вроде:
$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
.