private static void ProceedCommand()
        {
            Console.WriteLine("Queue length = " + Queue.Count);

            if (Queue.Count == 0)
            {
                Thread.Sleep(40);
            }
            else
            {
                var command = (Command)Queue.Dequeue();

                if (command is QueryStateCommand)
                {
                    var queryStateCommand = command as QueryStateCommand;

                    Conference conference;
                    //Если пришел запрос состояния без id конференции (на создание)
                    if (string.IsNullOrWhiteSpace(queryStateCommand.ConferenceId))
                    {
                        string id = Conference.GenerateId();
                        while (Conferences.Keys.Contains(id))
                        {
                            id = Conference.GenerateId();
                        }

                        conference = Conference.Start(id, (ServerWebSocketConnection)queryStateCommand.SenderConnection,
                                                      queryStateCommand.Width, queryStateCommand.Height, queryStateCommand.ClientName);

                        Conferences.Add(conference.Id, conference);
                    }
                    else
                    {
                        Conferences.TryGetValue(queryStateCommand.ConferenceId, out conference);
                    }

                    if (conference != null)
                    {
                        queryStateCommand.SenderConnection.ConnectionStateChangedEvent += (sender, args) =>
                        {
                            if (args.Value)
                            {
                                return;
                            }
                            var disconnectCommand = new DisconnectCommand
                            {
                                SenderConnection = queryStateCommand.SenderConnection
                            };
                            Queue.Enqueue(disconnectCommand);
                        };

                        Connections.Add((ServerWebSocketConnection)queryStateCommand.SenderConnection, conference.Id);
                        conference.AddConnection((ServerWebSocketConnection)queryStateCommand.SenderConnection, queryStateCommand.ClientName);

                        ((ServerWebSocketConnection)queryStateCommand.SenderConnection).SendState(conference.Id, ((ServerWebSocketConnection)queryStateCommand.SenderConnection).Id,
                                                                                                  command.SenderConnection == conference.PresenterConnection, conference.Bitmap.Size.Width, conference.Bitmap.Size.Height);

                        BroadcastParticipantsCommand(conference);
                    }
                    else
                    {
                        ((ServerWebSocketConnection)queryStateCommand.SenderConnection).SendState(string.Empty, string.Empty, false, 0, 0);
                        return;
                    }

                    if (command.SenderConnection != conference.PresenterConnection)
                    {
                        var quality = DiffContainer.Quality;

                        //Отсылаем последний вариант картинки
                        var data = DiffContainer.Split(
                            new KeyValuePair <Rectangle, Bitmap>(
                                new Rectangle(0, 0, conference.Bitmap.Size.Width, conference.Bitmap.Size.Height), conference.Bitmap), 50000, quality);

                        foreach (var d in data)
                        {
                            ((ServerWebSocketConnection)queryStateCommand.SenderConnection).SendDiff(conference.Id, new DiffItem(d, quality));
                        }
                    }
                }
                else if (command is DiffCommand)
                {
                    var diffCommand = command as DiffCommand;

                    Conference conference;
                    Conferences.TryGetValue(diffCommand.ConferenceId, out conference);

                    if (conference == null)
                    {
                        return;
                    }

                    conference.Graphics.DrawImage(DiffContainer.ByteArrayToImage(diffCommand.DiffItem.ImageBytes),
                                                  diffCommand.DiffItem.X, diffCommand.DiffItem.Y,
                                                  diffCommand.DiffItem.Width, diffCommand.DiffItem.Height);

                    foreach (var connection in conference.Connections)
                    {
                        if (connection == conference.PresenterConnection)
                        {
                            continue;
                        }
                        connection.SendDiff(conference.Id, diffCommand.DiffItem);
                    }
                }
                else if (command is DisconnectCommand)
                {
                    var disconnectCommand = command as DisconnectCommand;

                    string conferenceId =
                        Connections[((ServerWebSocketConnection)disconnectCommand.SenderConnection)];
                    Connections.Remove(((ServerWebSocketConnection)disconnectCommand.SenderConnection));

                    Conference conference;
                    Conferences.TryGetValue(conferenceId, out conference);

                    if (conference != null)
                    {
                        conference.RemoveConnection(((ServerWebSocketConnection)disconnectCommand.SenderConnection));

                        BroadcastParticipantsCommand(conference);

                        if (conference.Connections.Count == 0 || conference.PresenterConnection == null)
                        {
                            Conferences.Remove(conferenceId);
                        }
                    }
                }
                else if (command is PaintAddFigureCommand)
                {
                    var addFigureCommand = command as PaintAddFigureCommand;

                    Conference conference = Conferences[addFigureCommand.ConferenceId];

                    if (conference == null)
                    {
                        return;
                    }

                    foreach (var connection in conference.Connections)
                    {
                        if (command.SenderConnection != connection)
                        {
                            connection.PaintAddFigureCommand(conference.Id, addFigureCommand.FigureId, addFigureCommand.Points, addFigureCommand.Color);
                        }
                    }
                }
                else if (command is PaintDeleteFigureCommand)
                {
                    var deleteFigureCommand = command as PaintDeleteFigureCommand;

                    Conference conference = Conferences[deleteFigureCommand.ConferenceId];

                    if (conference == null)
                    {
                        return;
                    }

                    foreach (var connection in conference.Connections)
                    {
                        if (command.SenderConnection != connection)
                        {
                            connection.PaintDeleteFigureCommand(conference.Id, deleteFigureCommand.FigureId);
                        }
                    }
                }
                else if (command is InputCommand)
                {
                    var          connection   = (ServerWebSocketConnection)command.SenderConnection;
                    InputCommand inputCommand = command as InputCommand;

                    Conference conference = Conferences[inputCommand.ConferenceId];

                    if (conference == null)
                    {
                        return;
                    }

                    bool isAllowed = PresenterToControllingClient.ContainsKey(conference.PresenterConnection.Id) &&
                                     PresenterToControllingClient[conference.PresenterConnection.Id].Equals(connection.Id);
                    if (!isAllowed)
                    {
                        return;
                    }

                    conference.PresenterConnection.SendInput(conference.Id, inputCommand.MouseInput);
                }
                else if (command is ControlAccessCommand)
                {
                    var        controlAccessCommand = command as ControlAccessCommand;
                    Conference conference           = Conferences[controlAccessCommand.ConferenceId];
                    if (conference == null)
                    {
                        return;
                    }

                    if (controlAccessCommand.PresenterId.Equals("0"))
                    {
                        controlAccessCommand.PresenterId = conference.PresenterConnection.Id;
                    }

                    var isAllowed    = controlAccessCommand.IsAllowed;
                    var presenterId  = controlAccessCommand.PresenterId;
                    var conferenceId = controlAccessCommand.ConferenceId;
                    var clientId     = controlAccessCommand.ClientId;

                    if (!isAllowed)
                    {
                        if (PresenterToControllingClient.ContainsKey(presenterId) && PresenterToControllingClient[presenterId].Equals(clientId))
                        {
                            PresenterToControllingClient.Remove(presenterId);
                        }
                    }

                    if (PresenterToControllingClient.ContainsKey(presenterId))
                    {
                        var controllingClientId = PresenterToControllingClient[presenterId];
                        foreach (var connection in conference.Connections)
                        {
                            connection.ChangeControlAccess(conferenceId, presenterId, controllingClientId, false);
                        }
                        PresenterToControllingClient.Remove(presenterId);
                    }

                    if (isAllowed)
                    {
                        PresenterToControllingClient[presenterId] = clientId;
                    }

                    foreach (var connection in conference.Connections)
                    {
                        connection.ChangeControlAccess(conferenceId, presenterId, clientId, isAllowed);
                    }

                    var senderConnection = conference.Connections.FirstOrDefault(c => c.Id.Equals(controlAccessCommand.ClientId));
                    if (senderConnection == null)
                    {
                        return;
                    }

                    var clientConnection =
                        conference.Connections.FirstOrDefault(c => c.Id.Equals(controlAccessCommand.ClientId));

                    if (clientConnection == null)
                    {
                        return;
                    }

                    clientConnection.IsInputController = controlAccessCommand.IsAllowed;
                }
                else if (command is RequestControlCommand)
                {
                    var        senderConnection      = (ServerWebSocketConnection)command.SenderConnection;
                    var        requestControlCommand = command as RequestControlCommand;
                    Conference conference            = Conferences[requestControlCommand.ConferenceId];
                    if (conference == null)
                    {
                        return;
                    }

                    foreach (var connection in conference.Connections)
                    {
                        connection.RequestControl(requestControlCommand.ConferenceId, senderConnection.Id, requestControlCommand.IsAllowed);
                    }
                }
            }
        }
