예제 #1
0
        private void DoHandshake(Stream stream)
        {
            // read c0+c1
            var c01 = RtmpHandshake.Read(stream, true);

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

            random.NextBytes(randomBytes);

            // write s0+s1+s2
            var s01 = new RtmpHandshake
            {
                Version = 3,
                Time    = (uint)Environment.TickCount,
                Time2   = 0,
                Random  = randomBytes
            };
            var s02 = s01.Clone();

            s02.Time2 = (uint)Environment.TickCount;
            RtmpHandshake.WriteAsync(stream, s01, s02, true);

            // read c02
            var c02 = RtmpHandshake.Read(stream, false);

            hasConnected = true;
        }
예제 #2
0
        public async Task <AsObject> ReconnectAsync(int invokeId, AsObject cParameters, params object[] parameters)
        {
            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 RtmpHandshake
            {
                Version = 3,
                Time    = (uint)Environment.TickCount,
                Time2   = 0,
                Random  = randomBytes
            };
            await RtmpHandshake.WriteAsync(stream, c01, true);

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

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

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

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

            // handshake check. won't work if running a local server (time will be the same) so run on debug
#if !DEBUG
            if (!c01.Random.SequenceEqual(s2.Random) || c01.Time != s2.Time)
            {
                throw new ProtocolViolationException();
            }
#endif

            EstablishThreads(stream);

            var connectResult = await ConnectInvokeAsync(invokeId, cParameters, parameters);

            hasConnected   = true;
            IsDisconnected = false;
            return(connectResult);
        }
예제 #3
0
        public async Task RecreateConnection(string token)
        {
            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 RtmpHandshake()
            {
                Version = 3,
                Time    = (uint)Environment.TickCount,
                Time2   = 0,
                Random  = randomBytes
            };
            await RtmpHandshake.WriteAsync(stream, c01, true);

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

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

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

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

            EstablishThreads(stream);

#pragma warning disable 420
            Interlocked.Exchange(ref disconnectsFired, 0);
            Interlocked.Exchange(ref invokeId, 0);
#pragma warning restore 420

            var connectResult = await ReconnectInvokeAsync(null, null, uri.ToString(), token);
        }
예제 #4
0
        public async Task <AsObject> ConnectAsync()
        {
            TcpClient client = this.CreateTcpClient();

            client.NoDelay             = this.NoDelay;
            client.ReceiveTimeout      = this.ReceiveTimeout;
            client.SendTimeout         = this.SendTimeout;
            client.ExclusiveAddressUse = this.ExclusiveAddressUse;
            await client.ConnectAsync(this._uri.Host, this._uri.Port);

            Stream stream = await this.GetRtmpStreamAsync(client);

            Random random = new Random();

            byte[] numArray = new byte[1528];
            byte[] buffer   = numArray;
            random.NextBytes(buffer);
            RtmpHandshake c01 = new RtmpHandshake()
            {
                Version = 3, Time = (uint)Environment.TickCount, Time2 = 0, Random = numArray
            };
            await RtmpHandshake.WriteAsync(stream, c01, true);

            RtmpHandshake h = (await RtmpHandshake.ReadAsync(stream, true)).Clone();

            h.Time2 = (uint)Environment.TickCount;
            await RtmpHandshake.WriteAsync(stream, h, false);

            RtmpHandshake rtmpHandshake = await RtmpHandshake.ReadAsync(stream, false);

            if (!((IEnumerable <byte>)c01.Random).SequenceEqual <byte>((IEnumerable <byte>)rtmpHandshake.Random) || (int)c01.Time != (int)rtmpHandshake.Time)
            {
                throw new ProtocolViolationException();
            }
            this.EstablishThreads(stream);
            AsObject asObject = await this.ConnectInvokeAsync((string)null, (string)null, this._uri.ToString());

            string key1 = "clientId";
            object obj;

            if (asObject.TryGetValue(key1, out obj))
            {
                this.ClientId = obj as string;
            }
            string key2 = "id";

            if (asObject.TryGetValue(key2, out obj))
            {
                this.ClientId = this.ClientId ?? obj as string;
            }
            return(asObject);
        }
예제 #5
0
        public static async Task <RtmpHandshake> ReadAsync(Stream stream, bool readVersion)
        {
            RtmpHandshake rtmpHandshake;

            using (AmfReader amfReader = new AmfReader((Stream) new MemoryStream(await StreamHelper.ReadBytesAsync(stream, 1536 + (readVersion ? 1 : 0))), (SerializationContext)null))
                rtmpHandshake = new RtmpHandshake()
                {
                    Version = readVersion ? amfReader.ReadByte() : (byte)0,
                    Time    = amfReader.ReadUInt32(),
                    Time2   = amfReader.ReadUInt32(),
                    Random  = amfReader.ReadBytes(1528)
                };
            return(rtmpHandshake);
        }
