public static async Task <WebSocketConnection> Connect(Uri peer, Action <string> log)
        {
            ClientWebSocket clientWebSocket = new ClientWebSocket();

            await clientWebSocket.ConnectAsync(peer, CancellationToken.None);

            switch (clientWebSocket.State)
            {
            case WebSocketState.Open:
                // Connection log invoke
                log?.Invoke($"Opened connection to remote server: {peer}");

                // ===== Creating socket connection object =====
                WebSocketConnection socketConnection = new ClientWebSocketConnection(clientWebSocket, peer, log)
                {
                    // ===== Attaching data parser to on message event =====
                    OnMessage = DataContext.Instance.ReceiveData
                };

                // Setting the current connection for singleton connection implementation
                CurrentConnection = socketConnection;

                return(socketConnection);

            default:
                string errMsg = $"Cannot connect to remote server {peer} with status {clientWebSocket.State}";
                log?.Invoke(errMsg);
                throw new WebSocketException(errMsg);
            }
        }
Beispiel #2
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            DiffContainer.Init(byte.Parse(ConfigurationSettings.AppSettings["quality"]));

            _connectionManager = new ConnectionManager {
                ServerIp = "localhost"
            };
            _connectForm = new ConnectForm {
                ServerIp = _connectionManager.ServerIp
            };
            _mainForm = new MainForm
            {
                ScreenshotScale   = float.Parse(ConfigurationSettings.AppSettings["scale"]),
                ScreenshotTimeout = int.Parse(ConfigurationSettings.AppSettings["timeout"]),
                JpegQuality       = byte.Parse(ConfigurationSettings.AppSettings["quality"])
            };

            _connectForm.VisibleChanged += (sender, eventArgs) =>
            {
                if (!_connectForm.Visible)
                {
                    _connectionManager.ServerIp = _connectForm.ServerIp;

                    var clientWebSocketConnection = new ClientWebSocketConnection(_connectionManager.GetConnection());
                    _mainForm.ClientWebSocketConnection = clientWebSocketConnection;
                    _mainForm.ConferenceId = _connectForm.ConferenceId;
                    _mainForm.ClientName   = _connectForm.ClientName;

                    _connectionManager.Connect();

                    _mainForm.Show();
                }
                else
                {
                    _connectionManager.Disconnect();
                }
            };

            _mainForm.VisibleChanged += (sender, eventArgs) =>
            {
                if (!_mainForm.Visible)
                {
                    _connectForm.Show();
                }
            };

            Application.Run(_connectForm);
        }
Beispiel #3
0
        private void ClientWebSocketConnectionOnConnectionStateChanged(object sender, SimpleEventArgs <bool> webSocketEventArgs)
        {
            Invoke(new Action(() =>
            {
                if (webSocketEventArgs.Value)
                {
                    connectionStateValueLabel.Text = "Connected";

                    ClientWebSocketConnection.QueryState(ConferenceId, (int)(Screen.PrimaryScreen.Bounds.Width * ScreenshotScale), (int)(Screen.PrimaryScreen.Bounds.Height * ScreenshotScale), ClientName);
                }
                else
                {
                    connectionStateValueLabel.Text = "Connecting...";
                    _runDiffDetectThread           = false;
                    _runProcessCommandsThread      = false;
                }
            }));
        }
