public void RegisterSession(ClientSession.ClientSession clientSession) { if (clientSession.Channel?.Id != null) { Sessions.Add(clientSession.Channel); } ClientSessions.TryAdd(clientSession.SessionId, clientSession); }
public void UnregisterSession(ClientSession.ClientSession clientSession) { ClientSessions.TryRemove(clientSession.SessionId, out _); if (clientSession.Channel?.Id != null) { Sessions.Remove(clientSession.Channel); } }
public static void ScheduleSessionChecker(this IApplicationBuilder app) { var db = app.GetService <IJsonDataStore <JsonDatabase> >(); ClientSessions.Initiate(db); var settings = app.GetService <IOptionsSnapshot <AppSettings> >().Value; var timer = new Timer(CheckSessionsAlive.DoJob, app, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(settings.CheckSessionsIntervalSeconds)); }
/// <summary> /// 启动ws /// </summary> /// <param name="bindIp"></param> /// <param name="bindWebsocketPort"></param> void WebSocketListener(string bindIp, int bindWebsocketPort) { var websocketServer = new WebSocketServer("ws://" + bindIp.ToString() + ":" + bindWebsocketPort.ToString()); if (this.Certificate != null) { websocketServer.Certificate = Certificate; websocketServer.EnabledSslProtocols = SslProtocols.Default; } websocketServer.ListenerSocket.NoDelay = true; websocketServer.Start(wsSocket => { wsSocket.OnOpen = () => { var path = wsSocket.ConnectionInfo.Path.Split('/'); if (path.Length != 3) { wsSocket.Close(); } ushort clientID = GetNewClientId(); RegisterPlay(path[1], path[2], clientID); IStreamConnect wsConnect = new WebsocketConnect(this, wsSocket, clientID, this.Context, this.AmfEncoding); ClientSessions.Add(clientID, new ClientSession() { Connect = wsConnect, LastPing = DateTime.UtcNow, ReaderTask = null, WriterTask = null }); try { SendMetadataToPlayer(path[1], path[2], wsConnect, flvHeader: true); ConnectToClient(path[1], path[2], clientID, ChannelType.Audio); ConnectToClient(path[1], path[2], clientID, ChannelType.Video); } catch (Exception ex) { FleckLog.Error("ws请求了一个不存在的直播,请检查直播地址是否有误或检查直播状态,error:", ex); DisconnectSession(clientID); } }; wsSocket.OnPing = b => wsSocket.SendPong(b); }); }
public ActionResult UpdateClient(ClientUpdateApiModel client) { try { ClientSessions.Update(client.ServerId, client.ServerName); ViewUpdater.Update(); return(Ok()); } catch (Exception ex) { return(StatusCode(500, ex.ToString())); throw; } }
public ActionResult RemoveClient([FromBody] string serverId) { try { ClientSessions.Remove(serverId); ViewUpdater.Update(); return(Ok()); } catch (Exception ex) { return(StatusCode(500, ex.ToString())); throw; } }
public override ServerInfo ProcessData(CClientInfo Request) { ServerInfo Reply = new ServerInfo(); uint ID = Request.ClientID; if (ClientSessions.ContainsKey(ID) == false) { if (ClientSessions.Count < RGOServiceBase.maxNrClients) { var clientConn = new RGOClientConnection(ID) { IsLocal = Connection.IsOnLoopback, BatchSize = RGOServiceBase.LocalBatchsize, ConnectionName = Connection.Address }; if (!Connection.IsOnLoopback) { clientConn.BatchSize = RGOServiceBase.RemoteBatchsize; } ClientSessions.Add(ID, clientConn); Reply.ConnectionAccepted = true; } else { Reply.ConnectionAccepted = false; } } else { ClientSessions[ID].ClientCommCounter = Request.Counter; log.Debug($"Client: {Request.ClientID}, counter:{Request.Counter}"); Reply.SetTime(); Reply.SessionCounter = Request.Counter; Reply.CycleTime = RGOServiceStarter.MeasuredCycleTime; Reply.ConnectionAccepted = true; } return(Reply); }
internal 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; ClientSession client_state = null; if (e.type != i.Item3) { continue; } ClientSessions.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 ActionResult RemoveClients([FromBody] GridModel <ClientUpdateApiModel, string> vm) { try { foreach (var item in vm.Deleted) { ClientSessions.Remove(item.ServerId); } ViewUpdater.Update(); return(Ok()); } catch (Exception ex) { return(StatusCode(500, ex.ToString())); throw; } }
public void Stop() { try { Started = false; ClientSessionDictionary nClientSessions = null; lock (_locker) { nClientSessions = ClientSessions.Clone() as ClientSessionDictionary; } foreach (var current in nClientSessions) { ClientSession state = current.Value; ushort client_id = current.Key; IStreamConnect connect = state.Connect; if (connect.IsDisconnected) { continue; } try { DisconnectSession(client_id); } catch (Exception e) { Console.WriteLine(e.StackTrace); } } lock (_locker) { ClientSessions.Clear(); } _listener.Close(); } catch { } }
public async Task <ActionResult <string> > Push(LogViewModel data) { try { var item = populteListItem(data); ClientSessions.Add(item); ViewUpdater.Update(); using (var client = new HttpClient()) { var response = await client.PostAsJsonAsync("http://clients.ranpod.com/api/data/push", data); return(StatusCode((int)response.StatusCode, $"Server response :{await response.Content.ReadAsStringAsync()}")); } } catch (Exception ex) { return(StatusCode(500, ex.ToString())); throw; } }
internal bool UnRegisterPublish(ushort clientId) { var key = _clientRouteTable.First(x => x.Value == clientId).Key; ClientSession state; if (_clientRouteTable.ContainsKey(key)) { if (ClientSessions.TryGetValue(clientId, out state)) { IStreamConnect connect = state.Connect; connect.ChannelDataReceived -= SendDataHandler; var clients = _routedClients.FindAll(t => t.Item2 == clientId); foreach (var i in clients) { DisconnectSession(i.Item1); } _routedClients.RemoveAll(t => t.Item2 == clientId); } _clientRouteTable.Remove(key); return(true); } return(false); }
internal void ConnectToClient(string liveChannel, string path, ushort clientID, ChannelType channel_type) { ClientSession clientSession; ushort cachedClientID; var uri = new Uri("http://127.0.0.1/" + path); var key = new Tuple <string, string>(liveChannel, uri.AbsolutePath); if (!_clientRouteTable.TryGetValue(key, out cachedClientID)) { throw new KeyNotFoundException("请求地址不存在~"); } if (!ClientSessions.TryGetValue(cachedClientID, out clientSession)) { IStreamConnect connect = clientSession.Connect; _clientRouteTable.Remove(key); throw new KeyNotFoundException("请求客户端不存在~"); } _routedClients.Add(new Tuple <ushort, ushort, ChannelType>(clientID, cachedClientID, channel_type)); }
/// <summary> /// 启动连接状态检查线程 /// 执行rtmp的读写异步任务 /// </summary> void ClientWorkHandler() { _clientWorkThread = new Thread(() => { while (true) { try { if (ClientSessions.Count() < 1) { Thread.Sleep(1); continue; } ClientSessionDictionary nclientSessions = null; lock (_locker) { nclientSessions = ClientSessions.Clone() as ClientSessionDictionary; } Parallel.ForEach(nclientSessions, current => { ClientSession state = current.Value; ushort client_id = current.Key; IStreamConnect connect = state.Connect; try { if (connect.IsDisconnected) { DisconnectSession(client_id); } else { if (state.WriterTask == null) { state.WriterTask = connect.WriteOnceAsync(); } else { if (state.WriterTask.IsCompleted) { state.WriterTask = connect.WriteOnceAsync(); } if (state.WriterTask.IsCanceled || state.WriterTask.IsFaulted) { this.DisconnectSession(current.Key); //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) { this.DisconnectSession(current.Key); //throw state.ReaderTask.Exception; } } } } catch { DisconnectSession(client_id); } }); } catch (Exception ex) { FleckLog.Error("ConnectStateCheckUp.Thread.Error", ex); } } }) { IsBackground = true }; _clientWorkThread.Start(); }
/// <summary> /// 将发布者的媒体的meta发给播放者 /// </summary> /// <param name="liveChannel"></param> /// <param name="path"></param> /// <param name="self"></param> /// <param name="flvHeader"></param> internal void SendMetadataToPlayer(string liveChannel, string path, IStreamConnect self, bool flvHeader = false) { ushort publisherID; IStreamConnect publisher; ClientSession publisherState; var uri = new Uri("http://127.0.0.1/" + path); var key = new Tuple <string, string>(liveChannel, uri.AbsolutePath); if (!_clientRouteTable.TryGetValue(key, out publisherID)) { throw new KeyNotFoundException("请求地址不存在~"); } if (!ClientSessions.TryGetValue(publisherID, out publisherState)) { _clientRouteTable.Remove(key); throw new KeyNotFoundException("请求客户端不存在~"); } publisher = publisherState.Connect; if (publisher.IsPublishing) { var flv_metadata = (Dictionary <string, object>)publisher.FlvMetaData.MethodCall.Parameters[0]; var has_audio = flv_metadata.ContainsKey("audiocodecid"); var has_video = flv_metadata.ContainsKey("videocodecid"); if (flvHeader) { var header_buffer = Enumerable.Repeat <byte>(0x00, 13).ToArray <byte>(); header_buffer[0] = 0x46; header_buffer[1] = 0x4C; header_buffer[2] = 0x56; header_buffer[3] = 0x01; byte has_audio_flag = 0x01 << 2; byte has_video_flag = 0x01; byte type_flag = 0x00; if (has_audio) { type_flag |= has_audio_flag; } if (has_video) { type_flag |= has_video_flag; } header_buffer[4] = type_flag; var data_offset = BitConverter.GetBytes((uint)9); header_buffer[5] = data_offset[3]; header_buffer[6] = data_offset[2]; header_buffer[7] = data_offset[1]; header_buffer[8] = data_offset[0]; self.SendRawData(header_buffer); } self.SendAmf0Data(publisher.FlvMetaData); if (has_audio) { self.SendAmf0Data(publisher.AACConfigureRecord); } if (has_video) { self.SendAmf0Data(publisher.AvCConfigureRecord); } } }