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)); } }
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"); }
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); }
public void Write(byte[] value) { AKUtils.Trace("size:" + value.Length, value.ToUtfString(), value.ToHexString()); underlying.Write(value); }
public void Write(byte value) { AKUtils.Trace(value.ToString("x2")); underlying.Write(value); }
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 ++++++++++++++++++++++++++"); }