Skip to content

Commit

Permalink
Merge pull request #6 from elijahr2411/master
Browse files Browse the repository at this point in the history
Port to ClientWebSocket
  • Loading branch information
yellows111 authored Apr 8, 2024
2 parents a6a73b4 + 3ad06a2 commit ae96acc
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 259 deletions.
24 changes: 1 addition & 23 deletions .github/workflows/csc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,7 @@ jobs:

- name: Install MSBuild to PATH
uses: microsoft/[email protected]

- name: Download WebSocket-Sharp 1.0.3rc11
# Fine, I'll play dirty.
uses: carlosperate/[email protected]
with:
file-url: 'https://www.nuget.org/api/v2/package/WebSocketSharp/1.0.3-rc11'
file-name: websocketsharp.nupkg
location: './tmp'

- name: Extract WebSocket-Sharp with 7z
run: |
cd tmp
7z x websocketsharp.nupkg
copy .\lib\websocket-sharp.dll D:\a\collab-vm-csharp-client\collab-vm-csharp-client\
- name: Copy WebSocket-Sharp to build folders
run: |
cd D:\a\collab-vm-csharp-client\collab-vm-csharp-client\
mkdir ./bin/Debug
mkdir ./bin/Release
copy websocket-sharp.dll bin\Release
copy websocket-sharp.dll bin\Debug

- name: Use MSBuild to compile debug version
run: msbuild

Expand Down
385 changes: 184 additions & 201 deletions ConnectDialog.Designer.cs

Large diffs are not rendered by default.

10 changes: 0 additions & 10 deletions ConnectDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,55 +19,46 @@ private void Cb_SelectedIndexChanged(object sender, EventArgs e)
textBox.Text = "computernewb.com:443/collab-vm/vm1";
textBox2.Text = "vm1";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
case 2:
textBox.Text = "computernewb.com:443/collab-vm/vm2";
textBox2.Text = "vm2";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
case 3:
textBox.Text = "computernewb.com:443/collab-vm/vm3";
textBox2.Text = "vm3";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
case 4:
textBox.Text = "computernewb.com:443/collab-vm/vm4";
textBox2.Text = "vm4";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
case 5:
textBox.Text = "computernewb.com:443/collab-vm/vm5";
textBox2.Text = "vm5";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
case 6:
textBox.Text = "computernewb.com:443/collab-vm/vm6";
textBox2.Text = "vm6";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
case 7:
textBox.Text = "computernewb.com:443/collab-vm/vm7";
textBox2.Text = "vm7";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
case 8:
textBox.Text = "computernewb.com:443/collab-vm/vm8";
textBox2.Text = "vm8";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
case 9:
textBox.Text = "computernewb.com:443/collab-vm/vm0";
textBox2.Text = "vm0b0t";
checksecure.Checked = true;
checkcompression.Checked = true;
break;
}
}
Expand All @@ -78,7 +69,6 @@ private void OkButton_Click(object sender, EventArgs e)
Globals.vmname = textBox2.Text;
Globals.vmusername = textBox3.Text;
Globals.isSecure = checksecure.Checked;
Globals.isCompressed = checkcompression.Checked;
Hide();
new Form1().Show();
}
Expand Down
40 changes: 21 additions & 19 deletions Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Windows.Forms;
using System.IO;
using System.Timers;
using WebSocketSharp;
using Timer = System.Timers.Timer;
using System.Net;
using Newtonsoft.Json;
Expand Down Expand Up @@ -109,19 +108,22 @@ private void Form1_Load(object sender, EventArgs e)
g = Graphics.FromImage(pictureBox1.Image);
Text = "CollabVM .NET Client: " + Globals.vmip + "#" + Globals.vmname;
string protoPrefix = Globals.isSecure ? "s" : "";
socket = new WebSocket("ws"+protoPrefix+"://" + Globals.vmip, "guacamole") {Origin = "http"+protoPrefix+"://" + Globals.vmip.Split(':')[0]};
socket = new WebSocket("ws" + protoPrefix + "://" + Globals.vmip, "guacamole");
socket.Headers.Add("Origin", "http" + protoPrefix + "://" + Globals.vmip.Split(':')[0]);
if (Globals.isSecure){
socket.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
//socket.SslConfiguration.EnabledSslProtocols = (System.Security.Authentication.SslProtocols)0x00003000;
}
socket.OnClose += Socket_OnClose;
socket.OnOpen += Socket_OnOpen;
socket.OnMessage += Socket_OnMessage;
if (Globals.isCompressed){
socket.OnTextMessage += Socket_OnMessage;
// ClientWebSocket does not support deflate unfortunately.
// However i fail to see that as a loss since it's considered a security vulnerability
/*if (Globals.isCompressed){
socket.Compression = CompressionMethod.Deflate;
} else {
socket.Compression = CompressionMethod.None;
}
}*/
//pictureBox1.Image = Properties.Resources.Loading;
//pictureBox1.Refresh();
socket.Connect();
Expand Down Expand Up @@ -218,9 +220,9 @@ private void LogChat(string text)
richTextBox1.Invoke((MethodInvoker) delegate { richTextBox1.AppendText(text + Environment.NewLine); });
}

