public void Stop() { Started = false; foreach (var current in connects) { StreamConnectState state = current.Value; ushort client_id = current.Key; IStreamConnect connect = state.Connect; if (connect.IsDisconnected) { continue; } try { Close(client_id); } catch (Exception e) { Console.WriteLine(e.StackTrace); } } connects.Clear(); allocated_client_id.Clear(); allocated_stream_id.Clear(); listener.Close(); }
private void sendDataHandler(object sender, ChannelDataReceivedEventArgs e) { var server = (RtmpConnect)sender; var server_clients = routedClients.FindAll((t) => t.Item2 == server.ClientId); foreach (var i in server_clients) { IStreamConnect client; StreamConnectState client_state = null; if (e.type != i.Item3) { continue; } connects.TryGetValue(i.Item1, out client_state); switch (i.Item3) { case ChannelType.Audio: if (client_state == null) { continue; } client = client_state.Connect; client.SendAmf0Data(e.e); break; case ChannelType.Video: if (client_state == null) { continue; } client = client_state.Connect; client.SendAmf0Data(e.e); break; case ChannelType.Message: throw new NotImplementedException(); } } }
public RtmpServer( SerializationContext context, X509Certificate2 cert = null, ObjectEncoding object_encoding = ObjectEncoding.Amf0, ParameterAuthCallback publishParameterAuth = null, ParameterAuthCallback playParameterAuth = null, string bindIp = "0.0.0.0", int bindRtmpPort = 1935, int bindWebsocketPort = -1 ) { this.context = context; objectEncoding = object_encoding; if (bindWebsocketPort != -1) { var server = new WebSocketServer("ws://" + bindIp.ToString() + ":" + bindWebsocketPort.ToString()); if (cert != null) { this.cert = cert; server.Certificate = cert; server.EnabledSslProtocols = SslProtocols.Default; } server.ListenerSocket.NoDelay = true; server.Start(socket => { socket.OnOpen = () => { var path = socket.ConnectionInfo.Path.Split('/'); if (path.Length != 3) { socket.Close(); } ushort client_id = GetNewClientId(); IStreamConnect connect = new WebsocketConnect(socket, context, object_encoding); lock (connects) { connects.Add(client_id, new StreamConnectState() { Connect = connect, LastPing = DateTime.UtcNow, ReaderTask = null, WriterTask = null }); } try { SendMetadata(path[1], path[2], connect, flvHeader: true); ConnectToClient(path[1], path[2], client_id, ChannelType.Audio); ConnectToClient(path[1], path[2], client_id, ChannelType.Video); } catch { Close(client_id); } }; socket.OnPing = b => socket.SendPong(b); }); } if (publishParameterAuth != null) { this.publishParameterAuth = publishParameterAuth; } if (playParameterAuth != null) { this.playParameterAuth = playParameterAuth; } ioThread = new Thread(() => { while (true) { foreach (var current in connects) { StreamConnectState state = current.Value; ushort client_id = current.Key; IStreamConnect connect = state.Connect; if (connect.IsDisconnected) { Close(client_id); continue; } try { if (state.WriterTask == null || state.WriterTask.IsCompleted) { state.WriterTask = connect.WriteOnceAsync(); } if (state.WriterTask.IsCanceled || state.WriterTask.IsFaulted) { throw state.WriterTask.Exception; } if (state.LastPing == null || DateTime.UtcNow - state.LastPing >= new TimeSpan(0, 0, PingPeriod)) { connect.PingAsync(PingTimeout); state.LastPing = DateTime.UtcNow; } if (state.ReaderTask == null || state.ReaderTask.IsCompleted) { state.ReaderTask = connect.ReadOnceAsync(); } if (state.ReaderTask.IsCanceled || state.ReaderTask.IsFaulted) { throw state.ReaderTask.Exception; } } catch { Close(client_id); continue; } } var prepare_add_length = prepare_to_add.Count; if (prepare_add_length != 0) { for (int i = 0; i < prepare_add_length; i++) { var current = prepare_to_add[0]; connects.Add(current.Key, current.Value); prepare_to_add.RemoveAt(0); } } var prepare_remove_length = prepare_to_remove.Count; if (prepare_remove_length != 0) { for (int i = 0; i < prepare_remove_length; i++) { var current = prepare_to_remove[0]; connects.Remove(current); prepare_to_remove.RemoveAt(0); } } } }) { IsBackground = true }; ioThread.Start(); listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.NoDelay = true; IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(bindIp), bindRtmpPort); listener.Bind(localEndPoint); listener.Listen(10); }