public RtmpConnect(Socket client_socket, Stream stream, RtmpServer server, ushort clientID, SerializationContext context, ObjectEncoding objectEncoding = ObjectEncoding.Amf0, bool asyncMode = false) { ClientID = clientID; this._clientSocket = client_socket; this._server = server; this._objectEncoding = objectEncoding; Writer = new RtmpPacketWriter(new AmfWriter(stream, context, ObjectEncoding.Amf0, asyncMode), ObjectEncoding.Amf0); Reader = new RtmpPacketReader(new AmfReader(stream, context, asyncMode)); Reader.EventReceived += EventReceivedCallback; Reader.Disconnected += OnPacketProcessorDisconnected; Writer.Disconnected += OnPacketProcessorDisconnected; _callbackManager = new TaskCallbackManager <int, object>(); }
/// <summary> /// rtmp握手逻辑 /// HandshakeAsync2 /// c01->s01->s2->c2 /// </summary> /// <param name="server"></param> /// <param name="client_socket"></param> /// <param name="client_id"></param> /// <param name="cert"></param> /// <returns></returns> public static async Task <int> HandshakeAsync(RtmpServer server, Socket client_socket, ushort client_id, X509Certificate2 cert = null) { Stream stream; if (cert != null) { var temp_stream = new SslStream(new NetworkStream(client_socket)); try { await temp_stream.AuthenticateAsServerAsync(cert); } catch (AuthenticationException) { temp_stream.Close(); throw; } stream = temp_stream; } else { stream = new NetworkStream(client_socket); } var random = new Random(Environment.TickCount); var randomBytes = new byte[1528]; random.NextBytes(randomBytes); client_socket.NoDelay = true; CancellationTokenSource cts = new CancellationTokenSource(); //over time cancel task Timer timer = new Timer((s) => { cts.Cancel(); throw new TimeoutException("rtmp 握手已超时!"); }, null, ReceiveTimeout, Timeout.Infinite); //read c0 c1 var c01 = await RtmpHandshake.ReadAsync(stream, true, cts.Token); timer.Change(Timeout.Infinite, Timeout.Infinite); //write s0 s1 var s01 = new RtmpHandshake() { Version = 3, Time = (uint)Environment.TickCount, Time2 = 0, Random = randomBytes }; timer.Change(ReceiveTimeout, Timeout.Infinite); await RtmpHandshake.WriteAsync(stream, s01, true, cts.Token); //write s2 random.NextBytes(randomBytes); await C2S2Async(stream, randomBytes, cts, timer); timer.Change(Timeout.Infinite, Timeout.Infinite); // handshake check //if (!c0.Random.SequenceEqual(s2.Random)) //throw new ProtocolViolationException(); var connect = new RtmpConnect(client_socket, stream, server, client_id, server.Context, server.AmfEncoding, true); connect.ChannelDataReceived += server.SendDataHandler; server.ClientSessions.Add(client_id, new ClientSession() { Connect = connect, LastPing = DateTime.UtcNow, ReaderTask = null, WriterTask = null }); return(client_id); }