Exemple #2
0
        public void StartDiffDetectThread()
        {
            _runDiffDetectThread = false;

            if (_diffDetectThread != null)
            {
                while (_diffDetectThread.IsAlive)
                {
                    Thread.Sleep(100);
                }
            }

            _runDiffDetectThread = true;

            _diffDetectThread = new Thread(() =>
            {
                IDiffDetector diffDetector = new CustomDiffDetector(JpegQuality);

                //IDiffDetector _diffDetector = new DiffDetector();
                //IDiffDetector _diffDetector = new DiffDetectorOpenCvSharp();


                while (_runDiffDetectThread)
                {
                    try
                    {
                        var screenShot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                                    Screen.PrimaryScreen.Bounds.Height);

                        using (Graphics screenShotGraphics = Graphics.FromImage(screenShot))
                        {
                            screenShotGraphics.CopyFromScreen(0, 0, 0, 0,
                                                              new Size(
                                                                  Screen.PrimaryScreen.Bounds.Width,
                                                                  Screen.PrimaryScreen.Bounds.Height));

                            if (Math.Abs(ScreenshotScale - 1) > 0.01)
                            {
                                screenShot = new Bitmap(screenShot,
                                                        (int)
                                                        (Screen.PrimaryScreen.Bounds.Width * ScreenshotScale),
                                                        (int)
                                                        (Screen.PrimaryScreen.Bounds.Height * ScreenshotScale));
                            }
                        }

                        DiffContainer diffContainer = diffDetector.GetDiffs(screenShot);

                        var quality = DiffContainer.Quality;

                        diffContainer.Data = DiffContainer.Split(diffContainer.Data, 64000, quality);

                        foreach (var s in diffContainer.Data)
                        {
                            ClientWebSocketConnection.SendDiff(ConferenceId, new DiffItem(s, quality));
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("_diffDetectThread : " + ex.Message);
                    }
                    Thread.Sleep(_delay);
                }
            });
            _diffDetectThread.Start();
        }