Beispiel #1
0
        protected RtmpMessage ReadCommandOrData(AmfReader r, Command command, RtmpHeader header = null)
        {
            var    methodName = (string)r.ReadAmf0Item();
            object temp       = r.ReadAmf0Item();

            if (header != null && methodName == "@setDataFrame")
            {
                command.ConnectionParameters = temp;
            }
            else
            {
                command.InvokeId             = Convert.ToInt32(temp);
                command.ConnectionParameters = r.ReadAmf0Item();
            }


            var parameters = new List <object>();

            while (r.DataAvailable)
            {
                parameters.Add(r.ReadAmf0Item());
            }

            command.MethodCall = new Method(methodName, parameters.ToArray());
            return(command);
        }
Beispiel #2
0
        public RtmpPacket CreatePacket(Notify notify)
        {
            var header = new RtmpHeader
            {
                ChannelId = 3,
                DataType  = notify.DataType,
                Timer     = notify.Timestamp
            };

            return(new RtmpPacket(header, notify));
        }
        public void Queue(RtmpMessage message, int streamId, int messageStreamId)
        {
            var header = new RtmpHeader();
            var packet = new RtmpPacket(header, message);

            header.StreamId        = streamId;
            header.Timestamp       = message.Timestamp;
            header.MessageStreamId = messageStreamId;
            header.MessageType     = message.MessageType;
            _packetQueue.Enqueue(packet);
            _packetAvailableEvent.Set();
        }
        static ChunkMessageHeaderType GetMessageHeaderType(RtmpHeader header, RtmpHeader previousHeader)
        {
            if (previousHeader == null || header.MessageStreamId != previousHeader.MessageStreamId || !header.IsTimerRelative)
            {
                return(ChunkMessageHeaderType.New);
            }

            if (header.PacketLength != previousHeader.PacketLength || header.MessageType != previousHeader.MessageType)
            {
                return(ChunkMessageHeaderType.SameSource);
            }

            if (header.Timestamp != previousHeader.Timestamp)
            {
                return(ChunkMessageHeaderType.TimestampAdjustment);
            }

            return(ChunkMessageHeaderType.Continuation);
        }
 protected override void OnServerBW(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ServerBW serverBw)
 {
 }
 protected override void OnClientBW(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ClientBW clientBw)
 {
     channel.Write(new ServerBW(clientBw.Bandwidth));
 }
 protected override void OnChunkSize(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ChunkSize chunkSize)
 {
     //ChunkSize is not implemented yet
 }
        protected override void OnPing(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, Ping ping)
        {
            switch (ping.PingType)
            {
            case Ping.PingClient:
            case Ping.StreamBegin:
            case Ping.RecordedStream:
            case Ping.StreamPlayBufferClear:
                // The server wants to measure the RTT
                Ping pong = new Ping();
                pong.PingType = Ping.PongServer;
                // The event data is a 4-byte timestamp, which was received with the in the Ping request
                pong.Value2 = ping.Value2;
                connection.Ping(pong);
                break;

            case Ping.StreamDry:
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("Stream indicates there is no data available");
                }
#endif
                break;

            case Ping.ClientBuffer:
                //Set the client buffer
                IClientStream stream = null;
                //Get the stream id
                int streamId = ping.Value2;
                //Get requested buffer size in milliseconds
                int buffer = ping.Value3;
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(string.Format("Client sent a buffer size: {0} ms for stream id: {1}", buffer, streamId));
                }
#endif
                if (streamId != 0)
                {
                    // The client wants to set the buffer time
                    stream = connection.GetStreamById(streamId);
                    if (stream != null)
                    {
                        stream.SetClientBufferDuration(buffer);
#if !SILVERLIGHT
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug(string.Format("Setting client buffer on stream: {0}", streamId));
                        }
#endif
                    }
                }
                //Catch-all to make sure buffer size is set
                if (stream == null)
                {
                    // Remember buffer time until stream is created
                    connection.RememberStreamBufferDuration(streamId, buffer);
#if !SILVERLIGHT
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug(string.Format("Remembering client buffer on stream: {0}", streamId));
                    }
