コード例 #1
0
        public void RegisterSession(ClientSession.ClientSession clientSession)
        {
            if (clientSession.Channel?.Id != null)
            {
                Sessions.Add(clientSession.Channel);
            }

            ClientSessions.TryAdd(clientSession.SessionId, clientSession);
        }
コード例 #2
0
        public void UnregisterSession(ClientSession.ClientSession clientSession)
        {
            ClientSessions.TryRemove(clientSession.SessionId, out _);

            if (clientSession.Channel?.Id != null)
            {
                Sessions.Remove(clientSession.Channel);
            }
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        /// <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);
            });
        }
コード例 #5
0
        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;
            }
        }
コード例 #6
0
        public ActionResult RemoveClient([FromBody] string serverId)
        {
            try
            {
                ClientSessions.Remove(serverId);

                ViewUpdater.Update();

                return(Ok());
            }

            catch (Exception ex)
            {
                return(StatusCode(500, ex.ToString()));

                throw;
            }
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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();
                }
            }
        }
コード例 #9
0
        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;
            }
        }
コード例 #10
0
        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 { }
        }
コード例 #11
0
        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;
            }
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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));
        }
コード例 #14
0
        /// <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();
        }
コード例 #15
0
        /// <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);
                }
            }
        }