Beispiel #4
0
        private void InitPaintControl()
        {
            _paintControl = new PainterControl();
            tableLayoutPanel.Controls.Add(_paintControl, 1, 1);
            _paintControl.Dock = DockStyle.Fill;

            _paintControl.FigureAdded += (s, e) => ClientWebSocketConnection.PaintAddFigureCommand(ConferenceId, e.Value.Id, e.Value.Points,
                                                                                                   e.Value.Color);

            _paintControl.FigureRemoved += (s, e) => ClientWebSocketConnection.PaintDeleteFigureCommand(ConferenceId, e.Value);

            _paintControl.MouseInputed += (sender, args) => ClientWebSocketConnection.SendInput(ConferenceId, args.Value);

            _paintControl.FullScreenCanceled += (s, e) =>
            {
                silentRadioButton.Checked = true;
            };
        }
        /// <summary>
        /// Attempts to extract SIP messages from the data that has been received on the client web socket SIP stream connection.
        /// </summary>
        /// <param name="recvChannel">The receiving SIP channel.</param>
        /// <param name="clientConn">The web socket client connection properties including pending receive buffer</param>
        /// <param name="buffer">The buffer holding the current data from the stream. Note that the buffer can
        /// stretch over multiple receives.</param>
        /// <param name="bytesRead">The bytes that were read by the latest receive operation (the new bytes available).</param>
        private void ExtractSIPMessages(SIPChannel recvChannel, ClientWebSocketConnection clientConn,
                                        ArraySegment <byte> buffer, int bytesRead)
        {
            if (bytesRead + clientConn.RecvEndPosn > clientConn.PendingReceiveBuffer.Length)
            {
                // Don't have enough space for the read. Throw away the pending buffer and hope the SIP transaction is re-attempted.
                clientConn.RecvStartPosn = clientConn.RecvEndPosn = 0;
            }

            Buffer.BlockCopy(buffer.ToArray(), 0, clientConn.PendingReceiveBuffer, clientConn.RecvEndPosn, bytesRead);
            clientConn.RecvEndPosn += bytesRead;

            int bytesSkipped = 0;

            byte[] sipMsgBuffer = SIPMessageBuffer.ParseSIPMessageFromStream(clientConn.PendingReceiveBuffer,
                                                                             clientConn.RecvStartPosn, clientConn.RecvEndPosn, out bytesSkipped);

            while (sipMsgBuffer != null)
            {
                // A SIP message is available.
                if (SIPMessageReceived != null)
                {
                    clientConn.LastTransmission = DateTime.Now;
                    SIPMessageReceived(recvChannel, clientConn.LocalEndPoint, clientConn.RemoteEndPoint, sipMsgBuffer)
                    .Wait();
                }

                clientConn.RecvStartPosn += (sipMsgBuffer.Length + bytesSkipped);

                if (clientConn.RecvStartPosn == clientConn.RecvEndPosn)
                {
                    // All data has been successfully extracted from the receive buffer.
                    clientConn.RecvStartPosn = clientConn.RecvEndPosn = 0;
                    break;
                }
                else
                {
                    // Try and extract another SIP message from the receive buffer.
                    sipMsgBuffer = SIPMessageBuffer.ParseSIPMessageFromStream(clientConn.PendingReceiveBuffer,
                                                                              clientConn.RecvStartPosn, clientConn.RecvEndPosn, out bytesSkipped);
                }
            }
        }
        public static async Task <WebSocketConnection> Connect(Uri peer, Action <string> log)
        {
            ClientWebSocket clientWebSocket = new ClientWebSocket();
            await clientWebSocket.ConnectAsync(peer, CancellationToken.None);

            switch (clientWebSocket.State)
            {
            case WebSocketState.Open:
                log?.Invoke($"Opened connection to remote server: {peer}");

                WebSocketConnection socketConnection = new ClientWebSocketConnection(clientWebSocket, peer, log);

                socketConnection.onMessage = DataContext.Instance.ReceiveData;
                CurrentConnection          = socketConnection;

                return(socketConnection);

            default:
                string errorMessage = $"Cannot connect to remote server {peer} with status {clientWebSocket.State}";
                log?.Invoke(errorMessage);
                throw new WebSocketException(errorMessage);
            }
        }