#endif
                }
                break;

            default:
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(string.Format("Unhandled ping: {0}", ping));
                }
#endif
                break;
            }
        }
            /// <summary>
            /// Gets a header with the appropriate timestamp.
            /// </summary>
            /// <param name="dataType">Type of the event.</param>
            /// <param name="eventTime">The event time.</param>
            /// <returns></returns>
            public RtmpHeader GetTimeStamp(byte dataType, int eventTime)
            {
                RtmpHeader header = new RtmpHeader();

#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                {
                    log.Debug(string.Format("GetTimeStamp - event time: {0} last event: {1} audio: {2} video: {3} data: {4}", eventTime, _lastEventTime, _lastAudioTime, _lastVideoTime, _lastNotifyTime));
                }
#endif
                switch (dataType)
                {
                case Constants.TypeAudioData:
                    if (_lastAudioTime > 0)
                    {
                        //set a relative value
                        header.Timer = eventTime - _lastAudioTime;
#if !SILVERLIGHT
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("Relative audio");
                        }
#endif
                    }
                    else
                    {
                        //use absolute value
                        header.Timer           = eventTime;
                        header.IsTimerRelative = false;
#if !SILVERLIGHT
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("Absolute audio");
                        }
#endif
                    }
                    _lastAudioTime = eventTime;
                    break;

                case Constants.TypeVideoData:
                    if (_lastVideoTime > 0)
                    {
                        //set a relative value
                        header.Timer = eventTime - _lastVideoTime;
#if !SILVERLIGHT
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("Relative video");
                        }
#endif
                    }
                    else
                    {
                        //use absolute value
                        header.Timer           = eventTime;
                        header.IsTimerRelative = false;
#if !SILVERLIGHT
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("Absolute video");
                        }
#endif
                    }
                    _lastVideoTime = eventTime;
                    break;

                case Constants.TypeNotify:
                case Constants.TypeInvoke:
                case Constants.TypeFlexStreamEnd:
                    if (_lastNotifyTime > 0)
                    {
                        //set a relative value
                        header.Timer = eventTime - _lastNotifyTime;
#if !SILVERLIGHT
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("Relative notify");
                        }
#endif
                    }
                    else
                    {
                        //use absolute value
                        header.Timer           = eventTime;
                        header.IsTimerRelative = false;
#if !SILVERLIGHT
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("Absolute notify");
                        }
#endif
                    }
                    _lastNotifyTime = eventTime;
                    break;

                case Constants.TypeBytesRead:
                case Constants.TypePing:
                    header.Timer           = eventTime;
                    header.IsTimerRelative = false;
                    break;

                default:
                    // ignore other types
#if !SILVERLIGHT
                    if (log.IsDebugEnabled)
                    {
                        log.Debug(string.Format("Unmodified type: {0} timestamp: {1}", dataType, eventTime));
                    }
#endif
                    break;
                }
#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                {
                    log.Debug(string.Format("Event time: {0} current ts: {1}", eventTime, header.Timer));
                }
