/// <summary> /// retrieve the remote session clipboard /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load( object sender, EventArgs e) { // if cookies are enabled, the http session id is added to the http request headers; otherwise, it's added to the http request url // in both cases, the given http session is automatically bound to the current http context RemoteSessionManager remoteSessionManager = null; try { // retrieve the remote session manager for the current http session remoteSessionManager = (RemoteSessionManager)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSessionManager.ToString()]; } catch (Exception exc) { System.Diagnostics.Trace.TraceError("Failed to retrieve the remote session manager for the http session {0}, ({1})", HttpContext.Current.Session.SessionID, exc); return; } try { System.Diagnostics.Trace.TraceInformation("Requesting remote clipboard, remote session {0}", remoteSessionManager.RemoteSession.Id); remoteSessionManager.SendCommand(RemoteSessionCommand.RequestRemoteClipboard); } catch (Exception exc) { System.Diagnostics.Trace.TraceError("Failed to retrieve remote clipboard, remote session {0} ({1})", remoteSessionManager.RemoteSession.Id, exc); } }
/// <summary> /// stop the rdp session /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void DisconnectButtonClick( object sender, EventArgs e) { // disconnect the active remote session, if any and connected if (RemoteSessionManager != null && (RemoteSessionManager.RemoteSession.State == RemoteSessionState.Connecting || RemoteSessionManager.RemoteSession.State == RemoteSessionState.Connected)) { try { // update the remote session state RemoteSessionManager.RemoteSession.State = RemoteSessionState.Disconnecting; // send a disconnect command to the rdp client RemoteSessionManager.SendCommand(RemoteSessionCommand.CloseRdpClient); // update controls UpateControls(); } catch (Exception exc) { System.Diagnostics.Trace.TraceError("Failed to disconnect remote session {0} ({1})", RemoteSessionManager.RemoteSession.Id, exc); } } }
/// <summary> /// send user input(s) (mouse, keyboard) to the rdp session /// if long-polling is disabled (xhr only), also returns image data within the response /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load( object sender, EventArgs e) { // if cookies are enabled, the http session id is added to the http request headers; otherwise, it's added to the http request url // in both cases, the given http session is automatically bound to the current http context RemoteSessionManager remoteSessionManager = null; try { // retrieve the remote session manager for the current http session remoteSessionManager = (RemoteSessionManager)HttpContext.Current.Session[HttpSessionStateVariables.RemoteSessionManager.ToString()]; } catch (Exception exc) { System.Diagnostics.Trace.TraceError("Failed to retrieve the remote session manager for the http session {0}, ({1})", HttpContext.Current.Session.SessionID, exc); return; } try { // retrieve params var data = HttpContext.Current.Request.QueryString["data"]; var fsu = int.Parse(HttpContext.Current.Request.QueryString["fsu"]) == 1; var imgIdx = int.Parse(HttpContext.Current.Request.QueryString["imgIdx"]); var imgEncoding = HttpContext.Current.Request.QueryString["imgEncoding"]; var imgQuality = int.Parse(HttpContext.Current.Request.QueryString["imgQuality"]); var imgReturn = int.Parse(HttpContext.Current.Request.QueryString["imgReturn"]) == 1; var bandwidthRatio = int.Parse(HttpContext.Current.Request.QueryString["bandwidthRatio"]); // image encoding var encoding = ImageEncoding.JPEG; Enum.TryParse(imgEncoding, true, out encoding); remoteSessionManager.ImageEncoding = encoding; // throttle the image quality depending on the bandwidth usage ratio if (bandwidthRatio >= (int)ImageQualityTweakBandwidthRatio.HigherBound) { remoteSessionManager.ImageQuality = imgQuality / 4; } else if (bandwidthRatio >= (int)ImageQualityTweakBandwidthRatio.LowerBound && bandwidthRatio < (int)ImageQualityTweakBandwidthRatio.HigherBound) { remoteSessionManager.ImageQuality = imgQuality / 2; } else { remoteSessionManager.ImageQuality = imgQuality; } // if defined, send the user input(s) through the rdp session // also, a websocket triggers periodical dummy xhr calls, without data, in order to keep the http session alive; such calls musn't close the websocket! if (!string.IsNullOrEmpty(data)) { remoteSessionManager.SendUserEvent(data); // if a websocket is set at this step, the client had probably changed the rendering mode (html5 -> html4) or configuration while the remote session is active, then reloaded the page (F5) // close the websocket (a new one will be set if the client change back to html5 again...) if (remoteSessionManager.WebSocket != null) { System.Diagnostics.Trace.TraceInformation("Removing no longer used websocket (the client had probably changed the rendering mode from HTML5 to HTML4 then reloaded the page (F5)), remote session {0}", remoteSessionManager.RemoteSession.Id); remoteSessionManager.WebSocket.Close(); remoteSessionManager.WebSocket = null; } } // if requested, ask for a fullscreen update if (fsu) { System.Diagnostics.Trace.TraceInformation("Requesting fullscreen update, remote session {0}", remoteSessionManager.RemoteSession.Id); remoteSessionManager.SendCommand(RemoteSessionCommand.SendFullscreenUpdate); } // xhr only if (imgReturn) { var image = remoteSessionManager.GetNextUpdate(imgIdx); if (image != null) { System.Diagnostics.Trace.TraceInformation("Returning image {0} ({1}), remote session {2}", image.Idx, (image.Fullscreen ? "screen" : "region"), remoteSessionManager.RemoteSession.Id); var imgData = image.Idx + "," + image.PosX + "," + image.PosY + "," + image.Width + "," + image.Height + "," + image.Format.ToString().ToLower() + "," + image.Quality + "," + image.Base64Data + "," + image.Fullscreen.ToString().ToLower(); // write the output HttpContext.Current.Response.Write(imgData); } // ensure the remote session is still connected else if (remoteSessionManager.RemoteSession.State == RemoteSessionState.Disconnected) { HttpContext.Current.Response.Write("disconnected"); } // the remote clipboard content was requested else if (remoteSessionManager.ClipboardRequested) { HttpContext.Current.Response.Write(string.Format("clipboard|{0}", remoteSessionManager.ClipboardText)); remoteSessionManager.ClipboardRequested = false; } } } catch (Exception exc) { System.Diagnostics.Trace.TraceError("Failed to send user input(s), remote session {0} ({1})", remoteSessionManager.RemoteSession.Id, exc); } }
private static void ProcessMessage(IWebSocketConnection socket, string message) { if (string.IsNullOrEmpty(message)) { Trace.TraceWarning("Received null or empty websocket message"); return; } var msgParams = message.Split(new[] { "|" }, StringSplitOptions.None); if (msgParams.Length >= 2) { var httpSessionId = msgParams[1]; RemoteSessionManager remoteSessionManager = null; try { // retrieve the remote session manager for the given http session (the http session id is passed as parameter as the ws protocol doesn't pass it automatically) var remoteSessionsManagers = (IDictionary <string, RemoteSessionManager>)_global.Application[HttpApplicationStateVariables.RemoteSessionsManagers.ToString()]; remoteSessionManager = remoteSessionsManagers[httpSessionId]; } catch (Exception exc) { Trace.TraceError("Failed to retrieve the remote session manager for the http session {0}, ({1})", httpSessionId, exc); return; } try { switch (msgParams[0]) { // user input (mouse, keyboard) case "input": var data = msgParams[2]; var fsu = int.Parse(msgParams[3]) == 1; var imgIdx = int.Parse(msgParams[4]); var imgEncoding = msgParams[5]; var imgQuality = int.Parse(msgParams[6]); var bandwidthRatio = int.Parse(msgParams[7]); var newSocket = int.Parse(msgParams[8]) == 1; var timestamp = long.Parse(msgParams[9]); // if the socket is new, bind it to the remote session manager // close the old one, if any if (newSocket) { // ensure the remote session is still connected if (remoteSessionManager.RemoteSession.State == RemoteSessionState.Disconnected) { if (socket.IsAvailable) { socket.Send("disconnected"); } return; } if (remoteSessionManager.WebSocket != null) { remoteSessionManager.WebSocket.Close(); } remoteSessionManager.WebSocket = socket; } // image encoding var encoding = ImageEncoding.JPEG; Enum.TryParse(imgEncoding, true, out encoding); remoteSessionManager.ImageEncoding = encoding; // throttle the image quality depending on the bandwidth usage ratio if (bandwidthRatio >= (int)ImageQualityTweakBandwidthRatio.HigherBound) { remoteSessionManager.ImageQuality = imgQuality / 4; } else if (bandwidthRatio >= (int)ImageQualityTweakBandwidthRatio.LowerBound && bandwidthRatio < (int)ImageQualityTweakBandwidthRatio.HigherBound) { remoteSessionManager.ImageQuality = imgQuality / 2; } else { remoteSessionManager.ImageQuality = imgQuality; } // if defined, send the user input(s) through the rdp session if (!string.IsNullOrEmpty(data)) { remoteSessionManager.SendUserEvent(data); } // if requested, ask for a fullscreen update if (fsu) { Trace.TraceInformation("Requesting fullscreen update, remote session {0}", remoteSessionManager.RemoteSession.Id); remoteSessionManager.SendCommand(RemoteSessionCommand.SendFullscreenUpdate); } // acknowledge the message processing with the given timestamp; it will be used by the client to compute the roundtrip delay socket.Send("ack," + timestamp); break; // remote session has been disconnected; close the websocket case "close": if (remoteSessionManager.WebSocket != null) { remoteSessionManager.WebSocket.Close(); remoteSessionManager.WebSocket = null; } break; } } catch (Exception exc) { Trace.TraceError("Failed to process websocket message, remote session {0} ({1})", remoteSessionManager.RemoteSession.Id, exc); } } else { Trace.TraceError("Failed to parse websocket message {0}", message); } }