Beispiel #7
0
        private void RadioButtonOnCheckedChanged(object sender, EventArgs eventArgs)
        {
            if (sender == inputRadioButton)
            {
                if (inputRadioButton.Checked)
                {
                    if (_isPresenter)
                    {
                        return;
                    }

                    ClientWebSocketConnection.RequestControlCommand(ConferenceId, _id, true);
                }
                else
                {
                    ClientWebSocketConnection.RequestControlCommand(ConferenceId, _id, false);
                    ClientWebSocketConnection.ControlAccessCommand(ConferenceId, "0", _id, false); //Хак (передаем ноль, так как в данной реализации может быть только один презентер и этот ноль переопределиться на сервере в нормальный id presenter'а)
                }
            }

            if (silentRadioButton.Checked)
            {
                _paintControl.Mode = PaintControlModes.Silent;
            }
            if (drawRadioButton.Checked)
            {
                if (_isPresenter)
                {
                    _topMostForm.SetClickThrough(false);
                }
                _paintControl.Mode = PaintControlModes.Draw;
            }
            if (inputRadioButton.Checked)
            {
                _paintControl.Mode = PaintControlModes.Input;
            }
        }
        /// <summary>
        /// Attempts a send to a remote web socket server. If there is an existing connection it will be used
        /// otherwise an attempt will made to establish a new one.
        /// </summary>
        /// <param name="serverEndPoint">The remote web socket server URI to send to.</param>
        /// <param name="buffer">The data buffer to send.</param>
        /// <returns>A success value or an error for failure.</returns>
        private async Task <SocketError> SendAsync(SIPEndPoint serverEndPoint, byte[] buffer)
        {
            try
            {
                string uriPrefix = (serverEndPoint.Protocol == SIPProtocolsEnum.wss)
                    ? WEB_SOCKET_SECURE_URI_PREFIX
                    : WEB_SOCKET_URI_PREFIX;
                var serverUri = new Uri($"{uriPrefix}{serverEndPoint.GetIPEndPoint()}");

                string connectionID = GetConnectionID(serverUri);
                serverEndPoint.ChannelID    = this.ID;
                serverEndPoint.ConnectionID = connectionID;

                if (m_egressConnections.TryGetValue(connectionID, out var conn))
                {
                    Logger.Logger.Debug(
                        $"Sending {buffer.Length} bytes on client web socket connection to {conn.ServerUri}.");

                    ArraySegment <byte> segmentBuffer = new ArraySegment <byte>(buffer);
                    await conn.Client.SendAsync(segmentBuffer, WebSocketMessageType.Text, true, m_cts.Token)
                    .ConfigureAwait(false);

                    return(SocketError.Success);
                }
                else
                {
                    // Attempt a new connection.
                    ClientWebSocket clientWebSocket = new ClientWebSocket();
                    await clientWebSocket.ConnectAsync(serverUri, m_cts.Token).ConfigureAwait(false);

                    Logger.Logger.Debug($"Successfully connected web socket client to {serverUri}.");

                    ArraySegment <byte> segmentBuffer = new ArraySegment <byte>(buffer);
                    await clientWebSocket.SendAsync(segmentBuffer, WebSocketMessageType.Text, true, m_cts.Token)
                    .ConfigureAwait(false);

                    var recvBuffer = new ArraySegment <byte>(new byte[2 * SIPStreamConnection.MaxSIPTCPMessageSize]);
                    Task <WebSocketReceiveResult> receiveTask = clientWebSocket.ReceiveAsync(recvBuffer, m_cts.Token);

                    // There's currently no way to get the socket IP end point used by the client web socket to establish
                    // the connection. Instead provide a dummy local end point that has as much of the information as we can.
                    IPEndPoint localEndPoint =
                        new IPEndPoint(
                            (serverEndPoint.Address.AddressFamily == AddressFamily.InterNetwork)
                                ? IPAddress.Any
                                : IPAddress.IPv6Any, 0);
                    SIPEndPoint localSIPEndPoint =
                        new SIPEndPoint(serverEndPoint.Protocol, localEndPoint, this.ID, connectionID);

                    ClientWebSocketConnection newConn = new ClientWebSocketConnection
                    {
                        LocalEndPoint  = localSIPEndPoint,
                        ServerUri      = serverUri,
                        RemoteEndPoint = serverEndPoint,
                        ConnectionID   = connectionID,
                        ReceiveBuffer  = recvBuffer,
                        ReceiveTask    = receiveTask,
                        Client         = clientWebSocket
                    };

                    if (!m_egressConnections.TryAdd(connectionID, newConn))
                    {
                        Logger.Logger.Error(
                            $"Could not add web socket client connected to {serverUri} to channel collection, closing.");
                        await Close(connectionID, clientWebSocket).ConfigureAwait(false);
                    }
                    else
                    {
                        if (!m_isReceiveTaskRunning)
                        {
                            m_isReceiveTaskRunning = true;
                            _ = Task.Factory.StartNew(MonitorReceiveTasks, TaskCreationOptions.LongRunning);
                        }
                    }

                    return(SocketError.Success);
                }
            }
            catch (SocketException sockExcp)
            {
                return(sockExcp.SocketErrorCode);
            }
        }