#endif
                _lastEventTime = eventTime;
                return(header);
            }
        public void PushMessage(IPipe pipe, IMessage message)
        {
            if (message is ResetMessage)
            {
                _timeStamper.Reset();
            }
            else if (message is StatusMessage)
            {
                StatusMessage statusMsg = message as StatusMessage;
                _data.SendStatus(statusMsg.body as StatusASO);
            }
            else if (message is RtmpMessage)
            {
                // Make sure chunk size has been sent
                if (!_chunkSizeSent)
                {
                    SendChunkSize();
                }

                RtmpMessage rtmpMsg = message as RtmpMessage;
                IRtmpEvent  msg     = rtmpMsg.body;

                int eventTime = msg.Timestamp;
#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                {
                    log.Debug(string.Format("Message timestamp: {0}", eventTime));
                }
#endif
                if (eventTime < 0)
                {
#if !SILVERLIGHT
                    if (log.IsDebugEnabled)
                    {
                        log.Debug(string.Format("Message has negative timestamp: {0}", eventTime));
                    }
#endif
                    return;
                }
                byte dataType = msg.DataType;
                // Create a new header for the consumer
                RtmpHeader header = _timeStamper.GetTimeStamp(dataType, eventTime);

                switch (msg.DataType)
                {
                case Constants.TypeStreamMetadata:
                    Notify notify = new Notify((msg as Notify).Data);
                    notify.Header    = header;
                    notify.Timestamp = header.Timer;
                    _data.Write(notify);
                    break;

                case Constants.TypeFlexStreamEnd:
                    // TODO: okay to send this also to AMF0 clients?
                    FlexStreamSend send = new FlexStreamSend((msg as Notify).Data);
                    send.Header    = header;
                    send.Timestamp = header.Timer;
                    _data.Write(send);
                    break;

                case Constants.TypeVideoData:
                    VideoData videoData = new VideoData((msg as VideoData).Data);
                    videoData.Header    = header;
                    videoData.Timestamp = header.Timer;
                    _video.Write(videoData);
                    break;

                case Constants.TypeAudioData:
                    AudioData audioData = new AudioData((msg as AudioData).Data);
                    audioData.Header    = header;
                    audioData.Timestamp = header.Timer;
                    _audio.Write(audioData);
                    break;

                case Constants.TypePing:
                    Ping ping = new Ping((msg as Ping).PingType, (msg as Ping).Value2, (msg as Ping).Value3, (msg as Ping).Value4);
                    ping.Header = header;
                    _connection.Ping(ping);
                    break;

                case Constants.TypeBytesRead:
                    BytesRead bytesRead = new BytesRead((msg as BytesRead).Bytes);
                    bytesRead.Header    = header;
                    bytesRead.Timestamp = header.Timer;
                    _connection.GetChannel((byte)2).Write(bytesRead);
                    break;

                default:
                    _data.Write(msg);
                    break;
                }
            }
        }
 protected override void OnFlexInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, FlexInvoke invoke)
 {
     OnInvoke(connection, channel, header, invoke);
 }
        public void PushMessage(IPipe pipe, IMessage message)
        {
            if (message is ResetMessage)
            {
                this._streamTracker.Reset();
            }
            else if (message is StatusMessage)
            {
                StatusMessage message2 = message as StatusMessage;
                this._data.SendStatus(message2.body as StatusASO);
            }
            else if (message is RtmpMessage)
            {
                RtmpMessage message3 = message as RtmpMessage;
                IRtmpEvent  body     = message3.body;
                RtmpHeader  header   = new RtmpHeader();
                int         num      = this._streamTracker.Add(body);
                if (num < 0)
                {
                    log.Warn("Skipping message with negative timestamp.");
                }
                else
                {
                    header.IsTimerRelative = this._streamTracker.IsRelative;
                    header.Timer           = num;
                    switch (body.DataType)
                    {
                    case 3:
                    {
                        BytesRead read = new BytesRead((body as BytesRead).Bytes);
                        header.IsTimerRelative = false;
                        header.Timer           = 0;
                        read.Header            = header;
                        read.Timestamp         = header.Timer;
                        this._connection.GetChannel(2).Write(read);
                        return;
                    }

                    case 4:
                    {
                        Ping ping = new Ping((body as Ping).Value1, (body as Ping).Value2, (body as Ping).Value3, (body as Ping).Value4);
                        header.IsTimerRelative = false;
                        header.Timer           = 0;
                        ping.Header            = header;
                        ping.Timestamp         = header.Timer;
                        this._connection.Ping(ping);
                        return;
                    }

                    case 8:
                    {
                        AudioData data2 = new AudioData((body as AudioData).Data)
                        {
                            Header    = header,
                            Timestamp = header.Timer
                        };
                        this._audio.Write(data2);
                        return;
                    }

                    case 9:
                    {
                        VideoData data = new VideoData((body as VideoData).Data)
                        {
                            Header    = header,
                            Timestamp = header.Timer
                        };
                        this._video.Write(data);
                        return;
                    }

                    case 15:
                    {
                        FlexStreamSend send = new FlexStreamSend((body as Notify).Data)
                        {
                            Header    = header,
                            Timestamp = header.Timer
                        };
                        this._data.Write(send);
                        return;
                    }

                    case 0x12:
                    {
                        Notify notify = new Notify((body as Notify).Data)
                        {
                            Header    = header,
                            Timestamp = header.Timer
                        };
                        this._data.Write(notify);
                        return;
                    }
                    }
                    this._data.Write(body);
                }
            }
        }
        protected override void OnInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, Notify invoke)
        {
            IServiceCall call = invoke.ServiceCall;

            if (invoke.EventType == EventType.STREAM_DATA)
            {
#if !SILVERLIGHT
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(string.Format("Ignoring stream data notify with header {0}", header));
                }
#endif
                return;
            }

            if (call.ServiceMethodName == "_result" || call.ServiceMethodName == "_error")
            {
                if (call.ServiceMethodName == "_error")
                {
                    call.Status = Messaging.Rtmp.Service.Call.STATUS_INVOCATION_EXCEPTION;
                }
                if (call.ServiceMethodName == "_result")
                {
                    call.Status = Messaging.Rtmp.Service.Call.STATUS_SUCCESS_RESULT;
                }
                //Get the panding call, if any, as HandlePendingCallResult will remove it
                IPendingServiceCall pendingCall = connection.GetPendingCall(invoke.InvokeId);
                HandlePendingCallResult(connection, invoke);

                if (call.IsSuccess && invoke.InvokeId == 1)
                {
                    // Should keep this as an Object to stay compatible with FMS3 etc
                    IDictionary aso = call.Arguments[0] as IDictionary;
                    if (aso != null)
                    {
                        object clientId = null;
                        if (aso.Contains("clientid"))
                        {
                            clientId = aso["clientid"];
                        }
#if !SILVERLIGHT
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug(string.Format("Client id: {0}", clientId));
                        }
#endif
                        _netConnection.SetClientId(clientId != null ? clientId.ToString() : null);
                    }
                }

                //Notify via NetConnection if no IPendingServiceCallback was defined but the call failed
                if (call.ServiceMethodName == "_error")
                {
                    object[] args      = call.Arguments;
                    ASObject statusAso = null;
                    if ((args != null) && (args.Length > 0))
                    {
                        statusAso = args[0] as ASObject;
                    }
                    bool raiseError = false;
                    if (pendingCall != null)
                    {
                        IPendingServiceCallback[] callbacks = pendingCall.GetCallbacks();
                        if (callbacks == null || callbacks.Length == 0)
                        {
                            raiseError = true;
                        }
                    }
                    else
                    {
                        raiseError = true;
                    }
                    if (raiseError)
                    {
                        if (statusAso != null)
                        {
                            _netConnection.RaiseNetStatus(statusAso);
                        }
                        else
                        {
                            string msg = __Res.GetString(__Res.Invocation_Failed, pendingCall != null ? pendingCall.ServiceMethodName : string.Empty, "Invocation failed");
                            _netConnection.RaiseNetStatus(msg);
                        }
                    }
                }
                return;
            }

            bool onStatus = call.ServiceMethodName.Equals("onStatus") || call.ServiceMethodName.Equals("onMetaData") ||
                            call.ServiceMethodName.Equals("onPlayStatus");
            if (onStatus)
            {
                /*
                 * IDictionary aso = call.Arguments[0] as IDictionary;
                 * // Should keep this as an Object to stay compatible with FMS3 etc
                 * object clientId = null;
                 * if( aso.Contains("clientid") )
                 *  clientId = aso["clientid"];
                 * if (clientId == null)
                 *  clientId = header.StreamId;
                 #if !SILVERLIGHT
                 * if (log.IsDebugEnabled)
                 *  log.Debug(string.Format("Client id: {0}", clientId));
                 #endif
                 * if (clientId != null)
                 * {
                 *  NetStream stream = _connection.GetStreamById((int)clientId) as NetStream;
                 *  if (stream != null)
                 *  {
                 *      stream.OnStreamEvent(invoke);
                 *  }
                 * }
                 */
                NetStream stream = _connection.GetStreamById(header.StreamId) as NetStream;
                if (stream != null)
                {
                    stream.OnStreamEvent(invoke);
                }
                return;
            }

            if (call is IPendingServiceCall)
            {
                IPendingServiceCall psc = call as IPendingServiceCall;

                /*
                 * object result = psc.Result;
                 * object result = psc.Result;
                 * if (result is DeferredResult)
                 * {
                 *  DeferredResult dr = result as DeferredResult;
                 *  dr.InvokeId = invoke.InvokeId;
                 *  dr.ServiceCall = psc;
                 *  dr.Channel = channel;
                 *  connection.RegisterDeferredResult(dr);
                 * }
                 * else
                 * {
                 *  Invoke reply = new Invoke();
                 *  reply.ServiceCall = call;
                 *  reply.InvokeId = invoke.InvokeId;
                 *  channel.Write(reply);
                 * }
                 */
                MethodInfo mi = MethodHandler.GetMethod(_netConnection.Client.GetType(), call.ServiceMethodName, call.Arguments, false, false);
                if (mi != null)
                {
                    ParameterInfo[] parameterInfos = mi.GetParameters();
                    object[]        args           = new object[parameterInfos.Length];
                    call.Arguments.CopyTo(args, 0);
                    TypeHelper.NarrowValues(args, parameterInfos);
                    try
                    {
                        InvocationHandler invocationHandler = new InvocationHandler(mi);
                        object            result            = invocationHandler.Invoke(_netConnection.Client, args);
                        if (mi.ReturnType == typeof(void))
                        {
                            call.Status = Messaging.Rtmp.Service.Call.STATUS_SUCCESS_VOID;
                        }
                        else
                        {
                            call.Status = result == null ? Messaging.Rtmp.Service.Call.STATUS_SUCCESS_NULL : Messaging.Rtmp.Service.Call.STATUS_SUCCESS_RESULT;
                            psc.Result  = result;
                        }
                    }
                    catch (Exception exception)
                    {
                        call.Exception = exception;
                        call.Status    = Messaging.Rtmp.Service.Call.STATUS_INVOCATION_EXCEPTION;
                        //log.Error("Error while invoking method " + call.ServiceMethodName + " on client", exception);
                    }
                }
                else// if (!onStatus)
                {
                    string msg = __Res.GetString(__Res.Invocation_NoSuitableMethod, call.ServiceMethodName);
                    call.Status    = Messaging.Rtmp.Service.Call.STATUS_METHOD_NOT_FOUND;
                    call.Exception = new FluorineException(msg);
                    _netConnection.RaiseNetStatus(call.Exception);

                    //log.Error(msg, call.Exception);
                }
                if (call.Status == Messaging.Rtmp.Service.Call.STATUS_SUCCESS_VOID || call.Status == Messaging.Rtmp.Service.Call.STATUS_SUCCESS_NULL)
                {
#if !SILVERLIGHT
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug("Method does not have return value, do not reply");
                    }
#endif
                    return;
                }
                Invoke reply = new Invoke();
                reply.ServiceCall = call;
                reply.InvokeId    = invoke.InvokeId;
                channel.Write(reply);
            }
            else
            {
                IPendingServiceCall pendingCall = connection.RetrievePendingCall(invoke.InvokeId);
                Unreferenced.Parameter(pendingCall);
            }
        }
