private void HandlerMessage(Stream message,bool needDispose = true) { var type = message.ReadByte(); AMF0Reader amf = new AMF0Reader(message); switch (type) { case Defines.RM_HEADER_MESSAGETYPE_INVOKE: case Defines.RM_HEADER_MESSAGETYPE_FLEX: case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: amf._ReadUInt32();//skip timestamp goto default; case Defines.RM_HEADER_MESSAGETYPE_VIDEODATA: VideoHandler(message); break; case Defines.RM_HEADER_MESSAGETYPE_AUDIODATA: AudioHandler(message); break; case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE: RawHandler(1, message); break; case Defines.RM_HEADER_MESSAGETYPE_USRCTRL: amf._ReadUInt32();//skip timestamp var usrCtrlType = amf.ReadUInt16(); switch (usrCtrlType) { case 0x29: var keepAliveServer = amf.ReadUInt32(); var keepAlivePeer = amf.ReadUInt32(); Logger.Debug("keepAliveServer:{0},keepAlivePeer:{1}", keepAliveServer, keepAlivePeer); Band.KeepAliveServer = keepAliveServer; break; case 0x22: var syncID = amf.ReadUInt32(); var count = amf.ReadUInt32(); if (Band.FlowSynchronization.ContainsKey(syncID)) { if (Band.FlowSynchronization[syncID].Count + 1 == count) { foreach (var flow in Band.FlowSynchronization[syncID]) flow.SyncDone(); Band.FlowSynchronization[syncID].Clear(); } else { Band.FlowSynchronization[syncID].Add(this); IsWaitingSync = true; } } else { Band.FlowSynchronization[syncID] = new HashSet<Flow> {this}; IsWaitingSync = true; } //Logger.Debug("syncID:{0},count:{1}", syncID, count); break; } break; default: try { var messageBody = RtmpProtocolSerializer.Deserialize(type, amf); switch (type) { case Defines.RM_HEADER_MESSAGETYPE_INVOKE: case Defines.RM_HEADER_MESSAGETYPE_FLEX: string functionName = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION]; Writer.CallbackHandle = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID]; MessageHandler(functionName, messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS]); break; case Defines.RM_HEADER_MESSAGETYPE_NOTIFY: case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: break; default: Logger.WARN("type:{0}\r\n{1}", type, messageBody.ToString()); break; } } catch (Exception) { //do nothing } break; } Writer.CallbackHandle = 0; if(needDispose) message.Dispose(); }
private void HandlerMessage(Stream message, bool needDispose = true) { var type = message.ReadByte(); AMF0Reader amf = new AMF0Reader(message); switch (type) { case Defines.RM_HEADER_MESSAGETYPE_INVOKE: case Defines.RM_HEADER_MESSAGETYPE_FLEX: case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: amf._ReadUInt32(); //skip timestamp goto default; case Defines.RM_HEADER_MESSAGETYPE_VIDEODATA: VideoHandler(message); break; case Defines.RM_HEADER_MESSAGETYPE_AUDIODATA: AudioHandler(message); break; case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE: RawHandler(1, message); break; case Defines.RM_HEADER_MESSAGETYPE_USRCTRL: amf._ReadUInt32(); //skip timestamp var usrCtrlType = amf.ReadUInt16(); switch (usrCtrlType) { case 0x29: var keepAliveServer = amf.ReadUInt32(); var keepAlivePeer = amf.ReadUInt32(); Logger.Debug("keepAliveServer:{0},keepAlivePeer:{1}", keepAliveServer, keepAlivePeer); Band.KeepAliveServer = keepAliveServer; break; case 0x22: var syncID = amf.ReadUInt32(); var count = amf.ReadUInt32(); if (Band.FlowSynchronization.ContainsKey(syncID)) { if (Band.FlowSynchronization[syncID].Count + 1 == count) { foreach (var flow in Band.FlowSynchronization[syncID]) { flow.SyncDone(); } Band.FlowSynchronization[syncID].Clear(); } else { Band.FlowSynchronization[syncID].Add(this); IsWaitingSync = true; } } else { Band.FlowSynchronization[syncID] = new HashSet <Flow> { this }; IsWaitingSync = true; } //Logger.Debug("syncID:{0},count:{1}", syncID, count); break; } break; default: try { var messageBody = RtmpProtocolSerializer.Deserialize(type, amf); switch (type) { case Defines.RM_HEADER_MESSAGETYPE_INVOKE: case Defines.RM_HEADER_MESSAGETYPE_FLEX: string functionName = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION]; Writer.CallbackHandle = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID]; MessageHandler(functionName, messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS]); break; case Defines.RM_HEADER_MESSAGETYPE_NOTIFY: case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: break; default: Logger.WARN("type:{0}\r\n{1}", type, messageBody.ToString()); break; } } catch (Exception) { //do nothing } break; } Writer.CallbackHandle = 0; if (needDispose) { message.Dispose(); } }
public Variant Deserialize(int msgType, AMF0Reader _amf0) { var messageBody = Variant.Get(); var stream = _amf0.BaseStream; //messageBody[Defines.RM_HEADER] = header.GetVariant(); switch (msgType) { case Defines.RM_HEADER_MESSAGETYPE_NOTIFY: messageBody[Defines.RM_NOTIFY, Defines.RM_NOTIFY_PARAMS] = Variant.Get(); while (_amf0.Available) messageBody[Defines.RM_NOTIFY, Defines.RM_NOTIFY_PARAMS].Add(_amf0.ReadVariant()); break; case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_UNKNOWNBYTE] = stream.ReadByte(); messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_PARAMS] = Variant.Get(); while (_amf0.Available) messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_PARAMS].Add(_amf0.ReadVariant()); break; case Defines.RM_HEADER_MESSAGETYPE_FLEX: messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_IS_FLEX] = true; stream.ReadByte(); goto case Defines.RM_HEADER_MESSAGETYPE_INVOKE; case Defines.RM_HEADER_MESSAGETYPE_INVOKE: messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION] = _amf0.ReadShortString(true); messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID] = _amf0.ReadAMFDouble(true); messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS] = Variant.Get(); while (_amf0.Available) messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS].Add(_amf0.ReadVariant()); break; case Defines.RM_HEADER_MESSAGETYPE_FLEXSHAREDOBJECT: if (stream.ReadByte() != 0) throw new NotSupportedException(); goto case Defines.RM_HEADER_MESSAGETYPE_SHAREDOBJECT; case Defines.RM_HEADER_MESSAGETYPE_SHAREDOBJECT: messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_NAME] = _amf0.ReadShortString(); messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_VERSION] = _amf0.ReadUInt32(); messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PERSISTENCE] = _amf0.ReadUInt32()==2; stream.Position += 4; messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PRIMITIVES] = Variant.Get(); while (_amf0.Available) { var primitive = Variant.Get(); primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE] = _amf0.ReadByte(); primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_STRTYPE] = GetSOPrimitiveString(primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE]); uint rawLength = 0; primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_RAWLENGTH] = rawLength = _amf0.ReadUInt32(); long read; switch ((byte)primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE]) { case Defines.SOT_CS_CONNECT: case Defines.SOT_CS_DISCONNECT: break; case Defines.SOT_CS_SET_ATTRIBUTE: read = 0; while (read < rawLength) { var afterRead = stream.Position; var key = _amf0.ReadShortString(); primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD, key] = _amf0.ReadVariant(); read += stream.Position - afterRead; } break; case Defines.SOT_CSC_DELETE_DATA: primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD] = _amf0.ReadShortString(); //read = 0; //while (read < rawLength) //{ // var afterRead = stream.Position; // var key = _amf0.ReadShortString(); // read += stream.Position - afterRead; // primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD].Add(key); //} break; case Defines.SOT_BW_SEND_MESSAGE: primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD] = Variant.Get(); while (_amf0.Available) primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD].Add(_amf0.ReadVariant()); break; default: Logger.FATAL("Invalid SO primitive type. Partial result:{0}",messageBody.ToString()); break; } messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PRIMITIVES].Add(primitive); } break; case Defines.RM_HEADER_MESSAGETYPE_USRCTRL: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE] = _amf0.ReadUInt16(); messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE_STRING] = GetUserCtrlTypeString(messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE]); switch ((ushort)messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE]) { case Defines.RM_USRCTRL_TYPE_STREAM_BEGIN: case Defines.RM_USRCTRL_TYPE_STREAM_EOF: case Defines.RM_USRCTRL_TYPE_STREAM_DRY: case Defines.RM_USRCTRL_TYPE_STREAM_IS_RECORDED: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_STREAMID] = _amf0.ReadUInt32(); break; case Defines.RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_STREAMID] = _amf0.ReadUInt32(); messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_BUFFLEN] = _amf0.ReadUInt32(); break; case Defines.RM_USRCTRL_TYPE_PING_REQUEST: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_PING] = _amf0.ReadUInt32(); break; case Defines.RM_USRCTRL_TYPE_PING_RESPONSE: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_PONG] = _amf0.ReadUInt32(); break; case Defines.RM_USRCTRL_TYPE_UNKNOWN1: case Defines.RM_USRCTRL_TYPE_UNKNOWN2: messageBody[Defines.RM_USRCTRL_UNKNOWN_U32] = _amf0.ReadUInt32(); break; default: throw new InvalidDataException("Invalid user control message:"+messageBody); } break; case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE: messageBody[Defines.RM_CHUNKSIZE] = _amf0.ReadUInt32(); break; case Defines.RM_HEADER_MESSAGETYPE_ACK: messageBody[Defines.RM_ACK] = _amf0.ReadUInt32(); break; case Defines.RM_HEADER_MESSAGETYPE_WINACKSIZE: messageBody[Defines.RM_WINACKSIZE] = _amf0.ReadUInt32(); break; case Defines.RM_HEADER_MESSAGETYPE_PEERBW: messageBody[Defines.RM_PEERBW, Defines.RM_PEERBW_VALUE] = _amf0.ReadUInt32(); messageBody[Defines.RM_PEERBW, Defines.RM_PEERBW_TYPE] = stream.ReadByte(); break; case Defines.RM_HEADER_MESSAGETYPE_ABORTMESSAGE: messageBody[Defines.RM_ABORTMESSAGE] = _amf0.ReadUInt32(); break; case 0: break; default: Logger.FATAL("Invalid message type"); break; } return messageBody; }