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); } } } }
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(); }