Beispiel #9
0
        public MainForm()
        {
            InitializeComponent();

            InitPaintControl();

            _topMostForm       = new TopMostForm();
            _topMostForm.Done += (sender, ea) =>
            {
                Focus();
                silentRadioButton.Checked = true;
            };

            dataGridView.AutoGenerateColumns = false;
            dataGridView.SelectionChanged   += (sender, ea) => dataGridView.ClearSelection();
            dataGridView.CellDoubleClick    += (sender, args) =>
            {
                if (!_isPresenter)
                {
                    return;
                }

                var clickedParticipantRowIndex = args.RowIndex;
                var participants = (IList <Participant>)dataGridView.DataSource;
                if (participants == null || clickedParticipantRowIndex < 0 ||
                    clickedParticipantRowIndex >= participants.Count)
                {
                    return;
                }

                var clickedParticipant = participants[clickedParticipantRowIndex];
                ClientWebSocketConnection.ControlAccessCommand(ConferenceId, _id, clickedParticipant.Id, true);
            };
            dataGridView.CellPainting += (sender, args) =>
            {
                if (dataGridView.Columns["ColorColumn"] != null && dataGridView.Columns["ColorColumn"].Index == args.ColumnIndex && args.RowIndex >= 0)
                {
                    using (
                        Brush gridBrush = new SolidBrush(dataGridView.GridColor),
                        backColorBrush = new SolidBrush(args.CellStyle.BackColor))
                    {
                        using (var gridLinePen = new Pen(gridBrush))
                        {
                            args.Graphics.FillRectangle(backColorBrush, args.CellBounds);

                            args.Graphics.DrawLine(gridLinePen, args.CellBounds.Left,
                                                   args.CellBounds.Bottom - 1, args.CellBounds.Right - 1,
                                                   args.CellBounds.Bottom - 1);
                            args.Graphics.DrawLine(gridLinePen, args.CellBounds.Right - 1,
                                                   args.CellBounds.Top, args.CellBounds.Right - 1,
                                                   args.CellBounds.Bottom);

                            args.Graphics.FillEllipse(new SolidBrush(Color.FromArgb((int)args.Value)), args.CellBounds.Location.X + args.CellBounds.Width / 2 - 5, args.CellBounds.Location.Y + args.CellBounds.Height / 2 - 5, 10, 10);

                            args.Handled = true;
                        }
                    }
                }
            };

            conferenceIdValueLabel.DoubleClick += (sender, args) => Clipboard.SetText(conferenceIdValueLabel.Text);

            VisibleChanged += (sender, ea) =>
            {
                if (!Visible)
                {
                    _topMostForm.Hide();

                    _runProcessCommandsThread = false;
                    _runDiffDetectThread      = false;
                    _isPresenter     = false;
                    _presenterWidth  = 0;
                    _presenterHeight = 0;
                    _id = string.Empty;

                    conferenceIdValueLabel.Text = string.Empty;
                    _paintControl.Image         = null;
                    roleValueLabel.Text         = string.Empty;

                    _paintControl.Mode        = PaintControlModes.Silent;
                    silentRadioButton.Checked = true;

                    //modeGroupBox.Enabled = false;

                    dataGridView.DataSource = null;
                }
            };

            FormClosing += (sender, ea) =>
            {
                Hide();
                ea.Cancel = true;
                if (_clientWebSocketConnection != null)
                {
                    _clientWebSocketConnection.ConnectionStateChangedEvent -=
                        ClientWebSocketConnectionOnConnectionStateChanged;
                }
            };

            silentRadioButton.CheckedChanged += RadioButtonOnCheckedChanged;
            drawRadioButton.CheckedChanged   += RadioButtonOnCheckedChanged;
            inputRadioButton.CheckedChanged  += RadioButtonOnCheckedChanged;
        }
Beispiel #10
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();
        }