👉🏻 아래는 miniMediaserver_1의 코드 설명입니다.(rtmp_session.cpp)
Below is the code description for miniMediaserver_1 (rtmp_session.cpp).
👉🏻 void RtmpSession::send_protocol_messages() {} 이 함수에서 Protocol Control Messages 를 보냅니다.
void RtmpSession::send_protocol_messages() {} This function sends Protocol Control Messages.
👉🏻 OBS가 서버로 보낼 데이터 설정 값을 OBS에게 통보합니다.
Notifies OBS of the data setting values to send to the server.
✔️ void RtmpSession::send_protocol_messages() {}
— 핸드셰이크 끝나자마자 버퍼 5MB, 대역폭 5MB/s, 청크 4KB 이렇게 셋팅한 3가지 규칙을 OBS한테 통보하는 함수입니다.
This is a function that notifies OBS of three rules set to 5MB buffer, 5MB/s bandwidth, and 4KB chunks as soon as the handshake is finished.
1) Window Acknowledgement Size – type 0x05
— obs가 서버에게 5Mbyte씩 데이터 보내고 Ack기다리라는 셋팅 값을 obs에게 전송 하는 부분입니다.
This is the part where a setting value is sent to OBS to send data to the server in 5Mbyte chunks and wait for an ACK.
— window라는 의미는 Tcp Sliding window에서 온 말이며 메세지 크기를 창문의 크기처럼 표현한 겁니다.
The term “window” comes from “TCP Sliding Window,” and it refers to the message size being expressed like the size of a window.
— 코드에서 빨간색은 헤더 부분입니다. Window Ack,Band with, chunk 모두 공통입니다.
The red parts in the code are the header sections. Window Ack, Band with, and chunk are all common.
1-1. 녹색은 데이터 크기(5M)를 표현할 바이트 수(4byte)입니다.
Green is the number of bytes (4 bytes) to represent the data size (5M).
노랑색은 서버가 OBS에 보내는 메세지 타입입이다. 0x05는 window ack를 의미합니다.
The yellow text indicates the message type the server sends to OBS. 0x05 means a window ack.
4byte는 pkt.insert(pkt.end(), (uint8_t*)&ack, (uint8_t*)&ack + 4);이 코드에 포함되어 있습니다.
4 bytes are included in this code: pkt.insert(pkt.end(), (uint8_t)&ack, (uint8_t)&ack + 4);
pkt.insert(pkt.end(), {00x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00 } );
1-2 htonl()함수를 이용해서 빅엔디언으로 바꿉니다.
Convert to big-endian using the htonl() function.
uint32_t ack = htonl(5000000);
5000000 = 0x004C4B40
리틀엔디안 == PC 메모리(거꾸로저장됨)
Little Endian == PC Memory (stored in reverse order):
40 4B 4C 00
빅엔디언 == 네트워크순서(복구)
Big Endian == Network Order (Recovery) :
00 4C 4B 40
1-3 uint32_t는 4바이트짜리 변수인데, uint8_t*로 바꾸면 1바이트씩 접근 가능합니다.
uint32_t is a 4-byte variable, but if you change it to uint8_t*, you can access it 1 byte at a time.
1-4.pkt에 (uint8_t*)&ack 뒤에 1~4바이트까지 1바이트 씩 읽어서 추가합니다.
Read bytes 1 through 4 one by one and append them to 1-4.pkt after (uint8_t*)&ack.
uint32_t ack = htonl(5000000);
pkt.insert(pkt.end(), (uint8_t*)&ack, (uint8_t*)&ack + 4);
2)ack에 포함시키지 않을 경우 데이터는 아래처럼 표현해도됩니다. 마지막 검은색이 16진수로 5Mbyte를 표현합니다.
If not included in the ack, the data may be expressed as follows. The last black part represents 5 Mbytes in hexadecimal.
pkt.insert(pkt.end(), {
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00,
0x00, 0x4C, 0x4B, 0x40
});
2) 대역폭 / BandWith
1-1. 녹색은 데이터 크기(5M)를 표현할 바이트 수(4byte)입니다. 노랑색은 서버가 OBS에 보내는 메세지 타입입이다. 0x06는 bandwith 메세지 임을 의미합니다.
Green is the number of bytes (4 bytes) to represent the data size (5M). Yellow is the message type the server sends to OBS. 0x06 means it is a bandwidth message.
1-2. 00 4C 4B 40 = 5000000(5Mbyte) + 02(limite type)
1-3 Limite type
00 : hard -> 무조건 지켜야함 / Must be followed unconditionally
01 : soft -> 권장설정 / Recommended settings
02 : Dynamic -> 권장설정 하지만 OBS 전송에 맞춤 / Recommended settings, but customized for OBS transmission
pkt.insert(pkt.end(), {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00});
1-4. htonl()함수를 이용해서 빅엔디언으로 바꿉니다.
Convert to big-endian using the htonl() function.
uint32_t bw = htonl(5000000);
1-5. pkt에 (uint8_t*)&ack 뒤에 1~4바이트까지 1바이트 씩 읽어서 추가합니다.
마지막에 pkt.push_back(0x02); 이렇게 limit type추가해서 5byte를 완성합니다.
Read bytes 1 through 4 one by one and append them to pkt after (uint8_t*)&ack.
Finally, add limit type like pkt.push_back(0x02); to complete the 5 bytes.
pkt.insert(pkt.end(), (uint8_t*)&bw, (uint8_t*)&bw + 4);
pkt.push_back(0x02);
3) Chunk
1-1. 녹색은 데이터 크기(5M)를 표현할 바이트 수(4byte)입니다. 노랑색은 서버가 OBS에 보내는 메세지 타입입이다. 0x01는 chunk 메세지 임을 의미합니다.
Green is the number of bytes (4 bytes) representing the data size (5M). Yellow is the message type the server sends to OBS. 0x01 means it is a chunk message.
pkt.insert(pkt.end(), {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00});
1-2. htonl()함수를 이용해서 빅엔디언으로 바꿉니다. 4096은 RTMP 프로토콜에서 OBS에서 서버로 보낼 메세지 단위 입니다.
Convert to big-endian using the htonl() function. 4096 is the message unit that OBS sends to the server in the RTMP protocol.
uint32_t cs = htonl(4096);
1-3. pkt에 (uint8_t*)&ack 뒤에 1~4바이트까지 1바이트 씩 읽어서 추가합니다.
Reads bytes 1 through 4 one by one and appends them to pkt after (uint8_t*)&ack.
pkt.insert(pkt.end(), (uint8_t*)&cs, (uint8_t*)&cs + 4);
4)Protocol Control Messages 전송하기
Sending Protocol Control Messages
— 위에서 설정된 pkt를 OBS로 전송하고 read_chunk_header(); 함수를 실행합니다.
Send the pkt configured above to OBS and execute the read_chunk_header(); function.
asio::async_write(socket_, asio::buffer(pkt),
[this, self](std::error_code ec, std::size_t) {
if (ec) return;
std::cout << "[Server] Protocol messages sent\n";
read_chunk_header();
});