Skip to content

Commit b996715

Browse files
committed
see changelog
1 parent 43f1125 commit b996715

25 files changed

+548
-506
lines changed

CHANGELOG

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
2021-03-07 Version 2.9.2
1+
2021-07-22 Version 2.9.3
2+
pre-requisites PLEASE READ! Myrtille requires a Windows Server edition (2012 R2 or greater) for itself (remote servers can be whatever OS with RDP enabled). Windows client editions (7, 8, 10 - whatever the version: pro, enterprise, ultimate, etc.) are not suitable for Myrtille due to the limitation to a maximum of 10 simultaneous connections on IIS!
3+
a client is now identified by an unique id instead of a cookie based key; this fixes a problem of sharing a session by url within the same browser
4+
disabled the share session by url feature (web.config), because it bypasses the share session by guest logic and make it difficult to track the active clients
5+
redesigned the adaptive display tweaking logic, based on bandwidth usage
6+
7+
2021-03-07 Version 2.9.2
28
FreeRDP is now built as a dll instead of an executable for better modularity and to reduce the risk of false positive detection of wfreerdp.exe by some antiviruses (mostly cloud based)
39
embedded interact.js and simple-keyboard (nodejs modules) into myrtille in order to remove dependencies on external CDNs (ans thus allow myrtille to be used standalone and not subject to external changes)
410
fixed a problem with the creation of the self-signed certificate that prevented Myrtille from installing correctly on Windows Server 2012 R2 (thanks camjcorley)

DOCUMENTATION.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,14 @@ I hope you will enjoy Myrtille! :)
4141
Special thanks to Catalin Trifanescu for its support.
4242

