PDA

Просмотр полной версии : Подключение к Премьере через PHP. Возвращает ошибку 10061



Dok
27.12.2012, 17:28
Пытаюсь подключить к Премьере согласно документации (в целях конспирации ip и port заменил нулями):

$IP = "00.00.0.000";
$port = 0000;

$arError = Array();

$fp = fsockopen($IP, $port, $arError["N"], $arError["TEXT"], 7);

if (!$fp) {
return "Connection failed. Error #".$arError["N"].": ".$arError["TEXT"];
}

Возвращает:

Connection failed. Error #10061: Подключение не установлено, т.к. конечный компьютер отверг запрос на подключение.

В чем может быть проблема?

P.S. http://www.bravica.net/ru/net-port.html - показывает, что указываемый порт открыт у данного IP
P.P.S. Скрипт запускаю на локальной машине в Denwer. Интернет доступен

sibgaba
27.12.2012, 17:42
Попробуйте, для начала, через sockettest.exe со своей машины выполнить запрос на нужный IP и порт. Например простейший GetHalls. Если вам вернется какая то XML-ка, то это ответил шлюз, если не вернется ничего - значит либо не тот IP, либо не тот порт, либо что то со стороны сервера вас не пускает (Антивирь, файрвол, роутер)

Та ошибка которая у вас есть, говорит о том что на вызываемой стороне никто не отозвался.

Dok
27.12.2012, 18:15
Попробуйте, для начала, через sockettest.exe со своей машины выполнить запрос на нужный IP и порт. Например простейший GetHalls. Если вам вернется какая то XML-ка, то это ответил шлюз, если не вернется ничего - значит либо не тот IP, либо не тот порт, либо что то со стороны сервера вас не пускает (Антивирь, файрвол, роутер)

Та ошибка которая у вас есть, говорит о том что на вызываемой стороне никто не отозвался.
Спасибо за скорый ответ! Однако, найти такую программу совсем не получилось. Есть возможность загрузить её на форум или дать ссылку?

sibgaba
27.12.2012, 20:26
Выложил
http://www.carbis.ru/forum/showthread.php?t=6844&p=52967#post52967

Dok
27.12.2012, 20:50
Благодарю! Порт действительно открыт, и подключиться к нему не удавалось только с денвера. На реальном сервере происходит подключение.

function getXML($ip, $port, $request, $in1251 = false) { // Функция отправляет запрос к Премьере
$arError = Array();

$fp = fsockopen($ip, $port, $arError["N"], $arError["TEXT"], 7);

if (!$fp) {
return "Connection failed. Error #".$arError["N"].": ".$arError["TEXT"];
} else {
fwrite($fp, $request);
$result = '';
while (!feof($fp)) {
$temp = fread($fp, 256);
$result .= $temp;
}
fclose($fp);

$result = substr($result, strpos($result, "<?xml version='1.0'"));
if ($in1251 and $result) {
$result = preg_replace("/<PN>.*?<\/PN>/", "<PN></PN>", $result);

return $result;
} elseif($result) {
$result = str_replace("<?xml version='1.0' encoding='CP-866' standalone='yes'?>", "<?xml version='1.0' encoding='windows-1251' standalone='yes'?>", $result);
$result = preg_replace("/<PN>.*?<\/PN>/", "<PN></PN>", $result);
$result = iconv("cp866", "windows-1251", $result);

return $result;
}

return "Error";
}
}
При передаче правильных IP и Port (по крайней мере этот порт у машины с указанным IP открыт) функция возвращает Error.
Значит соединиться удалось... может я не верно составил формат запроса? Проверьте, поажлуйста :)

echo Premiere::getXML(
"255.255.255.255",
9194,
"0000000118&ServiceID=548387668&QueryCode=GetLevelsPlans&Halls=1&ListType=Image&Encoding=Windows-1251&Version=3&Expect=");

P.S.
На такой запрос возвращается Error:

"0000000046&QueryCode=1&CardCode=1&CardPIN=1111"

А на такой "QueryCode=1&CardCode=1&CardPIN=1111":

0000000183&ErrorCEE-008

На такой "0000000035&QueryCode=1&CardCode=1&CardPIN=1111":

0000000205&ErrorCEE-063

На такой "0000000045&QueryCode=1&CardCode=1&CardPIN=1111&Version=3":

0000000212&ErrorCEE-072

На такой "0000000065&QueryCode=1&CardCode=1&CardPIN=1111&Version=3&ServiceID=548387668":

0000000205&ErrorCEE-079

Я что-то неправильно делаю?

P.P.S. Наверное через все ошибки пройти придется)))

sibgaba
27.12.2012, 21:39
Во первых: Какая версия Премьеры?
До 3,16 включительно конструкция