private void Socket_OnMessage(object sender, MessageEventArgs e)
private void Socket_OnMessage(object sender, string msg)
{
string[] args = DecodeGuac(e.Data);
string[] args = DecodeGuac(msg);
switch (args[0])
{
case "chat":
Expand Down Expand Up @@ -289,7 +291,7 @@ private void Socket_OnMessage(object sender, MessageEventArgs e)
case "nop":
{
Send("nop");
socket.Ping();
//socket.Ping();
break;
}
case "png":
Expand Down Expand Up @@ -672,15 +674,9 @@ private void Socket_OnOpen(object sender, EventArgs e)
t.Enabled = true;
}

private void Socket_OnClose(object sender, CloseEventArgs e)
private void Socket_OnClose(object sender, WebSocketCloseEventArgs e)
{
if (e.Reason == "An exception has occurred while connecting.")
{
MessageBox.Show("Failed to connect to the VM.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
Close();
Application.Exit();
}
else if (e.Reason == "An error has occurred while connecting.")
if (e.Reason == WebSocketCloseReason.Error)
{
MessageBox.Show("Failed to connect to the VM.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
Close();
Expand All @@ -703,7 +699,7 @@ private void Socket_OnClose(object sender, CloseEventArgs e)
else
{
LogChat(">TIP: Try '!reconnect' or '!autoreconnect yes'.");
if (!string.IsNullOrEmpty(e.Reason)) MessageBox.Show(e.Reason, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (!string.IsNullOrEmpty(e.Message)) MessageBox.Show(e.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
Expand Down Expand Up @@ -795,7 +791,13 @@ private void TextBox1_KeyDown(object sender, KeyEventArgs e)
LogChat(">Reconnecting...");
socket.Connect();
break;
}
}
case "!disconnect":
{
users.Clear();
socket.Close();
break;
}
case "!ss":
{
Invoke((MethodInvoker) delegate { pictureBox1.Refresh(); });
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ yes the key handler is awful
i know many of these problems

originally by someone who doesn't want his name shared but has gladly agreed for me to repost this

oh yeah you'll probably need a copy of [websocket-sharp](https://github.com/sta/websocket-sharp)
166 changes: 166 additions & 0 deletions WebSocket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CollabClient
{
public class WebSocket
{
// Fields
private ClientWebSocket socket;
private Uri uri;
private string[] protocols;
private bool closeHandled = false;

// Properties

public string Uri => uri.ToString();
public string[] Protocols => protocols.ToArray();
public Dictionary<string,string> Headers { get; set; }

// Events
public event EventHandler<WebSocketCloseEventArgs> OnClose;
public event EventHandler OnOpen;
public event EventHandler<string> OnTextMessage;
public event EventHandler<byte[]> OnBinaryMessage;

// Methods
public WebSocket(string url, params string[] protocols)
{
this.uri = new Uri(url);
this.protocols = protocols;
this.Headers = new Dictionary<string, string>();
// Register dummy handlers on events to prevent NullReferenceException
OnClose += (s, e) => { };
OnOpen += (s, e) => { };
OnTextMessage += (s, e) => { };
OnBinaryMessage += (s, e) => { };

}

public void Close(WebSocketCloseStatus status = WebSocketCloseStatus.NormalClosure, string reason = "")
{
if (this.socket.State != WebSocketState.Open) return;
closeHandled = true;
this.socket.CloseAsync(status, reason, CancellationToken.None).GetAwaiter().GetResult();
this.socket.Dispose();
this.socket = null;
OnClose.Invoke(this, new WebSocketCloseEventArgs
{
Code = status,
Reason = WebSocketCloseReason.CloseByClient,
Message = reason,
});
closeHandled = false;
}

public async Task Connect()
{
if (this.socket != null && this.socket.State == WebSocketState.Open) Close();
this.socket = new ClientWebSocket();
foreach (string protocol in this.protocols) this.socket.Options.AddSubProtocol(protocol);
foreach (KeyValuePair<string, string> header in Headers) this.socket.Options.SetRequestHeader(header.Key, header.Value);
await this.socket.ConnectAsync(this.uri, CancellationToken.None);
messageLoop();
this.OnOpen.Invoke(this, new EventArgs());

}

public bool Send(string msg)
{
return Send(Encoding.UTF8.GetBytes(msg), WebSocketMessageType.Text);
}

public bool Send(byte[] msg, WebSocketMessageType type = WebSocketMessageType.Binary)
{
if (this.socket == null || this.socket.State != WebSocketState.Open) return false;
this.socket.SendAsync(new ArraySegment<byte>(msg), type, true, CancellationToken.None).GetAwaiter().GetResult();
return true;
}

private async void messageLoop()
{
ArraySegment<byte> recieveBuffer = new ArraySegment<byte>(new byte[8192]);
do
{
using (var ms = new MemoryStream())
{
WebSocketReceiveResult res;
do
{
try
{
res = await socket.ReceiveAsync(recieveBuffer, CancellationToken.None);
}
catch (WebSocketException ex)
{
if (this.socket == null || closeHandled) return;
this.socket.Dispose();
this.socket = null;
this.OnClose.Invoke(this, new WebSocketCloseEventArgs
{
Code = null,
Reason = WebSocketCloseReason.Error,
Message = ex.Message,
});
return;
}
if (res.MessageType == WebSocketMessageType.Close)
{
if (this.socket == null || closeHandled) return;
this.socket.Dispose();
this.socket = null;
this.OnClose.Invoke(this, new WebSocketCloseEventArgs
{
Code = res.CloseStatus,
Reason = WebSocketCloseReason.CloseByServer,
Message = res.CloseStatusDescription
});
return;
}
await ms.WriteAsync(recieveBuffer.Array, 0, res.Count);
} while (!res.EndOfMessage);
byte[] msgbytes = ms.ToArray();
if (res.MessageType == WebSocketMessageType.Binary) this.OnBinaryMessage.Invoke(this, msgbytes);
else if (res.MessageType == WebSocketMessageType.Text) this.OnTextMessage.Invoke(this, Encoding.UTF8.GetString(msgbytes));
}
} while (socket.State == WebSocketState.Open);
if (this.socket == null || closeHandled) return;
// this shouldn't happen I don't think but we'll handle it anyway
this.socket.Dispose();
this.socket = null;
this.OnClose.Invoke(this, new WebSocketCloseEventArgs
{
Code = null,
Reason = WebSocketCloseReason.CloseByServer,
Message = ""
});
return;
}
}

public class WebSocketCloseEventArgs
{
/// <summary>
/// Closure code provided by the server, or null if the connection closed uncleanly
/// </summary>
public WebSocketCloseStatus? Code { get; set; }
/// <summary>
/// The reason for the closure
/// </summary>
public WebSocketCloseReason Reason { get; set; }
public string Message { get; set; }
}

public enum WebSocketCloseReason
{
CloseByClient,
CloseByServer,
Error
}
}
4 changes: 1 addition & 3 deletions collabvm-client-dotnet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="websocket-sharp, Version=1.0.2.59611, Culture=neutral, PublicKeyToken=5660b08a1845a91e, processorArchitecture=MSIL">
<HintPath>packages\WebSocketSharp.1.0.3-rc11\lib\websocket-sharp.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="APIPayloads.cs" />
Expand Down Expand Up @@ -127,6 +124,7 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="WebSocket.cs" />
<Compile Include="X11KeyEnum.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 0 additions & 1 deletion packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net471" />
<package id="WebSocketSharp" version="1.0.3-rc11" targetFramework="net461" />
</packages>

0 comments on commit ae96acc

Please sign in to comment.