Beispiel #14
0
        protected RtmpHeader ReadHeader()
        {
            // first byte of the chunk basic header
            var chunkBasicHeaderByte   = reader.ReadByte();
            var chunkStreamId          = GetChunkStreamId(chunkBasicHeaderByte, reader);
            var chunkMessageHeaderType = (ChunkMessageHeaderType)(chunkBasicHeaderByte >> 6);

            var header = new RtmpHeader()
            {
                StreamId        = chunkStreamId,
                IsTimerRelative = chunkMessageHeaderType != ChunkMessageHeaderType.New
            };

            RtmpHeader previousHeader;

            // don't need to clone if new header, as it contains all info
            if (!rtmpHeaders.TryGetValue(chunkStreamId, out previousHeader) && chunkMessageHeaderType != ChunkMessageHeaderType.New)
            {
                previousHeader = header.Clone();
            }

            switch (chunkMessageHeaderType)
            {
            // 11 bytes
            case ChunkMessageHeaderType.New:
                header.Timestamp       = reader.ReadUInt24();
                header.PacketLength    = reader.ReadUInt24();
                header.MessageType     = (MessageType)reader.ReadByte();
                header.MessageStreamId = reader.ReadReverseInt();
                break;

            // 7 bytes
            case ChunkMessageHeaderType.SameSource:
                header.Timestamp       = reader.ReadUInt24();
                header.PacketLength    = reader.ReadUInt24();
                header.MessageType     = (MessageType)reader.ReadByte();
                header.MessageStreamId = previousHeader.MessageStreamId;
                break;

            // 3 bytes
            case ChunkMessageHeaderType.TimestampAdjustment:
                header.Timestamp       = reader.ReadUInt24();
                header.PacketLength    = previousHeader.PacketLength;
                header.MessageType     = previousHeader.MessageType;
                header.MessageStreamId = previousHeader.MessageStreamId;
                break;

            // 0 bytes
            case ChunkMessageHeaderType.Continuation:
                header.Timestamp       = previousHeader.Timestamp;
                header.PacketLength    = previousHeader.PacketLength;
                header.MessageType     = previousHeader.MessageType;
                header.MessageStreamId = previousHeader.MessageStreamId;
                header.IsTimerRelative = previousHeader.IsTimerRelative;
                break;

            default:
                throw new SerializationException("Unexpected header type: " + (int)chunkMessageHeaderType);
            }

            // extended timestamp
            if (header.Timestamp == 0xFFFFFF)
            {
                header.Timestamp = reader.ReadInt32();
            }

            return(header);
        }