예제 #6
0
        public static RtmpHandshake Read(Stream stream, bool readVersion)
        {
            int count = 1536 + (readVersion ? 1 : 0);

            using (AmfReader amfReader = new AmfReader((Stream) new MemoryStream(StreamHelper.ReadBytes(stream, count)), (SerializationContext)null))
            {
                RtmpHandshake rtmpHandshake = new RtmpHandshake();
                rtmpHandshake.Version = readVersion ? amfReader.ReadByte() : (byte)0;
                rtmpHandshake.Time    = amfReader.ReadUInt32();
                rtmpHandshake.Time2   = amfReader.ReadUInt32();
                rtmpHandshake.Random  = amfReader.ReadBytes(1528);
                rtmpHandshake         = rtmpHandshake;
                return(rtmpHandshake);
            }
        }
예제 #7
0
        public static Task WriteAsync(Stream stream, RtmpHandshake h, bool writeVersion)
        {
            using (var memoryStream = new MemoryStream())
            using (var writer = new AmfWriter(memoryStream, null))
            {
                if (writeVersion)
                    writer.WriteByte(h.Version);

                writer.WriteUInt32(h.Time);
                writer.WriteUInt32(h.Time2);
                writer.WriteBytes(h.Random);

                var buffer = memoryStream.ToArray();
                return stream.WriteAsync(buffer, 0, buffer.Length);
            }
        }
예제 #8
0
        async void OnClientAccepted(IAsyncResult ar)
        {
            TcpListener listener = ar.AsyncState as TcpListener;

            if (listener == null)
            {
                return;
            }

            try
            {
                TcpClient client = listener.EndAcceptTcpClient(ar);
                var       stream = await GetRtmpStreamAsync(client);

                // read c0+c1
                var c01 = await RtmpHandshake.ReadAsync(stream, true);

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

                // write s0+s1+s2
                var s01 = new RtmpHandshake()
                {
                    Version = 3,
                    Time    = (uint)Environment.TickCount,
                    Time2   = 0,
                    Random  = randomBytes
                };
                var s02 = s01.Clone();
                s02.Time2 = (uint)Environment.TickCount;
                await RtmpHandshake.WriteAsync(stream, s01, s02, true);

                // read c02
                var c02 = await RtmpHandshake.ReadAsync(stream, false);

                RtmpClient rtmpClient = new RtmpClient(_serverUri, _context, stream);
                rtmpClient.ServerMessageReceived += ServerMessageReceived;
                rtmpClient.ServerCommandReceived += ServerCommandReceived;
                _clients.Add(rtmpClient);
            }
            finally
            {
                listener.BeginAcceptTcpClient(OnClientAccepted, listener);
            }
        }
예제 #9
0
        public static Task WriteAsync(Stream stream, RtmpHandshake h, bool writeVersion)
        {
            using (var memoryStream = new MemoryStream())
                using (var writer = new AmfWriter(memoryStream, null))
                {
                    if (writeVersion)
                    {
                        writer.WriteByte(h.Version);
                    }

                    writer.WriteUInt32(h.Time);
                    writer.WriteUInt32(h.Time2);
                    writer.WriteBytes(h.Random);

                    var buffer = memoryStream.ToArray();
                    return(stream.WriteAsync(buffer, 0, buffer.Length));
                }
        }
예제 #10
0
 public static Task WriteAsync(Stream stream, RtmpHandshake h, bool writeVersion)
 {
     using (MemoryStream memoryStream = new MemoryStream())
     {
         using (AmfWriter amfWriter = new AmfWriter((Stream)memoryStream, (SerializationContext)null))
         {
             if (writeVersion)
             {
                 amfWriter.WriteByte(h.Version);
             }
             amfWriter.WriteUInt32(h.Time);
             amfWriter.WriteUInt32(h.Time2);
             amfWriter.WriteBytes(h.Random);
             byte[] array = memoryStream.ToArray();
             return(stream.WriteAsync(array, 0, array.Length));
         }
     }
 }
예제 #11
0
        private void DoHandshake(Stream stream)
        {
            RtmpHandshake.Read(stream, true);
            Random random = new Random();

            byte[] numArray = new byte[1528];
            byte[] buffer   = numArray;
            random.NextBytes(buffer);
            RtmpHandshake h = new RtmpHandshake()
            {
                Version = 3, Time = (uint)Environment.TickCount, Time2 = 0, Random = numArray
            };
            RtmpHandshake h2 = h.Clone();

            h2.Time2 = (uint)Environment.TickCount;
            RtmpHandshake.WriteAsync(stream, h, h2, true);
            RtmpHandshake.Read(stream, false);
        }