4343
## Installation
44-
Starting from version 2.8.0, the Myrtille requirements change: Windows 8.1 or Windows Server 2012 R2 or greater. This is partly because of the automated installation of the roles and features required by myrtille (which requires a modern powershell) and partly to deliver the best user experience possible (fast display and audio support), as HTML5 websockets (supported by all browsers nowadays) are only available in IIS 8.0+ (Windows 8.1 or Windows Server 2012 R2 or greater).
45-
46-
That said, Myrtille will continue to fallback to HTML4 (xhr and long-polling) if websockets are not enabled into IIS (it's optional) or if the websocket traffic is blocked by any network equipment.
44+
Windows Server OS (2012 R2 or greater, with IIS 8.0+, .NET 4.5+ and WCF/HTTP activation enabled). CAUTION! IIS on Windows client OSes (7, 8, 10 - all versions) is limited to 10 simultaneous connections only - across all http sessions - and will hang after that!
4745

4846
The .NET 4.5+ framework can be installed automatically by the myrtille installer, enabled as a feature of IIS (Web Server role > Applications Development > ASP.NET 4.5 on Windows Server 2012) or installed separately (https://www.microsoft.com/en-us/download/details.aspx?id=30653).
4947

5048
Into the roles and features management, ensure you have enabled **HTTP Activation** under ".NET Framework 4.5+ Features" > "WCF Services" (required by the Myrtille services and REST API).
5149

5250
The installer does install myrtille under the IIS default website and creates a custom application pool ("MyrtilleAppPool"). If you want to use another website or application pool, you can change it manually afterward (with the IIS manager).
5351

54-
CAUTION! IIS on Windows client OSes (7, 8, 10) is limited to 10 simultaneous connections only - across all http sessions - and will hang after that! (https://forums.asp.net/t/2062118.aspx?+limit+of+10+simultaneous+connections+imposed+). Use Windows Server editions for production environments.
55-
5652
All releases here: https://github.com/cedrozor/myrtille/releases
5753

5854
## Docker

Myrtille.Web/SendInputs.aspx.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,7 @@ protected void Page_Load(
5050
// retrieve the remote session for the current http session
5151
remoteSession = (RemoteSession)Session[HttpSessionStateVariables.RemoteSession.ToString()];
5252

53-
var clientId = Session.SessionID;
54-
if (Request.Cookies[HttpRequestCookies.ClientKey.ToString()] != null)
55-
{
56-
clientId = Request.Cookies[HttpRequestCookies.ClientKey.ToString()].Value;
57-
}
53+
var clientId = Request.QueryString["clientId"];
5854

5955
if (!remoteSession.Manager.Clients.ContainsKey(clientId))
6056
{
@@ -131,7 +127,7 @@ protected void Page_Load(
131127
// process input(s)
132128
if (!string.IsNullOrEmpty(data))
133129
{
134-
remoteSession.Manager.ProcessInputs(Session, data);
130+
remoteSession.Manager.ProcessInputs(Session, clientId, data);
135131
}
136132

137133
client.ImgIdx = imgIdx;

Myrtille.Web/Web.Base.config

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,12 @@
181181
<!-- allow audio plaback -->
182182
<add key="AllowAudioPlayback" value="true"/>
183183
<!-- share a session by url, with owner rights. set to false to disable and provide a session url spoofing protection. requires cookieless="UseUri" session state (system.web/sessionState section above) -->
184-
<!-- if a session is shared by url between different clients, each client is identified by a unique key instead of the http session id -->
185-
<add key="AllowShareSessionUrl" value="true"/>
184+
<add key="AllowShareSessionUrl" value="false"/>
186185
<!-- client ip protection -->
187186
<add key="ClientIPTracking" value="false"/>
188187
<!-- if the browser window/tab of the remote session owner is closed without disconnecting first, or if the connection is lost, delay (ms) before the remote session is disconnected by the gateway. value must be greater than "browserPulseInterval" defined into config.js (default 10 secs). 0 to disable -->
189188
<!-- this comes in addition but does not replace the session idle timeout, defined at the RDS level, which will disconnect the session after no user inputs are received for a given time, independently of Myrtille -->
190-
<add key="ClientIdleTimeout" value="0"/>
189+
<add key="OwnerIdleTimeout" value="0"/>
191190
<!-- audio buffer. improves the audio quality at the expense of a slight latency -->
192191
<add key="AudioBuffering" value="true"/>
193192
<!-- show or hide the toolbar (you can hide it if using your own UI) -->

Myrtille.Web/handlers/AudioSocketHandler.ashx.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public void ProcessRequest(HttpContext context)
3131
context.AcceptWebSocketRequest(
3232
new RemoteSessionAudioSocketHandler(
3333
context,
34-
string.IsNullOrEmpty(context.Request["binary"]) ? true : context.Request["binary"] == "true"));
34+
string.IsNullOrEmpty(context.Request["binary"]) ? true : context.Request["binary"] == "true",
35+
context.Request["clientId"]));
3536
}
3637
}
3738

Myrtille.Web/handlers/EventSourceHandler.ashx.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ public class EventSourceHandler : IHttpHandler, IReadOnlySessionState
2727
{
2828
public void ProcessRequest(HttpContext context)
2929
{
30-
var handler = new RemoteSessionEventSourceHandler(context);
30+
// retrieve params
31+
var clientId = context.Request.QueryString["clientId"];
32+
33+
var handler = new RemoteSessionEventSourceHandler(context, clientId);
3134

3235
try
3336
{

Myrtille.Web/handlers/LongPollingHandler.ashx.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class LongPollingHandler : IHttpHandler, IReadOnlySessionState
2828
public void ProcessRequest(HttpContext context)
2929
{
3030
// retrieve params
31+
var clientId = context.Request.QueryString["clientId"];
3132
var longPollingDuration = int.Parse(context.Request.QueryString["longPollingDuration"]);
3233
var imgIdx = int.Parse(context.Request.QueryString["imgIdx"]); // if needed
3334

@@ -36,7 +37,7 @@ public void ProcessRequest(HttpContext context)
3637
var startTime = DateTime.Now;
3738
var remainingTime = longPollingDuration;
3839

39-
var handler = new RemoteSessionLongPollingHandler(context);
40+
var handler = new RemoteSessionLongPollingHandler(context, clientId);
4041

4142
try
4243
{

Myrtille.Web/handlers/SocketHandler.ashx.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public void ProcessRequest(HttpContext context)
3939
new RemoteSessionSocketHandler(
4040
context,
4141
string.IsNullOrEmpty(context.Request["binary"]) ? true : context.Request["binary"] == "true",
42+
context.Request["clientId"],
4243
direction));
4344
}
4445
}

Myrtille.Web/js/audio/audiowebsocket.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function AudioWebsocket(base, config, dialog, display, network)
3737
config.setAudioBitrate(320);
3838
}
3939

40-
var wsUrl = config.getHttpServerUrl().replace('http', 'ws') + 'handlers/AudioSocketHandler.ashx?binary=true';
40+
var wsUrl = config.getHttpServerUrl().replace('http', 'ws') + 'handlers/AudioSocketHandler.ashx?binary=true&clientId=' + network.getClientId();
4141

4242
//dialog.showDebug('audio websocket server url: ' + wsUrl);
4343

Myrtille.Web/js/config.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ function Config(
126126
var imageEncoding = imageEncodingEnum.JPEG; // image encoding
127127
var imageQuality = 75; // image quality (%) higher = better; not applicable for PNG (lossless); tweaked dynamically to fit the available bandwidth if using JPEG, AUTO or WEBP encoding.
128128
var imageQuantity = 100; // image quantity (%) less images = lower cpu and bandwidth usage / faster; more = smoother display (skipping images may result in some display inconsistencies). tweaked dynamically to fit the available bandwidth; possible values: 5, 10, 20, 25, 50, 100 (lower = higher consolidation rate)
129-
var imageTweakBandwidthLowerThreshold = 50; // tweak the image quality & quantity depending on the available bandwidth (%): lower threshold. see network.js
130-
var imageTweakBandwidthHigherThreshold = 75; // tweak the image quality & quantity depending on the available bandwidth (%): higher threshold. see network.js
129+
var imageTweakBandwidthThreshold = 50; // tweak the image quality depending on the available bandwidth (%): threshold. see network.js
131130
var imageCountOk = 100; // reasonable number of images to display at once; for HTML4 (divs), used to clean the DOM (by requesting a fullscreen update) as too many divs may slow down the browser; not applicable for HTML5 (canvas)
132131
var imageCountMax = 300; // maximal number of images to display at once; for HTML4 (divs), used to clean the DOM (by reloading the page) as too many divs may slow down the browser; not applicable for HTML5 (canvas)
133132
var imageMode = imageModeEnum.AUTO; // image mode
@@ -145,15 +144,15 @@ function Config(
145144
var roundtripDurationMax = 0; // roundtrip duration (ms) above which the connection is considered having issues, displaying a warning message to the user. 0 to disable
146145
var bandwidthCheckInterval = 300000; // periodical bandwidth check; used to tweak down the images (quality & quantity) if the available bandwidth gets too low. it relies on a 5MB dummy file download, so this param shouldn't be set on a too short timer (or it will eat the bandwidth it's supposed to test...)
147146
var networkMode = networkModeEnum.AUTO; // network mode
148-
var websocketCount = 5; // number of concurrent websockets to send the user inputs and receive the display updates (RDP host only, max 100). splitting the load across multiple websockets can help to mitigate network lag. 1 for duplex websocket. CAUTION! IIS on Windows client OSes (7, 8, 10) is limited to 10 simultaneous connections only - across all http sessions - and will hang after that! use Windows Server editions for production environments
147+
var websocketCount = 2; // number of concurrent websockets to send the user inputs and receive the display updates (RDP host only, max 100). splitting the load across multiple websockets can help to mitigate network lag. 1 for duplex websocket. CAUTION! IIS on Windows client OSes (7, 8, 10) is limited to 10 simultaneous connections only - across all http sessions - and will hang after that! use Windows Server editions for production environments
149148
var httpSessionKeepAliveInterval = 30000; // periodical dummy xhr calls (ms) when using websocket, in order to keep the http session alive
150149
var xmlHttpTimeout = 3000; // xmlhttp requests (xhr) timeout (ms)
151150
var longPollingDuration = 60000; // long-polling requests duration (ms)
152151
var bufferEnabled = true; // buffer for user inputs; adjusted dynamically to fit the latency
153152
var bufferDelayBase = 0; // minimal buffering duration (ms)
154153
var bufferDelayEmpty = 10; // buffering duration (ms) when sending empty buffer
155154
var bufferSize = 128; // max number of buffered items (not size in bytes)
156-
var browserPulseInterval = 10000; // periodical browser pulse (ms); used server side to detect if the browser window/tab was closed (and possibly disconnect the remote session before the RDS idle timeout occurs; see "ClientIdleTimeout" into web.config)
155+
var browserPulseInterval = 10000; // periodical browser pulse (ms); used server side to detect if the browser window/tab was closed (and possibly disconnect the remote session before the RDS idle timeout occurs; see "OwnerIdleTimeout" into web.config)
157156

158157
// user
159158
var mouseMoveSamplingRate = 100; // sampling the mouse moves (%) may help to reduce the server load in applications that trigger a lot of updates (i.e.: imaging applications); possible values: 5, 10, 20, 25, 50, 100 (lower = higher drop rate)
@@ -204,8 +203,7 @@ function Config(
204203
this.setImageQuality = function(quality) { imageQuality = quality; };
205204
this.getImageQuantity = function() { return imageQuantity; };
206205
this.setImageQuantity = function(quantity) { imageQuantity = quantity; };
207-
this.getImageTweakBandwidthLowerThreshold = function() { return imageTweakBandwidthLowerThreshold; };
208-
this.getImageTweakBandwidthHigherThreshold = function() { return imageTweakBandwidthHigherThreshold; };
206+
this.getImageTweakBandwidthThreshold = function() { return imageTweakBandwidthThreshold; };
209207
this.getImageCountOk = function() { return imageCountOk; };
210208
this.getImageCountMax = function() { return imageCountMax; };
211209
this.getImageModeEnum = function() { return imageModeEnum; };

Myrtille.Web/js/myrtille.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,8 @@ function changeImageQuality(quality)
613613
// display settings are applied by the network.js "tweakDisplay" function
614614
network.setOriginalImageEncoding(config.getImageEncodingEnum().JPEG);
615615
network.setOriginalImageQuality(quality <= 90 ? quality : 90);
616+
network.tweakDisplay(true);
617+
network.setImageTweak(false);
616618
}
617619
catch (exc)
618620
{

0 commit comments

Comments
 (0)