При работе над одним приложением мне довелось столкнуться с отсутствием поддержки RTMP протокола на столь важном уровне как «внешний вызов» приложений и команд.
Дело в том, что на том же ActionScript эти действия — совершенно прозрачны, существует готовы набор функций, все очень легко и понятно. Однако, если Вы создаете свое приложение, которому это понадобилось, Вы так или иначе встретитесь с целым рядом вопросов.
На данный момент только продукт от broccoli products имеет такие функции, однако у него есть проблемы на уровне первоначального соединения с сервером. Благодаря мне они сделали проверку HandShake опциональной, однако AMF параметры в connect пока не включили. Да, есть еще FluorineFX, однако у них точно такие же трудности. И обе либы C#, что не всегда нужно и решает задачи.
Тем самым вопрос «не мейнстримовский», однако имеет место быть.
Мое решение — в некоторой модернизации librtmp под свои нужды. В принципе, это даже не модернизация, а «нашлепка поверх» — можно обойтись и без правки библиотеки.
Для примера возьмем то, что элементарно реализуется на action script:
NetworkConnection.call("sendMessage", null, "text");
Реализуем на С++:
#define RTMP_PACKET_TYPE_INVOKE 0x14 #define SAVC(x) static const AVal av_##x = AVC(#x) #define STR2AVAL(av,str) av.av_val = str; av.av_len = strlen(av.av_val) //-------------------------------- int RTMP_SendMessage(RTMP *r, char *msg) { RTMPPacket packet; char pbuf[1024], *pend = pbuf + sizeof(pbuf); char *enc; struct AVal msgEnc; STR2AVAL(msgEnc, msg); packet.m_nChannel = 0x03; /* control channel (invoke) */ packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; packet.m_packetType = RTMP_PACKET_TYPE_INVOKE; packet.m_nTimeStamp = 0; packet.m_nInfoField2 = 0; packet.m_hasAbsTimestamp = 0; packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; enc = packet.m_body; enc = AMF_EncodeString(enc, pend, &av_sendMessage); enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes); *enc++ = AMF_NULL; /* NULL */ enc = AMF_EncodeString(enc, pend, &msgEnc); packet.m_nBodySize = enc - packet.m_body; return RTMP_SendPacket(r, &packet, TRUE); }
Это направление для дальнейшего развития, не более чем. На самом деле данная функция нужна очень редко, в основном для специфических серверов.