RTMP (Real Time Messaging Protocol)
Adobe에서 개발한 독점 컴퓨터 통신 규약. audio video 및 기타 data를 인터넷을 통해 스트리밍할 때 쓰인다. 별도의 Adobe flash player가 있어야 사용가능하다. 다음과 같은 여러 종류가 있다
- RTMP : 1935 포트 사용(기본값), 암호화 X
- RTMPT : RTMP Tunneled, RTMP를 HTTP로 감싼 것
- RTMPS : RTMP Secure, RTMP를 HTTPS로 감싼 것
- RTMPE : Encrypted RTMP, 128bit로 암호화된 RTMP. SSL보다 가벼우나 SSL인증이 없음
- RTMPTE : RTMPT와 RTMPE를 섞어 놓은 형태
- RTMFP : Real Time Media Flow Protocol : UDP에서 동작. 항상 암호화된 상태로 데이터를 전송
Adobe사에서 RTMP에 대한 specification을 제공 링크
RTMP Chunk stream
provides multiplexing, packetizing services for a higher-level multimedia stream protocol
Message Format
message 자체는 chunk로 쪼개져서 higher level protocol에서의 multiplexing을 지원할 수 있다. 하지만 chunk를 만들 때에는 다음과 같은 message format을 지켜서 만들어야한다.
- Timestamp: message의 timestamp (4bytes)
- Length : message payload의 length. message header를 지울 수 없으면 length에 포함되어야 한다. chunk header에서 3bytes의 공간을 차지한다
- Type Id: protocol control message를 위해 예약된 type ID의 범위가 정해져 있다. 이 message는 RTMP chunk stream과 higher-level protocol 둘다 다루는 정보이다. 이범위 밖의 다른 유형의 ID에 대해서는 higher-level protocol에서만 다루도록 되어 있다. 즉 higher-level protocol에 따라 type이 아닌 다른 정보로도 사용가능하다. chunk header에서 1byte를 차지한다.
- Message Stream ID : 임의의 값을 사용할 수 있다. 다른 message Stream이 같은 chunk에 multiplexing됐을 때 message stream ID를 통해서 demultiplexed된다. RTMP Chunk Stream level에서는 opaque value이다. chunk header에서 4byte를 차지한다.
Handshake
RTMP 연결은 handshake부터 시작한다. handshake는 나머지 protocol과는 상당히 다른 모습인데, header뒤에 가변길이의 chunk가 있는 모양새와는 다르게 3개의 고정된 길이의 chunk를 사용한다.
client와 server사이에서 3개의 chunk를 서로에게 보냄으로써 이뤄진다. 설명을 위해 client에서 server로 보내는 chunk를 C0, C1, C2라고 하고 server에서 client로 보내는 chunk를 S0, S1, S2라고 하자.
Handshake Sequence
Handshake는 client가 C0와 C1 chunk를 보냄으로써 시작한다.
Client는 반드시 C2를 보내기 전에 S1을 받아야하며 S2를 받기 전까지 어떤 data도 전송을 시작할 수 없다.
Server는 반드시 S0와 S1을 보내기 전에 C0를 받아야 하며 마찬가지로 S2를 보내기 전에 C1을 기다려야한다. C2를 받기 전까지는 어떤 data도 전송을 시작할 수 없다.
C0 and S0 Format
C0와 S0 packet은 singleoctet으로 8-bit interger field로 다뤄진다
image(C0 and S0 bits)
C0/S0 packet에 있는 filed는 다음과 같다.
Version (8 bits) : C0에서는 client에서 요청하는 RTMP의 version을 의미한다. S0에서는 server에 의해 선택된 RTMP version을 의미한다. 보통 3으로 정의되어 있다. 0-2는 deprecated값이고 4-31은 미래 구현을 위해 예약된 값이다. 32-255는 허용되지 않는다. (text-based protocol과 RTMP를 구분하기 위해서 그런다고 함) server가 client의 version을 잘 모르겠으면 3으로 respond해야한다. client는 version 3를 선택하거나 handshake를 포기할 것이다.
C1 and S1 Format
C1과 S1 packet은 1536 octet길이로 다음과 같은 field를 포함하고 있다.
C1, S1 picture
Time (4 bytes) : timestamp로 이후 오는 chunk의 기준이 된다. 값은 0 혹은 임의의 숫자를 가진다. 여러개의 chunk stream을 동기화하기 위해서는 다른 chunk stream의 timestamp 값이 필요하다.
Zero (4 bytes) : 전부 0의 값을 가진다.
Random data (1528 bytes) : 임의의 값을 가질 수 있는 field. 동적값이나 암호화 보안을 필요로 하지는 않지만. 다수의 peer가 연결되는 과정에서 각 peer에 대한 구분을 위해 충분히 랜덤한 값이 필요하다.
C2 and S2 Format
C2와 S2 packetdms 1536 octet길이로 사실상 거의 S1과 C1의 echo에 가깝다. 다음과 같은 field를 포함하고 있다.
C2, S2 picture
Time (4 bytes) : C2의 경우 S1, S2에 경우 C1에서 보내준 timestamp 값을 그대로 사용한다.
Time2 (4 bytes) : C2의 경우 S1, S2에 경우 C1에서 보내준 timestamp 값이 읽혔을 때의 값을 넣는다.
Random echo (1528 bytes) : C2의 경우 S1, S2의 경우 C1보내준 random 값을그대로 사용한다.
time2와 time field의 값 및 현재의 timestamp 값을 통해서 bandwidth나 connection의 latency를 estimate 할 수 있지만 크게 유용하지는 않다.
Handshake Diagram
Handshake picture
Uninitialized : client 가 C0에 version을 넣어서 전달, server가 지원가능한 버전이면 S0, S1을 response로 보냄. 지원을 하지 않을 경우 connection이 종료됨
Version Sent : Client가 S1 packet을 기다리고 있고, Server가 C1 packet을 기다리고 있는 상태. Client가 S1 packet을 받으면 C2 packet을 보내고 Server가 C1 packet을 받으면 S2 packet을 보낸다. 이후 State는 Ack Sent 상태로 전환된다.
Ack Sent : client와 Server가 S2와 C2를 기다리고 있는 상태
Handshake Done : client와 server가 message 교환을 시작한다.
Chunking
handshaking이 끝난 뒤에 connection에 하나 이상의 chunk stream을 multiplex해서 보낸다. 각 chunk stream은 하나의 message stream의 하나의 type에 대한 message를 전달한다. 각 chunk는 chunk stream ID라고 부르는 것과 연관된 unique ID를 생성합니다. 각 chunk를 네트워크를 통해서 전달 할 때 각 chunk는 다음 chunk가 도착하기 전에 도착해야합니다. receiver에서는 chunk가 chunk stream ID에 기반하여 message로 합쳐집니다.
chunking은 큰 message를 higher-level protocol에서는 큰 message를 작게 쪼개서 보내는 걸 허용하는데 이를 통한 예시로 video 같이 크고 우선 순위가 낮은 message가 우선 순위가 높지만 크기는 작은 audio나 control message를 blocking하는 것을 방지 할 수있습니다.
chunking을 통해서 작은 크기의 메세지를 낮은 오버헤드로 보내는 것 또한 허용됩니다. chunk header에 압축 관련 정보를 포함하기 때문에
chunk size는 조정가능합니다. 후에 얘기하게 될 Set Chunk Size control message를 통해 설정할 수 있습니다. chunk size가 클 수록 CPU 사용량은 줄어들지만 낮은 bandwidth에서는 오히려 다른 contents의 delay가 일어날 수 있습니다. 그렇다고 너무 작은 chunk는 high-bitrate streaming에서 좋지 않습니다.
Chunk Format
각 chunk는 header와 data를 포함합니다. header는 세 부분으로 이뤄져있습니다.
Chunk Format picture
Basic Header (1 to 3 bytes) : chunk stream ID와 chunk type을 encode 하는 field. chunk type이 encode된 message header의 format을 결정한다. length는 전적으로 가변 길이 영역인 chunk stream ID에 따른다.
Message Header (0, 3, 7, or 11 bytes) : message가 전체가 왔는지 혹은 쪼개서 왔는지에 대한 infromation을 encode한 filed. length는 chunk header에 있는 chunk type을 사용하여 결정될 수 있다.
Extended Timestamp (0 or 4 bytes): chunk message header인코딩 된 timestamp 또는 timestamp delta filed에 따라 특정 상황에 존재하는 field
Chunk Data (variable size) : chunk의 payload
Chunk Basic Header
Chunk type이 encode된 message header의 format을 결정한다. Chunk Basic Header filed는 1,2,3 byte가 가능하며 chunk stream ID에 depend한다.
Protocol이 3-65599의 ID를 가진 65597개의 Stream까지 지원이 가능하다. ID 0,1,2는 예약되어있다. 0은 2byte form을 의미하며 ID의 range는 64-319임을 의미한다.. value 1은 3byte form을 의미하며 ID의 range가 64-65599임을 의미(ID는 다음과 같이 나타내어진다 : third byte * 256 + second byte + 64)한다. 3-63의 값은 complete stream ID를 나타낸다. value 2를 가진 chunk stream ID는 low-level protocol control message와 command 를 위해 예약되어있다.
Chunk basic header 1
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|fmt| cs id |
+-+-+-+-+-+-+-+-+
Chunk basic header 2
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|fmt| 0 | cs id - 64 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk basic header 2
0 1 2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|fmt| 0 | cs id - 64 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
cs id (6 bits) : chunk stream ID를 포함한 field, 2-63의 value를 가짐. 0 이나 1의 value의 경우에 이 field의 크기가 2 또는 3byte이다.
-
fmt (2 bits) : ‘chunk message header’에 쓰이는 4 format 중 하나를 나타낸다. chunk message header의 4가지 format은 fmt field에 의해서 선택된다.
-
cs id - 64 (8 or bits) : chunk stream ID에 64를 뺀 값이다. 예를 들어 365인경우 16bit의 301이 쓰여진다.
Type 0
Type 0 chunk headers 11 byte의 길이이다. 이 타입은 chunk stream의 처음에 사용되거나 timestamp가 반대로 갈때 사용되어야한다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |message length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| message length (cont) |message type id| msg stream id |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| message stream id (cont) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
timestamp (3 bytes) : type-0 chunk경우에 message의 timestamp의 절대값이 포함되어 있다. timestamp가 만약 1677215 (0xFFFFFF) 값보다 크거나 같으면 field의 값은 무조건 16777215이어야하고 Extended Timestamp field가 존재해야함을 시사한다.
Type 1
Type 1 chunk의 header 길이는 7 byte이다. message stream ID는 포함되지 않는다. 이 chunk는 이전 chunk랑 동일한 stream ID를 사용한다. 크기가 다양한 Message의 stream의 경우 첫 번째 chunk이후에 이 format을 사용해야한다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |message length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| message length (cont) |message type id|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Type 2
Type 2의 chunk header 길이는 3byte이다. stream ID, message길이 둘다 포함되지 않는다. 이 chunk의 경우 이전 chunk와 동일한 stream ID 및 message 길이를 갖는다. 일정한 크기의 메시지가 있는 스트림은 첫 번째 메시지 이후 이 형식을 사용해야한다.
0 1 2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Type 3
Type 3 chunk는 message header가 없다. stream ID, message length, timestamp delta filed 전부 없다. 이 유형의 chunk는 이전 chunk와 동일한 chunk stream id를 가진다. single message가 chunk로 나뉘었을 때는 첫번째를 제외한 모든 chunk는 이 타입을 사용해야한다. 정확히 같은 크기, 스트림 ID 및 동일한 시간 간격의 message로 구성된 stream은 type2의 chunk이후의 모든 chunk에 대해서 이런 유형을 사용해야한다. 만약 type 3가 type 0 다음에 오는 경우 type 3의 timestamp는 type 0의 timestamp와 동일하다.
Common Header Fields
chunk message header의 각 field에 대한 설명
timestamp delta (3 bytes) : type-1과 type-2 chunk에서 이전 chunk의 timestamp와 timestamp delta값을 나타낸다. delta값이 16777215 (0xFFFFFF)보다 크거나 같을 경우 field값은 16777215이고 Extended Timestamp가 있음을 나타낸다.
message length (3 bytes) : type-0 또는 type-1 chunk의 경우 message의 길이를 나타낸다. chunk payload의 길이 값과 일반적으로 같은 값은 아니다. chunk payload의 길이는 마지막 chunk를 제외한 모든 chunk의 최대 크기와 마지막 chunk의 크기이이다.
message type id (1 byte) : type-0 또는 type-1 chunk의 message의 type을 나타낸다.
message stream id (4 bytes) : type-0 chunk에서 message stream ID를 나타낸다. 일반적으로 동일한 chunk stream의 모든 message는 동일한 message stream에서 나온다. 별도의 message stream을 동일한 chunk stream으로 multiplex하는 것이 가능하기는 하지만 헤더 압축 측면에서 이점이 사라진다.
Extended Timestamp
Extended Timestamp는 timestamp 혹은 timestamp delta가 16777215 (0xFFFFFF)보다 큰 값을 가질 때 사용되는 field이다.
Protocol Control Messages
RTMP Chunk Stream은 messgae Type ID 1,2,3,5,6을 protocol control message로 사용한다. 이런 메세지들은 RTMP Chunk Stream protocol에서 필요한 정보를 담고 ㅇㅆ다.
이런 protocol control message는 message stream ID 0과 chunk stream ID 2를 가져야한다. Protocol control message는 받는 즉시 실시해야한다. timestamp는 무시된다.
Set Chunk Size (Message Type ID == 1)
Set Chunk Size는 새로운 maximum chunk size를 peer에게 알리기 위해 사용된다.
maximum chunk size의 기본값은 128byte이지만, client나 server가 이 값을 바꿔서 서로에게 message를 통해 업데이트 할 수 있다. maximum chunk size는 보통 최소 128byte의 값을 가지며 최소한 1byte는 넘어야한다.
‘Set Chunk Size’ protocol message의 payload
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0| chunk size (31 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0: 이 bit 값은 0이어야 한다.
chunk size (31 bits) : 새로운 maximum chunk size를 가지고 있는 field로 단위는 byte이다. 사용가능한 값의 범위는 1에서 2147483647 (0x7FFFFFFF)이다.
Abort Message (Message Type ID == 2)
Protocol control message 2, Abort Message는 message를 완성하기 위해서 chunk를 기다리고 있는 peer에게 부분적으로 받아놓은 chunk stream을 드랍하도록 알려주는 message이다. message의 payload에 chunk stream ID가 있어서 이를 통해서 peer가 어떤 message를 드랍해야하는지 알 수 있다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| chunk stream id (32 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Acknowledgement (Message Type ID == 3)
client 와 server는 widow size와 같은 크기의 byte를 받았을 때 반드시 peer에게 acknowledgement를 보내야한다. window size는 sender가 acknowledgement를 받지 않고 보낼 수 있는 최대 크기의 byte를 말한다. 이 message는 다음과 같은 정보를 포함한다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| sequence number (32 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
sequence number : 받은 byte 크기에 대한 정보를 담고 있다.
Window Acknowledgement Size (Message Type ID == 5)
client 또는 server는 이 메세지를 통해서 peer에게 acknowledgement를 보내기 위한 window size를 알려준다. sender는 acknowledgement를 sender가 window size 크기를 보낸 이후에 예측한다. 메세지를 받는 peer는 Acknowledgement받은 적이 없거나 Acknowledgement보낸 이후에 이와 일치하는 크기의 byte가 들어왔을 때 반드시 Acknowledgement보내야 한다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgement Window size (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Set Peer Bandwidth (Message Type ID == 6)
client 또는 server는 이 메세지를 peer의 output bandwidth를 제한하기 위해서 사용한다. 이 메세지를 받은 peer는 Window Acknowledgement Size message와 함께 window size가 최근의 것과 동일한지 보내줄 필요가 있다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgement Window size (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Limit Type |
+-+-+-+-+-+-+-+-+
Limit Type는 다음 값 중에 하나를 가진다
-
0 - Hard : peer가 제시된 window size에 맞춰서 output bandwidth를 조정할 필요가 있다.
-
1 - Soft : peer가 제시된 window size에 맞춰서 output bandwidth를 조정하거나 이미 적용중인 limit값중 더 작은것으로 조정할 필요가 있다.
-
2 - Dynamic : 이전 요청이 Hard이면 Hard처럼 메세지를 처리하고 그렇지 않으면 메세지를 무시한다.
RTMP Message Formats
RTMP Chunk Stream을 transport layer로 가지는 RTMP message에 대해서 알아보자.
RTMP Message Format
RTMP message는 크게 두가지 파트로 나뉜다 header와 payload
Message Header
message header는 다음과 같은 정보를 포함한다
-
Message Type : 1byte field로 message type을 나타낸다. 1-6까지는 protocol control message를 위한 예약어이다.
-
Length : 3bytes field로 payload의 길이를 나타낸다.
-
Timestamp : 4 bytes field로 message의 timestamp를 가진다.
-
Message Stream Id : 3 bytes field로 message의 stream을 구분하는데 사용된다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message Type | Payload length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Stream ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Message Payload
payload는 실제 data를 가지고 있는 부분이다.
User Control Messages (Message Type ID == 4)
RTMP 는 message type 4를 User Control Message로 사용한다.
User Control Message는 message stream ID는 0 RTMP Chnk Stream을 통해서 보낼 때 chunk stream ID는 2를 사용한다. User Control Message는 도착한 순간 바로 적용되며 timestamp는 무시된다.
User Control protocol message는 다음과 같이 생겼다
+------------------------------+----------------------------
| Event Type (16 bits) | Event Data
+------------------------------+----------------------------
처음 2 byte는 Event type을 구분하기 위해 사용된다. Event data에 따라 Event Type이 결정되는데 Event Data field의 크기는 일정하지 않다. 한편 RTMP Chunk Stream layer를 통해서 data가 전달될 때 maximum chunk sizea는 모든 message가 들어갈 수 있을 정도로 충분히 커야 한다.
RTMP Command Messages
server와 client사이에서 주고받는 데이터에는 다양한 유형이 있다.
- audio data
- video data
- user data
- shared object message
- command message
shared object message는 여러 client와 server간에 distributed data를 관리하는 방법을 제공한다. command message의 경우에는 AMF로 encode된 command를 client와 server사이에서 전달한다. client와 server는 이를 RPC로써 사용할 수 있다.
Types of Messages
Command Message (Message Type == 20 ,17)
Command massage는 AMF-encode된 commands를 client와 server사이에서 전달한다. 이 메세지는 message type 값 20을 AMF0 encoding에 사용하며 message type 값 17을 AMF3 encoding에 사용한다. message의 종류로는 connect, createStream, publish, play, pause 와 같은 operation과 onstatus, result와 같이 sender에게 status를 제공해 주기 위한 message가 있다. command message는 command name, transaction ID, 그리고 command와 관련된 parameter를 가지고 있는 command object로 이루어져있다.
Data Message (Message Type == 18, 15)
Metadata나 user data를 peer에게 보낼 때 사용하는 message이다. Metadata는 audio,video 등의 Data와 관련된 정보를 포함하는데, creation time, duration, theme 과 같은 정보가 있다. Data Message에서 message type value 18은 AMF0, message type value 15은 AMF3를 사용한다.
Shared Object Message (Message Type == 19, 16)
shared object는 Flash object(name value pair의 collection)로 여러 client, instance사이에서 동기화된다. message types 19은 AMF0 16은 AMF3를 사용합니다. 각 message는 여러개의 event를 가질 수 있다.
+------+------+-------+-----+-----+------+-----+-+-----+------+-----+
|Header|Shared|Current|Flags|Event|Event |Event|.|Event|Event |Event|
| |Object|Version| |Type |data |data |.|Type |data |data |
| |Name | | | |length| |.| |length| |
+------+------+-------+-----+-----+------+-----+-+-----+------+-----+
| |
|<---------------------------------------------------------->|
| AMF Shared Object Message body |
shared object message format
다음 과 같은 event type이 사용가능하다
Event | Description |
---|---|
Use (=1) | shared object를 만들었음을 server에게 알리기 위해 client가 보내는 event |
Release (=2) | shared object가 client side에서 지워졌을 때 client가 server에게 보내는 event |
Request Change (=3) | shared object내의 parameter namer과 관련된 값을 변경하고자 할때 보내는 event |
Change (=4) | named parameter가 변했음을 나머지 client에게 알려주는 event |
Success (=5) | Request Change에 대해서 request가 성공하면 client에게 보내주는 event |
SendMessage (=6) | client가 server에게 broadcast하고자 하는 message를 보낼때 쓰는 event |
Status (=7) | server가 client에게 error condition에 대한 것을 알리고자할 때 보내는 event |
Clear (=8) | shared object를 clear하고자 할때, 혹은 Use event에 대한 response로 보내는 event |
Remove (=9) | client가 slot을 지우도록 server가 보내는 event |
Request Remove (=10) | client가 slot을 지우도록 client가 보내는 event |
Use Success(=11) | client가 successful connectin에 있을 때 server가 보내는 event |
Audio Message (Message Type == 8)
client 혹은 server가 audio data를 보내기 위해서 사용하는 메세지. message type은 8이다.
Video Message (Message Type == 9)
client 혹은 server가 video data를 보내기 위해서 사용하는 메세지. message type은 9이다.
Aggregate Message (Message Type == 22)
RTMP sub-message를 series로 가지고 있는 single message가 aggregate message이다. Message type은 22가 사용된다.
+---------+------------------------+
| Header | Aggregate Message body |
+---------+------------------------+
Aggregate Message body format
+--------+-------+---------+---------+-------+----------+ - - - -
|Header 0|Message|Back |Header 1 |Message|Back |
| |Data 0 |Pointer 0| |Data 1 |Pointer 1 |
+--------+-------+---------+---------+-------+----------+ - - - -
pack pointer는 이전 message의 header까지 포함한 size를 가진다.
User Control Message Events
다음과 같은 user control event type이 지원된다.
Event | Description |
---|---|
Stream Begin (=0) | server가 client에게 보내는 event로 stream이 동작하고 communication에 사용될 수 있음을 알려줌. 기본적으로, client가 application connection command를 성공적으로 받고 난뒤 stream ID 0으로 보내진다. event data는 4byte로 사용가능한 stream의 stream ID를 나타낸다. |
Stream EOF (=1) | server가 client에게 보내는 event로 stream에 대해서 요청한 playback data가 끝났음을 알려줌. 추가적인 command가 없이는 data가 더 들어오지 않는다. 4byte의 event data는 끝난 playback stream의 ID를 나타낸다. |
StreamDry (=2) | stream에 data가 없음을 보낼때 server가 client에게 보내는 event. 일정 시간동한 server가 message를 찾지못하면 client에게 stream이 dry상태에 있다고 알려줄 수 있다. 4byte의 event data는 dry stream의 stream ID를 나타낸다. |
SetBufferLength (=3) | client가 server에게 stream을 통해 오는 data를 버퍼링하는데 사용되는 버퍼의 크기(millisecond)를 알려주기 위해 보내는 event. 서버가 stream처리를 시작하기 전에 전송된다. event data의 첫 4byte는 stream ID를 나타내고 다음 4byte가 buffer 길이(millisecond)를 나타낸다 |
StreamIsRecorded (=4) | server가 client에게 stream이 recorded streamd임을 알리기 위해 보내는 event. event data의 4byte는 recorded stream의 stream ID를 나타낸다. |
PingRequest (=6) | client에 접근 가능한지 확인하기위해 사용하는 event. Event data는 4byte의 timestamp로 command를 보낼때의 로컬 server 시간을 나타낸다. client는 이에 대한 응답으로 PingResponse를 보낸다. |
PingResponse (=7) | PingRequest에 대한 response. event Data는 PingRequest와 동일한 data를 그대로 보낸다 |
Types of Commands
client와 server는 AMF로 인코딩된 명령을 주고 받는다. sender는 command name, transaction ID 그리고 관련된 parameter를 가진 command object를 포함한 command messge를 보낸다. 예를 들면, conncet command의 경우 ‘app’이라는 parameter를 가지며 이는 server application에게 연결해야하는 client의 이름을 알려준다. recevier는 command를 수행하고 같은 transaction ID로 response를 보낸다. response string은 _result, _error 또는 method 이름(Ex. verifyClient, contactExternalServer)이다. _result 또는 _error의 command string은 response를 나타낸다. transaction은 ID는 응답이 참조하는 미해결 command를 나타낸다. method name의 경우 receiver에서 주어진 method를 실행하려고 함을 나타낸다. 다음 class object는 다양한 command를 보내기 위해 사용된다.
- Netconnection : server와 client사이의 connection을 higher-level로 감싼 object
- NetStream : audio stream, video stream 혹은 다른 data stream channel을 나타내는 object.
NetConnection Commands
NetConnection은 client와 server간의 양방향 통신을 관리한다. 추가적으로 비동기 remote method call도 지원한다.
다음과 같은 명령어를 사용할 수 있다
- connect
- call
- close
- createStream
NetStream Commands
Netstream은 audio, video, data message의 streaming channel을 정의한다. 사용가능한 명령어는 다음과 같다. (client에서 서버로)
- play
- play2
- deleteStream
- closeStream
- receiveAudio
- receiveVideo
- publish
- seek
- pause
server는 NetStream의 상태 업데이트를 client의 onStatus command를 통해 수행한다.