Beispiel #15
0
 protected override void OnPing(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, Ping ping)
 {
     if (ping.Value1 == 6)
     {
         Ping ping2 = new Ping {
             Value1 = 7
         };
         int num = Environment.TickCount & ((int)0xffffffffL);
         ping2.Value2 = num;
         ping2.Value3 = -1;
         connection.Ping(ping2);
     }
 }
Beispiel #16
0
        protected override void OnInvoke(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, Notify invoke)
        {
            IServiceCall serviceCall = invoke.ServiceCall;

            if ((serviceCall.ServiceMethodName == "_result") || (serviceCall.ServiceMethodName == "_error"))
            {
                if (serviceCall.ServiceMethodName == "_error")
                {
                    serviceCall.Status = 0x13;
                }
                if (serviceCall.ServiceMethodName == "_result")
                {
                    serviceCall.Status = 2;
                }
                base.HandlePendingCallResult(connection, invoke);
            }
            else if (serviceCall is IPendingServiceCall)
            {
                IPendingServiceCall call2      = serviceCall as IPendingServiceCall;
                MethodInfo          methodInfo = MethodHandler.GetMethod(this._netConnection.Client.GetType(), serviceCall.ServiceMethodName, serviceCall.Arguments, false, false);
                if (methodInfo != null)
                {
                    ParameterInfo[] parameters = methodInfo.GetParameters();
                    object[]        array      = new object[parameters.Length];
                    serviceCall.Arguments.CopyTo(array, 0);
                    TypeHelper.NarrowValues(array, parameters);
                    try
                    {
                        object obj2 = new InvocationHandler(methodInfo).Invoke(this._netConnection.Client, array);
                        if (methodInfo.ReturnType == typeof(void))
                        {
                            serviceCall.Status = 4;
                        }
                        else
                        {
                            serviceCall.Status = (obj2 == null) ? ((byte)3) : ((byte)2);
                            call2.Result       = obj2;
                        }
                    }
                    catch (Exception exception)
                    {
                        serviceCall.Exception = exception;
                        serviceCall.Status    = 0x13;
                    }
                }
                else
                {
                    string message = __Res.GetString("Invocation_NoSuitableMethod", new object[] { serviceCall.ServiceMethodName });
                    serviceCall.Status    = 0x11;
                    serviceCall.Exception = new FluorineException(message);
                }
                if ((serviceCall.Status == 4) || (serviceCall.Status == 3))
                {
                    if (log.get_IsDebugEnabled())
                    {
                        log.Debug("Method does not have return value, do not reply");
                    }
                }
                else
                {
                    FluorineFx.Messaging.Rtmp.Event.Invoke invoke2 = new FluorineFx.Messaging.Rtmp.Event.Invoke {
                        ServiceCall = serviceCall,
                        InvokeId    = invoke.InvokeId
                    };
                    channel.Write(invoke2);
                }
            }
        }