while (!feof($fp)) {
$temp = fread($fp, 256);
$result .= $temp;
}

Работала нормально.
На версиях выше 3,16 она не работала т.к. внешний протокол перестал слать feof в конце ответа. В этом случае лучше пользовать более строгий код типа вот такого:

$n = fgets($fp,11);
$s = fgets($fp,$n+1);

Т.е. читать не пока конец потока, а ровно столько байт, сколько в ответе. По формату ответа первые 10 байт как раз содержат длину пакета. Более подробно обсуждалось тут http://www.carbis.ru/forum/ucs-Премьера/5175-Связь-ucs-премьера-внешний-протокол-с-сайтом-на-php.html

Что касается ошибок № 8 и 63 сейчас доки под рукой нету. Завтра посмотрю их расшифровку.

Далее не совсем понял вот такой момент: Если через СокетТест сделать запрос GetHalls то что он показывает? Я всегда тестирую через GetHalls т.к. он не требует Login и либо вернет перечень залов (значит external на стороне сервера настроен нормально, порты прокинуты и если что то не работает то надо смотреть php код) либо вернет ошибку и тогда php тут не причем и крутить надо external.

---------- Добавлено в 19:39 ---------- Предыдущее сообщение было размещено в 19:29 ----------

Чета вы в запросах хрень какую то шлете...
Я так понимаю что вы не инсталятор, а разработчик сайта. Верно?

В любом случае дока по запросам внешнего протокола у вас есть?

По формату протокола обмена, в любом запросе, ВСЕГДА должен присутствовать ServiceID. И он должен всегда идти первым (вот тут могу ошибаться, но кажется так).

Далее: параметр QueryCode не должен принимать числовое значение. Он должен содержать имя запроса который вы выполняете. Например GetHalls

Попробуйте вот такой запрос прогнать через свой скрипт:
0000000108&ServiceID=548387668&QueryCode=GetHalls&CardCode=&DateList=&Theatres=&Encoding=Windows-1251&Version=3&Expect=

Должна вернуться xml-ка с перечнем залов, для которых разрешены внешние продажи.

Прогоните тот же запрос с помощью SocketTest, только допишите правильный ServiceID

sibgaba
28.12.2012, 12:56
По ошибкам:

CEE-008 Сделан не верный запрос
Сделан не верный запрос. Ошибка в указании параметра QueryCode.

CEE-063 Ошибочна версия протокола
Ошибочна версия протокола. Требуется проверить номер версии протокола. На момент написания
документации внешний протокол 3.00 поддерживал только 3 версию протокола. В xml-ответе
указывается номер текущей версии.

CEE-072 Ошибочно введен идентификатор службы внешней продажи
По указанному идентификатору (ServiceID) не обнаружено ни одной службы внешних продаж.

CEE-079 У службы внешних продаж не обнаружен IP адрес
У службы внешних продаж не обнаружен IP адрес. Поступивший запрос получен с IP адреса не
указанного в списке адресов службы внешних продаж в ПО Премьера.

В общем все ошибки (кроме последней) Ваши. И идут они от того что вы не верно формируете запросы. Не указываете необходимые параметры или указываете их не правильно (Например QueryCode=1, параметр QueryCode не может принимать числовое значение, он должен содержать имя вызываемого запроса)

Я так понимаю что вы не иснталятор, а разработчик сайта. Верно?
Вам доку на внешний протокол дали???

Dok
28.12.2012, 13:15
По SocketTest:

Time: 00:00.546


0000000205&<?xml version='1.0' encoding='Windows-1251' standalone='yes'?><XML><Result>Error</Result><Error>CEE-079</Error><Remark><=!=[=C=D=A=T=A=[У службы внешних продаж не обнаружен IP адрес]=]=></Remark><Data></Data></XML>


Да, я разрабатываю новый сайт и необходимо наладить связь с премьерой, вот разбираюсь.
Дали документацию ПО «UCS Премьера: внешний протокол» версия 3.02
Пока еще не проникся всеми тонкостями протокола :)

Уже понял, что запрос "0000000076&QueryCode=1&CardCode=1&CardPIN=12345&Version=3&ServiceID=548387668&Expect=30" неверный, но возвращает он туже ошибку: CEE-079.
Связывался с кинотеатром, где установлена Премьера, сказали, что добавили IP хостинга, с которого произвожу подключение и перезагрузили службу, но все равно ошибка 079.

В чем может быть дело?

P.S. По моему SocketTes вернул ошибку потому что программа запускалась на локальном компьютере, IP которого точно не записан в Премьере.

P.P.S. Прогнал через скрипт "0000000108&ServiceID=548387668&QueryCode=GetHalls&CardCode=&DateList=&Theatres=&Encoding=Windows-1251&Version=3&Expect="
Все равно 079 возвращает

