При работе над одним приложением мне довелось столкнуться с отсутствием поддержки 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);
}
Это направление для дальнейшего развития, не более чем. На самом деле данная функция нужна очень редко, в основном для специфических серверов.