Beispiel #17
0
 protected override void OnChunkSize(RtmpConnection connection, RtmpChannel channel, RtmpHeader source, ChunkSize chunkSize)
 {
 }
 protected override void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message)
 {
     _netConnection.OnSharedObject(connection, channel, header, message);
 }
Beispiel #19
0
 internal void OnSharedObject(RtmpConnection connection, RtmpChannel channel, RtmpHeader header, SharedObjectMessage message)
 {
     RemoteSharedObject.Dispatch(message);
 }
            /// <summary>
            /// Gets a header with the appropriate timestamp.
            /// </summary>
            /// <param name="dataType">Type of the event.</param>
            /// <param name="eventTime">The event time.</param>
            /// <returns></returns>
            public RtmpHeader GetTimeStamp(byte dataType, int eventTime)
            {
                RtmpHeader header = new RtmpHeader();
#if !SILVERLIGHT
                if( log.IsDebugEnabled )
                    log.Debug(string.Format("GetTimeStamp - event time: {0} last event: {1} audio: {2} video: {3} data: {4}", eventTime, _lastEventTime, _lastAudioTime, _lastVideoTime, _lastNotifyTime));
#endif
                switch (dataType)
                {
                    case Constants.TypeAudioData:
                        if (_lastAudioTime > 0)
                        {
                            //set a relative value
                            header.Timer = eventTime - _lastAudioTime;
#if !SILVERLIGHT
                            if (log.IsDebugEnabled)
                                log.Debug("Relative audio");
#endif
                        }
                        else
                        {
                            //use absolute value
                            header.Timer = eventTime;
                            header.IsTimerRelative = false;
#if !SILVERLIGHT
                            if (log.IsDebugEnabled)
                                log.Debug("Absolute audio");
#endif
                        }
                        _lastAudioTime = eventTime;
                        break;
                    case Constants.TypeVideoData:
                        if (_lastVideoTime > 0)
                        {
                            //set a relative value
                            header.Timer = eventTime - _lastVideoTime;
#if !SILVERLIGHT
                            if (log.IsDebugEnabled)
                                log.Debug("Relative video");
#endif
                        }
                        else
                        {
                            //use absolute value
                            header.Timer = eventTime;
                            header.IsTimerRelative = false;
#if !SILVERLIGHT
                            if (log.IsDebugEnabled)
                                log.Debug("Absolute video");
#endif
                        }
                        _lastVideoTime = eventTime;
                        break;
                    case Constants.TypeNotify:
                    case Constants.TypeInvoke:
                    case Constants.TypeFlexStreamEnd:
                        if (_lastNotifyTime > 0)
                        {
                            //set a relative value
                            header.Timer = eventTime - _lastNotifyTime;
#if !SILVERLIGHT
                            if (log.IsDebugEnabled)
                                log.Debug("Relative notify");
#endif
                        }
                        else
                        {
                            //use absolute value
                            header.Timer = eventTime;
                            header.IsTimerRelative = false;
#if !SILVERLIGHT
                            if (log.IsDebugEnabled)
                                log.Debug("Absolute notify");
#endif
                        }
                        _lastNotifyTime = eventTime;
                        break;
                    case Constants.TypeBytesRead:
                    case Constants.TypePing:
                        header.Timer = eventTime;
                        header.IsTimerRelative = false;
                        break;
                    default:
                        // ignore other types
#if !SILVERLIGHT
                        if (log.IsDebugEnabled)
                            log.Debug(string.Format("Unmodified type: {0} timestamp: {1}", dataType, eventTime));
#endif
                        break;
                }
#if !SILVERLIGHT
                if (log.IsDebugEnabled)
                    log.Debug(string.Format("Event time: {0} current ts: {1}", eventTime, header.Timer));
#endif
                _lastEventTime = eventTime;
                return header;
            }
        public static AbstractRtmpMessage Decode(RtmpHeader header, IByteBuffer payload)
        {
            AbstractRtmpMessage result = null;
            short messageTypeId        = header.MessageTypeId;

            switch (messageTypeId)
            {
            case Constants.MSG_SET_CHUNK_SIZE:
            {
                int          readInt      = payload.ReadInt();
                SetChunkSize setChunkSize = new SetChunkSize();
                setChunkSize.ChunkSize = readInt;
                result = setChunkSize;
            }
            break;

            case Constants.MSG_ABORT_MESSAGE:
            {
                int   csid  = payload.ReadInt();
                Abort abort = new Abort(csid);
                result = abort;
            }

            break;

            case Constants.MSG_ACKNOWLEDGEMENT:
            {
                int ack = payload.ReadInt();
                result = new Acknowledgement(ack);
            }
            break;

            case Constants.MSG_WINDOW_ACKNOWLEDGEMENT_SIZE:
            {
                int size = payload.ReadInt();
                result = new WindowAcknowledgementSize(size);
            }
            break;

            case Constants.MSG_SET_PEER_BANDWIDTH:
            {
                int ackSize = payload.ReadInt();
                int type    = payload.ReadByte();
                result = new SetPeerBandWidth(ackSize, type);
            }
            break;

            case Constants.MSG_TYPE_COMMAND_AMF0:
            {
                List <Object> decode = AMF0.DecodeAll(payload);
                result = new RtmpCommandMessage(decode);
            }
            break;

            case Constants.MSG_USER_CONTROL_MESSAGE_EVENTS:
            {
                short readShort = payload.ReadShort();
                int   data      = payload.ReadInt();
                result = new UserControlMessageEvent(readShort, data);
            }
            break;

            case Constants.MSG_TYPE_AUDIO_MESSAGE:
            {
                AudioMessage am = new AudioMessage();

                byte[] data = ReadAll(payload);
                am.AudioData = data;

                if (header.Fmt == Constants.CHUNK_FMT_0)
                {
                    am.Timestamp = header.Timestamp;
                }
                else if (header.Fmt == Constants.CHUNK_FMT_1 || header.Fmt == Constants.CHUNK_FMT_2)
                {
                    am.TimestampDelta = header.TimestampDelta;
                }
                result = am;
            }
            break;

            case Constants.MSG_TYPE_VIDEO_MESSAGE:
            {
                VideoMessage vm   = new VideoMessage();
                byte[]       data = ReadAll(payload);

                vm.VideoData = data;

                if (header.Fmt == Constants.CHUNK_FMT_0)
                {
                    vm.Timestamp = header.Timestamp;
                }
                else if (header.Fmt == Constants.CHUNK_FMT_1 || header.Fmt == Constants.CHUNK_FMT_2)
                {
                    vm.TimestampDelta = header.TimestampDelta;
                }
                result = vm;
            }
            break;

            case Constants.MSG_TYPE_DATA_MESSAGE_AMF0:
            {
                result = new RtmpDataMessage(AMF0.DecodeAll(payload));
            }
            break;

            default:
                break;
            }
            if (result != null)
            {
                result.InboundBodyLength   = header.MessageLength;
                result.InboundHeaderLength = header.HeaderLength;

                return(result);
            }
            else
            {
                return(null);
            }
        }