sibgaba
28.12.2012, 13:43
79-я ошибка говорит о том что IP адрес, с которого вы шлете запросы, не прописан в разрешениях внешнего протокола.

на стороне сервера Премьеры, в логах CinemaExternal можно посмотреть с какого IP приходят ваши запросы.
Вариантов 2: либо в премьера прописали не тот IP, либо его прописали не туда (там, в зависимости от версии премьеры, есть 2 места где он прописывается)

Dok
28.12.2012, 15:45
Спасибо за помощь!

Проблема оказалась в том, что в Премьере есть ограничение на IP адреса, которые уже были заполнены.
Временно поменяв один адрес на мой - все заработало.
Жаль, что есть такое ограничение, но хотя бы удалось установить сам факт связи!

---------- Добавлено в 14:45 ---------- Предыдущее сообщение было размещено в 13:06 ----------

На всякий случай спрошу - можно ли как-то обойти ограничение в 2 IP адреса?

sibgaba
28.12.2012, 20:58
На всякий случай спрошу - можно ли как-то обойти ограничение в 2 IP адреса?
Официально, кроме как купить доп обработчик - никак.
Можно програмно намутить: делаем промежуточный шлюз, который принимает запросы ото всех и отправляет в Премьеру. А потом получает от Премьеры ответы и рассылет их адресатам.

Dok
29.12.2012, 18:29
Официально, кроме как купить доп обработчик - никак.
Можно програмно намутить: делаем промежуточный шлюз, который принимает запросы ото всех и отправляет в Премьеру. А потом получает от Премьеры ответы и рассылет их адресатам.
Спасибо! Со шлюзом получилось :)
В Премьеры были заняты 2 IP - на Киноход и на рабочий сайт.
На рабочий сайт добавил скрипт, через который идут данные. Всё работает!

Shadof
01.03.2013, 23:20
Похожая проблема!!


<? header('Content-Type: text/plain;');
error_reporting(E_ALL ^ E_WARNING);//включаем отображение ошибок
ini_set('display_errors', 0);
set_time_limit(0);//чтоб скрипт выполнялся всегда, а не положенные 30 секунд по дефолту
ob_implicit_flush();//выводить строки с помощью echo нужно сразу при их выводе, а не после полной загрузки страницы, как это делается по-умолчанию.
echo "-= Client =-\n\n";//выводим информацию что клиент запущен
$address = 'xxx.195.xxx.xxx';//адрес, к которому мы будем поключаться
$port = 4xxxx; //порт сервера
try { echo 'Create socket … ';
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);//создаём сокет
if ($socket < 0) {
throw new Exception('socket_create() failed: '.socket_strerror(socket_last_error())."\n");//если возникла ошибка – создаём исключение с описанием ошибки
} else { echo "OK\n";//иначе пишем что всё нормально
} echo 'Connect socket … ';
$result = socket_connect($socket, $address, $port);//подключаемся к серверу
if ($result === false) {
throw new Exception('socket_connect() failed: '.socket_strerror(socket_last_error())."\n");//если неудалось – создаём исключение с описанием ошибки
} else {
echo "OK\n";//в противном случае, пишем что всё нормально
}$msg ="0000000426&ServiceID=956&QueryCode=GetHalls&DateList=&Theatres=&Encoding=Windows-1251&Version=3";
//$msg = "<PING>\r\n";//Подготавливаем сообщение к отправке.
echo "Say to server ($msg) …";
socket_write($socket, $msg, strlen($msg));//отправляем сообщение серверу
echo "OK\n";
echo 'Server said: ';
$out = socket_read($socket, 1024);//читаем ответ сервера
echo $out."\n";//здесь можно писать обработчик различных сообщений сервера
} catch (Exception $e) {
echo "\nError: ".$e->getMessage();//если возникло исключение – пишем ошибку на экран
} if (isset($socket)) { echo 'Close socket … ';
socket_close($socket);//закрываем сокет
echo "OK\n"; }
выдает :

-= Client =- Create socket � OK Connect socket � OK Say to server (1391961426&ServiceID=956&QueryCode=GetHalls&DateList=&Theatres=&Encoding=Windows-1251&Version=3) �OK Server said: Close socket � OK
к сожалению не оч силен в пхп, но может кто подскажет... как я вижу, я просто не могу получить xml

puzoid
10.11.2015, 16:15
Скажите пожалуйста, где взять этот самый ServiceID?

sibgaba
10.11.2015, 17:07
Скажите пожалуйста, где взять этот самый ServiceID?
В самой Премьере. Он прописан в одном из свойств справочника в котором описан сервис внешних продаж.