Попытка подключиться к MQ с помощью PHP;почти готово - PullRequest
8 голосов
/ 28 октября 2011

Итак, я провел последние несколько дней, пытаясь решить эту проблему, которая, кажется, была забыта, поскольку ни одно из двух доступных расширений 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?

1 Ответ

1 голос
/ 28 октября 2011

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, и поэтому все имена полей и значения по умолчанию точно соответствуют этим включаемым файлам. Этот модуль, похоже, использует аналогичный подход, и я ожидаю использовать определенные имена и значения по умолчанию для полей, где это необходимо.

Я думаю что-то вроде:

$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.

...