欢迎关注公众号:冒泡的肥皂
这篇文章介绍下Command Message(命令消息,Message Type ID=17或20)命令的一个交互流程,命令消息是在数据传输前的一个协商过程。推送消息的时候会带有命令的名字,接收端收到命令后,会返回以下三种消息中的一种:_result接收、_error拒绝、method name调用的执行函数,携带TransactionId
命令消息
1.connect
2.Call
3.createStream
4.onStatus
5.play
6.play2
7.deleteStream closeStream
8.receiveVideo
9.publish
10.seek
11.pause
connect:用于客户端向服务器发送连接请求,消息的结构如下:
| 字段 | 类型 | 说明 |
|---|---|---|
| Command Name(命令名字) | String | 命令的名字,如”connect” |
| Transaction ID(事务ID) | Number | 恒为1 |
| Command Object(命令包含的参数对象) | Object | 键值对集合表示的命令参数 |
| Optional User Arguments(额外的用户参数) | Object | 用户自定义的额外信息 |
第三个字段中的Command Object中会涉及到很多键值对,这里不再一一列出,使用时可以参考协议的官方文档。
客户端向服务器发送connect消息之后,服务器向客户端发送了Window Acknowledgement Size和
Set Peer Bandwidth消息
消息的回应有两种,_result表示接受连接,_error表示连接失败,
Window Acknowledgement Size用来通知对端,如果收到该大小字节的数据,需要回复一个Acknowledgement消息,也就是ACK
Set Peer Bandwidth该消息里设置对端输出带宽。刚开始建立连接,服务器向客户端发送Set Peer Bandwidth消息,客户端第一次收到Set Peer Bandwidth消息,之前没有发送过Window Acknowledgement Size,所以在这里向服务端发送一次消息。
connect日志
21:55:05.139 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - << [STRING connect]
21:55:05.140 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - << [NUMBER 1.0]
21:55:05.140 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - << [STRING live]
21:55:05.140 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - << [STRING nonprivate]
21:55:05.141 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - << [STRING FMLE/3.0 (compatible; FMSc/1.0)]
21:55:05.141 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - << [STRING rtmp://127.0.0.1/live]
21:55:05.141 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - << [STRING rtmp://127.0.0.1/live]
21:55:05.141 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - << [OBJECT {app=live, type=nonprivate, flashVer=FMLE/3.0 (compatible; FMSc/1.0), swfUrl=rtmp://127.0.0.1/live, tcUrl=rtmp://127.0.0.1/live}]
connect交互
private void handleConnect(ChannelHandlerContext ctx, RtmpCommandMessage msg) {
// client send connect
// server reply windows ack size and set peer bandwidth
String app = (String) ((Map) msg.getCommand().get(2)).get("app");
Integer clientRequestEncode = (Integer) ((Map) msg.getCommand().get(2)).get("objectEncoding");
if(clientRequestEncode !=null && clientRequestEncode.intValue()==3) {
log.error("client :{} request AMF3 encoding but server currently doesn't support",ctx);
ctx.close();
return ;
}
streamName = new StreamName(app, null,false);
//接收大小触发应答
int ackSize = 5000000;
WindowAcknowledgementSize was = new WindowAcknowledgementSize(ackSize);
//传输速率
SetPeerBandwidth spb = new SetPeerBandwidth(ackSize, RtmpDict.SET_PEER_BANDWIDTH_TYPE_SOFT);
SetChunkSize setChunkSize = new SetChunkSize(5000);
ctx.writeAndFlush(was);
ctx.writeAndFlush(spb);
ctx.writeAndFlush(setChunkSize);
List<Object> result = new ArrayList<Object>();
result.add("_result");
result.add(msg.getCommand().get(1));// transaction id
result.add(new Amf0Object().addProperty("fmsVer", "FMS/3,0,1,123").addProperty("capabilities", 31));
result.add(new Amf0Object().addProperty("level", "status").addProperty("code", "NetConnection.Connect.Success")
.addProperty("description", "Connection succeeded").addProperty("objectEncoding", 0));
RtmpCommandMessage response = new RtmpCommandMessage(result);
ctx.writeAndFlush(response);
}
connect应答日志
21:55:05.146 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [STRING _result]
21:55:05.146 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [NUMBER 1.0]
21:55:05.146 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [OBJECT {fmsVer=FMS/3,0,1,123, capabilities=31}]
21:55:05.147 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [STRING FMS/3,0,1,123]
21:55:05.147 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [NUMBER 31]
21:55:05.147 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [OBJECT {level=status, code=NetConnection.Connect.Success, description=Connection succeeded, objectEncoding=0}]
21:55:05.147 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [STRING status]
21:55:05.147 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [STRING NetConnection.Connect.Success]
21:55:05.147 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [STRING Connection succeeded]
21:55:05.147 [nioEventLoopGroup-2-2] INFO c.p.r.a.AMF0 - >> [NUMBER 0]