예제 #1
0
        public void ReadLoop()
        {
            try
            {
                while (Continue)
                {
                    AKUtils.Trace("ReadLoop() +++++++");
                    var header = ReadHeader();
                    rtmpHeaders[header.StreamId] = header;

                    RtmpPacket packet;
                    if (!rtmpPackets.TryGetValue(header.StreamId, out packet) || packet == null)
                    {
                        packet = new RtmpPacket(header);
                        rtmpPackets[header.StreamId] = packet;
                    }

                    var remainingMessageLength = packet.Length + (header.Timestamp >= 0xFFFFFF ? 4 : 0) - packet.CurrentLength;
                    var bytesToRead            = Math.Min(remainingMessageLength, readChunkSize);
                    var bytes = reader.ReadBytes(bytesToRead);
                    packet.AddBytes(bytes);

                    if (packet.IsComplete)
                    {
                        rtmpPackets.Remove(header.StreamId);

                        var @event = ParsePacket(packet);
                        OnEventReceived(new EventReceivedEventArgs(@event));

                        // process some kinds of packets
                        var chunkSizeMessage = @event as ChunkSize;
                        if (chunkSizeMessage != null)
                        {
                            readChunkSize = chunkSizeMessage.Size;
                        }

                        var abortMessage = @event as Abort;
                        if (abortMessage != null)
                        {
                            rtmpPackets.Remove(abortMessage.StreamId);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
#if DEBUG
                System.Diagnostics.Debug.Print("Exception: {0} at {1}", ex, ex.StackTrace);
                if (ex.InnerException != null)
                {
                    var inner = ex.InnerException;
                    System.Diagnostics.Debug.Print("InnerException: {0} at {1}", inner, inner.StackTrace);
                }
#endif

                OnDisconnected(new ExceptionalEventArgs("rtmp-packet-reader", ex));
            }
        }
예제 #2
0
        private static async Task MainAsync()
        {
//            Socket s = new Socket(AddressFamily.Ipx, SocketType.Stream, ProtocolType.IP);
//            await s.ConnectAsync(
            const string uri = "rtmp://x.kipod.com/live/51:902b3459783c:6?signature=JJa-cs2s660ec4FEjugXHA&expires=1441112256";

            AKUtils.Trace(uri);
            var client = new RtmpClient(
                new Uri(uri),
                new SerializationContext(),
                ObjectEncoding.Amf3);

            // connect to the server
            await client.ConnectAsync();

//            await client.();

            // call a remote service
//            var songs = await client.InvokeAsync<string[]>("musicalService", "findSongs");
            var streamId = await client.CreateStreamInvokeAsync();

            var play = await client.PlayInvokeAsync();//<object>("play", "51:902b3459783c:6:live");
        }
예제 #3
0
 public void Write(byte[] bytes, int index, int count)
 {
     AKUtils.Trace("index:" + index, "count:" + count, bytes.Skip(index).Take(count).ToArray().ToHexString());
     underlying.Write(bytes, index, count);
 }
예제 #4
0
 public void Write(byte[] value)
 {
     AKUtils.Trace("size:" + value.Length, value.ToUtfString(), value.ToHexString());
     underlying.Write(value);
 }
예제 #5
0
 public void Write(byte value)
 {
     AKUtils.Trace(value.ToString("x2"));
     underlying.Write(value);
 }
예제 #6
0
        public async Task ConnectAsync()
        {
            if (hasConnected)
            {
                return;
            }

            var client = CreateTcpClient();

            client.NoDelay             = NoDelay;
            client.ReceiveTimeout      = ReceiveTimeout;
            client.SendTimeout         = SendTimeout;
            client.ExclusiveAddressUse = ExclusiveAddressUse;

            await client.ConnectAsync(uri.Host, uri.Port);

            var stream = await GetRtmpStreamAsync(client);


            var random      = new Random();
            var randomBytes = new byte[1528];

            random.NextBytes(randomBytes);

            // write c0+c1
            var c01 = new Handshake()
            {
                Version = 3,
                Time    = (uint)Environment.TickCount,
                Time2   = 0,
                Random  = randomBytes
            };
            await Handshake.WriteAsync(stream, c01, true);

            // read s0+s1
            var s01 = await Handshake.ReadAsync(stream, true);

            // write c2
            var c2 = s01.Clone();

            c2.Time2 = (uint)Environment.TickCount;
            await Handshake.WriteAsync(stream, c2, false);

            // read s2
            var s2 = await Handshake.ReadAsync(stream, false);

            // handshake check
            if (!c01.Random.SequenceEqual(s2.Random) || c01.Time != s2.Time)
            {
                throw new ProtocolViolationException();
            }

            AKUtils.Trace("+++++++++++++++++++++ HANDSHAKE COMPLETE +++++++++++++++++++++++++");

            writer = new RtmpPacketWriter(new AmfWriter(stream, context), ObjectEncoding.Amf3);
            reader = new RtmpPacketReader(new AmfReader(stream, context));
            reader.EventReceived += EventReceivedCallback;
            reader.Disconnected  += OnPacketProcessorDisconnected;
            writer.Disconnected  += OnPacketProcessorDisconnected;

            writerThread = new Thread(reader.ReadLoop)
            {
                IsBackground = true
            };
            readerThread = new Thread(writer.WriteLoop)
            {
                IsBackground = true
            };

            writerThread.Start();
            readerThread.Start();

            // call `connect`
            var connectResult = await ConnectInvokeAsync(null, null, uri.ToString());

            object cId;

            if (connectResult.TryGetValue("clientId", out cId))
            {
                ClientId = cId as string;
            }

            hasConnected = true;
            AKUtils.Trace("++++++++++++++++++++++++ CONNECT COMPLETE ++++++++++++++++++++++++++");
        }