예제 #12
0
        async void OnClientAccepted(IAsyncResult ar)
        {
            TcpListener listener = ar.AsyncState as TcpListener;
            if (listener == null)
                return;

            try
            {
                TcpClient client = listener.EndAcceptTcpClient(ar);
                var stream = await GetRtmpStreamAsync(client);

                // read c0+c1
                var c01 = await RtmpHandshake.ReadAsync(stream, true);

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

                // write s0+s1+s2
                var s01 = new RtmpHandshake()
                {
                    Version = 3,
                    Time = (uint)Environment.TickCount,
                    Time2 = 0,
                    Random = randomBytes
                };
                var s02 = s01.Clone();
                s02.Time2 = (uint)Environment.TickCount;
                await RtmpHandshake.WriteAsync(stream, s01, s02, true);

                // read c02
                var c02 = await RtmpHandshake.ReadAsync(stream, false);

                RtmpClient rtmpClient = new RtmpClient(_serverUri, _context, stream);
                rtmpClient.ServerMessageReceived += ServerMessageReceived;
                rtmpClient.ServerCommandReceived += ServerCommandReceived;
                _clients.Add(rtmpClient);
            }
            finally
            {
                listener.BeginAcceptTcpClient(OnClientAccepted, listener);
            }
        }
예제 #13
0
        public async Task <AsObject> ReconnectAsync(int invokeId, AsObject cParameters, params object[] parameters)
        {
            TcpClient client = this.CreateTcpClient();

            client.NoDelay             = this.NoDelay;
            client.ReceiveTimeout      = this.ReceiveTimeout;
            client.SendTimeout         = this.SendTimeout;
            client.ExclusiveAddressUse = this.ExclusiveAddressUse;
            await client.ConnectAsync(this._uri.Host, this._uri.Port);

            Stream stream = await this.GetRtmpStreamAsync(client);

            Random random = new Random();

            byte[] numArray = new byte[1528];
            byte[] buffer   = numArray;
            random.NextBytes(buffer);
            RtmpHandshake c01 = new RtmpHandshake()
            {
                Version = 3, Time = (uint)Environment.TickCount, Time2 = 0, Random = numArray
            };
            await RtmpHandshake.WriteAsync(stream, c01, true);

            RtmpHandshake h = (await RtmpHandshake.ReadAsync(stream, true)).Clone();

            h.Time2 = (uint)Environment.TickCount;
            await RtmpHandshake.WriteAsync(stream, h, false);

            RtmpHandshake rtmpHandshake = await RtmpHandshake.ReadAsync(stream, false);

            if (!((IEnumerable <byte>)c01.Random).SequenceEqual <byte>((IEnumerable <byte>)rtmpHandshake.Random) || (int)c01.Time != (int)rtmpHandshake.Time)
            {
                throw new ProtocolViolationException();
            }
            this.EstablishThreads(stream);
            AsObject asObject = await this.ConnectInvokeAsync(invokeId, cParameters, parameters);

            this.IsDisconnected = false;
            return(asObject);
        }
예제 #14
0
        public virtual 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 RtmpHandshake()
            {
                Version = 3,
                Time    = (uint)Environment.TickCount,
                Time2   = 0,
                Random  = randomBytes
            };
            await RtmpHandshake.WriteAsync(stream, c01, true);

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

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

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

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

            // handshake check. won't work if running a local server (time will be the same) so run on debug
            #if !DEBUG
            if (!c01.Random.SequenceEqual(s2.Random) || c01.Time != s2.Time)
            {
                throw new ProtocolViolationException();
            }
            #endif

            EstablishThreads(stream);

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

            object cId;

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

            hasConnected = true;
        }
예제 #15
0
        private void DoHandshake(Stream stream)
        {
            // read c0+c1
            var c01 = RtmpHandshake.Read(stream, true);

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

            // write s0+s1+s2
            var s01 = new RtmpHandshake()
            {
                Version = 3,
                Time = (uint) Environment.TickCount,
                Time2 = 0,
                Random = randomBytes
            };
            var s02 = s01.Clone();
            s02.Time2 = (uint) Environment.TickCount;
            RtmpHandshake.WriteAsync(stream, s01, s02, true);

            // read c02
            var c02 = RtmpHandshake.Read(stream, false);
            hasConnected = true;
        }