From 118e0015d5eb51bafc388e7e9e0eb55ceb5cdc28 Mon Sep 17 00:00:00 2001 From: sta Date: Tue, 31 Jul 2012 10:36:52 +0900 Subject: [PATCH] Supports RFC 6455 --- {wsclient1 => Example}/AssemblyInfo.cs | 4 +- Example/Program.cs | 127 ++ {wsclient => Example1}/AssemblyInfo.cs | 4 +- Example1/AudioStreamer.cs | 318 +++++ .../Example1.csproj | 21 +- Example1/Program.cs | 35 + README.md | 167 ++- websocket-sharp.sln | 20 +- websocket-sharp.userprefs | 8 +- websocket-sharp/AssemblyInfo.cs | 2 +- websocket-sharp/ByteOrder.cs | 38 + websocket-sharp/CloseEventArgs.cs | 87 ++ websocket-sharp/Ext.cs | 338 ++++-- websocket-sharp/Frame/CloseStatusCode.cs | 59 + websocket-sharp/Frame/Fin.cs | 38 + websocket-sharp/Frame/Mask.cs | 38 + websocket-sharp/Frame/Opcode.cs | 43 + websocket-sharp/Frame/PayloadData.cs | 184 +++ websocket-sharp/Frame/Rsv.cs | 38 + websocket-sharp/Frame/WsFrame.cs | 461 ++++++++ websocket-sharp/MessageEventArgs.cs | 87 ++ websocket-sharp/{ => Stream}/IWsStream.cs | 17 +- websocket-sharp/{ => Stream}/WsStream.cs | 52 +- websocket-sharp/WebSocket.cs | 1038 ++++++++++++----- .../WsReceivedTooBigMessageException.cs | 54 + websocket-sharp/WsState.cs | 2 +- websocket-sharp/bin/Debug/websocket-sharp.dll | Bin 15872 -> 0 bytes .../bin/Debug/websocket-sharp.dll.mdb | Bin 4763 -> 0 bytes .../bin/Debug_Ubuntu/websocket-sharp.dll | Bin 15872 -> 35328 bytes .../bin/Debug_Ubuntu/websocket-sharp.dll.mdb | Bin 4763 -> 14194 bytes .../bin/Release/websocket-sharp.dll | Bin 14336 -> 34304 bytes .../bin/Release_Ubuntu/websocket-sharp.dll | Bin 14336 -> 34304 bytes websocket-sharp/websocket-sharp.csproj | 23 +- websocket-sharp/websocket-sharp.pidb | Bin 12401 -> 33247 bytes wsclient/bin/Debug/websocket-sharp.dll | Bin 15872 -> 0 bytes wsclient/bin/Debug/websocket-sharp.dll.mdb | Bin 4763 -> 0 bytes wsclient/bin/Debug/wsclient.exe | Bin 4608 -> 0 bytes wsclient/bin/Debug/wsclient.exe.mdb | Bin 978 -> 0 bytes wsclient/bin/Debug_Ubuntu/websocket-sharp.dll | Bin 15872 -> 0 bytes .../bin/Debug_Ubuntu/websocket-sharp.dll.mdb | Bin 4763 -> 0 bytes wsclient/bin/Debug_Ubuntu/wsclient.exe | Bin 5120 -> 0 bytes wsclient/bin/Debug_Ubuntu/wsclient.exe.mdb | Bin 997 -> 0 bytes wsclient/bin/Release/websocket-sharp.dll | Bin 14336 -> 0 bytes wsclient/bin/Release/wsclient.exe | Bin 4608 -> 0 bytes .../bin/Release_Ubuntu/websocket-sharp.dll | Bin 14336 -> 0 bytes wsclient/bin/Release_Ubuntu/wsclient.exe | Bin 5120 -> 0 bytes wsclient/wsclient.cs | 67 -- wsclient/wsclient.pidb | Bin 3211 -> 0 bytes wsclient1/bin/Debug/websocket-sharp.dll | Bin 15872 -> 0 bytes wsclient1/bin/Debug/websocket-sharp.dll.mdb | Bin 4767 -> 0 bytes wsclient1/bin/Debug/wsclient1.exe | Bin 4608 -> 0 bytes wsclient1/bin/Debug/wsclient1.exe.mdb | Bin 1067 -> 0 bytes .../bin/Debug_Ubuntu/websocket-sharp.dll | Bin 15872 -> 0 bytes .../bin/Debug_Ubuntu/websocket-sharp.dll.mdb | Bin 4767 -> 0 bytes wsclient1/bin/Debug_Ubuntu/wsclient1.exe | Bin 5120 -> 0 bytes wsclient1/bin/Debug_Ubuntu/wsclient1.exe.mdb | Bin 1086 -> 0 bytes wsclient1/bin/Release/websocket-sharp.dll | Bin 14336 -> 0 bytes wsclient1/bin/Release/wsclient1.exe | Bin 4608 -> 0 bytes .../bin/Release_Ubuntu/websocket-sharp.dll | Bin 14336 -> 0 bytes wsclient1/bin/Release_Ubuntu/wsclient1.exe | Bin 5120 -> 0 bytes wsclient1/wsclient1.cs | 65 -- wsclient1/wsclient1.csproj | 68 -- wsclient1/wsclient1.pidb | Bin 3216 -> 0 bytes 63 files changed, 2857 insertions(+), 646 deletions(-) rename {wsclient1 => Example}/AssemblyInfo.cs (92%) create mode 100644 Example/Program.cs rename {wsclient => Example1}/AssemblyInfo.cs (92%) create mode 100644 Example1/AudioStreamer.cs rename wsclient/wsclient.csproj => Example1/Example1.csproj (83%) create mode 100644 Example1/Program.cs create mode 100644 websocket-sharp/ByteOrder.cs create mode 100644 websocket-sharp/CloseEventArgs.cs create mode 100644 websocket-sharp/Frame/CloseStatusCode.cs create mode 100644 websocket-sharp/Frame/Fin.cs create mode 100644 websocket-sharp/Frame/Mask.cs create mode 100644 websocket-sharp/Frame/Opcode.cs create mode 100644 websocket-sharp/Frame/PayloadData.cs create mode 100644 websocket-sharp/Frame/Rsv.cs create mode 100644 websocket-sharp/Frame/WsFrame.cs create mode 100644 websocket-sharp/MessageEventArgs.cs rename websocket-sharp/{ => Stream}/IWsStream.cs (77%) rename websocket-sharp/{ => Stream}/WsStream.cs (62%) create mode 100644 websocket-sharp/WsReceivedTooBigMessageException.cs delete mode 100755 websocket-sharp/bin/Debug/websocket-sharp.dll delete mode 100644 websocket-sharp/bin/Debug/websocket-sharp.dll.mdb delete mode 100755 wsclient/bin/Debug/websocket-sharp.dll delete mode 100644 wsclient/bin/Debug/websocket-sharp.dll.mdb delete mode 100755 wsclient/bin/Debug/wsclient.exe delete mode 100644 wsclient/bin/Debug/wsclient.exe.mdb delete mode 100755 wsclient/bin/Debug_Ubuntu/websocket-sharp.dll delete mode 100644 wsclient/bin/Debug_Ubuntu/websocket-sharp.dll.mdb delete mode 100755 wsclient/bin/Debug_Ubuntu/wsclient.exe delete mode 100644 wsclient/bin/Debug_Ubuntu/wsclient.exe.mdb delete mode 100755 wsclient/bin/Release/websocket-sharp.dll delete mode 100755 wsclient/bin/Release/wsclient.exe delete mode 100755 wsclient/bin/Release_Ubuntu/websocket-sharp.dll delete mode 100755 wsclient/bin/Release_Ubuntu/wsclient.exe delete mode 100644 wsclient/wsclient.cs delete mode 100644 wsclient/wsclient.pidb delete mode 100755 wsclient1/bin/Debug/websocket-sharp.dll delete mode 100644 wsclient1/bin/Debug/websocket-sharp.dll.mdb delete mode 100755 wsclient1/bin/Debug/wsclient1.exe delete mode 100644 wsclient1/bin/Debug/wsclient1.exe.mdb delete mode 100755 wsclient1/bin/Debug_Ubuntu/websocket-sharp.dll delete mode 100644 wsclient1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb delete mode 100755 wsclient1/bin/Debug_Ubuntu/wsclient1.exe delete mode 100644 wsclient1/bin/Debug_Ubuntu/wsclient1.exe.mdb delete mode 100755 wsclient1/bin/Release/websocket-sharp.dll delete mode 100755 wsclient1/bin/Release/wsclient1.exe delete mode 100755 wsclient1/bin/Release_Ubuntu/websocket-sharp.dll delete mode 100755 wsclient1/bin/Release_Ubuntu/wsclient1.exe delete mode 100644 wsclient1/wsclient1.cs delete mode 100644 wsclient1/wsclient1.csproj delete mode 100644 wsclient1/wsclient1.pidb diff --git a/wsclient1/AssemblyInfo.cs b/Example/AssemblyInfo.cs similarity index 92% rename from wsclient1/AssemblyInfo.cs rename to Example/AssemblyInfo.cs index 5d7a651f..d4e247fd 100644 --- a/wsclient1/AssemblyInfo.cs +++ b/Example/AssemblyInfo.cs @@ -4,12 +4,12 @@ using System.Runtime.CompilerServices; // Information about this assembly is defined by the following attributes. // Change them to the values specific to your project. -[assembly: AssemblyTitle("wsclient1")] +[assembly: AssemblyTitle("Example")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCopyright("sta")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/Example/Program.cs b/Example/Program.cs new file mode 100644 index 00000000..74c26cd7 --- /dev/null +++ b/Example/Program.cs @@ -0,0 +1,127 @@ +#if NOTIFY +using Notifications; +#endif +using System; +using System.Collections; +using System.Threading; +using WebSocketSharp; + +namespace Example +{ + public struct NfMessage + { + public string Summary; + public string Body; + public string Icon; + } + + public class ThreadState + { + public bool Enabled { get; set; } + public AutoResetEvent Notification { get; private set; } + + public ThreadState() + { + Enabled = true; + Notification = new AutoResetEvent(false); + } + } + + public class Program + { + private static Queue _msgQ = Queue.Synchronized(new Queue()); + + private static void enNfMessage(string summary, string body, string icon) + { + var msg = new NfMessage + { + Summary = summary, + Body = body, + Icon = icon + }; + + _msgQ.Enqueue(msg); + } + + public static void Main(string[] args) + { + ThreadState ts = new ThreadState(); + + WaitCallback notifyMsg = state => + { + while (ts.Enabled) + { + Thread.Sleep(500); + + if (_msgQ.Count > 0) + { + NfMessage msg = (NfMessage)_msgQ.Dequeue(); + #if NOTIFY + Notification nf = new Notification(msg.Summary, + msg.Body, + msg.Icon); + nf.AddHint("append", "allowed"); + nf.Show(); + #else + Console.WriteLine("{0}: {1}", msg.Summary, msg.Body); + #endif + } + } + + ts.Notification.Set(); + }; + + ThreadPool.QueueUserWorkItem(notifyMsg); + + using (WebSocket ws = new WebSocket("ws://echo.websocket.org", "echo")) + //using (WebSocket ws = new WebSocket("wss://echo.websocket.org", "echo")) + { + ws.OnOpen += (sender, e) => + { + ws.Send("Hi, all!"); + }; + + ws.OnMessage += (sender, e) => + { + enNfMessage("[WebSocket] Message", e.Data, "notification-message-im"); + }; + + ws.OnError += (sender, e) => + { + enNfMessage("[WebSocket] Error", e.Data, "notification-message-im"); + }; + + ws.OnClose += (sender, e) => + { + enNfMessage( + String.Format("[WebSocket] Close({0}:{1})", (ushort)e.Code, e.Code), + e.Reason, + "notification-message-im"); + }; + + ws.Connect(); + + Thread.Sleep(500); + Console.WriteLine("\nType \"exit\" to exit.\n"); + + string data; + while (true) + { + Thread.Sleep(500); + + Console.Write("> "); + data = Console.ReadLine(); + if (data == "exit") + { + break; + } + + ws.Send(data); + } + } + + ts.Enabled = false; + ts.Notification.WaitOne(); + } + } +} diff --git a/wsclient/AssemblyInfo.cs b/Example1/AssemblyInfo.cs similarity index 92% rename from wsclient/AssemblyInfo.cs rename to Example1/AssemblyInfo.cs index ade05a55..f92db6a2 100644 --- a/wsclient/AssemblyInfo.cs +++ b/Example1/AssemblyInfo.cs @@ -4,12 +4,12 @@ using System.Runtime.CompilerServices; // Information about this assembly is defined by the following attributes. // Change them to the values specific to your project. -[assembly: AssemblyTitle("wsclient")] +[assembly: AssemblyTitle("Example1")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] +[assembly: AssemblyCopyright("sta")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/Example1/AudioStreamer.cs b/Example1/AudioStreamer.cs new file mode 100644 index 00000000..44dd7f19 --- /dev/null +++ b/Example1/AudioStreamer.cs @@ -0,0 +1,318 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +#if NOTIFY +using Notifications; +#endif +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using WebSocketSharp; +using WebSocketSharp.Frame; + +namespace Example +{ + public struct NfMessage + { + public string Summary; + public string Body; + public string Icon; + } + + public class AudioMessage + { + public uint user_id; + public byte ch_num; + public uint buffer_length; + public float[,] buffer_array; + } + + public class TextMessage + { + public uint? user_id; + public string name; + public string type; + public string message; + } + + public class ThreadState + { + public bool Enabled { get; set; } + public AutoResetEvent Notification { get; private set; } + + public ThreadState() + { + Enabled = true; + Notification = new AutoResetEvent(false); + } + } + + public class AudioStreamer : IDisposable + { + private Dictionary _audioBox; + private Queue _msgQ; + private string _name; + private WaitCallback _notifyMsg; + private ThreadState _notifyMsgState; + private TimerCallback _sendHeartbeat; + private Timer _heartbeatTimer; + private uint? _user_id; + private WebSocket _ws; + + public AudioStreamer(string url) + { + _ws = new WebSocket(url); + _msgQ = Queue.Synchronized(new Queue()); + _audioBox = new Dictionary(); + _user_id = null; + + configure(); + } + + private void configure() + { + _ws.OnOpen += (sender, e) => + { + var msg = createTextMessage("connection", String.Empty); + _ws.Send(msg); + }; + + _ws.OnMessage += (sender, e) => + { + switch (e.Type) + { + case Opcode.TEXT: + var msg = parseTextMessage(e.Data); + _msgQ.Enqueue(msg); + break; + case Opcode.BINARY: + var audioMsg = parseAudioMessage(e.RawData); + if (audioMsg.user_id == _user_id) goto default; + if (_audioBox.ContainsKey(audioMsg.user_id)) + { + _audioBox[audioMsg.user_id].Enqueue(audioMsg.buffer_array); + } + else + { + var q = Queue.Synchronized(new Queue()); + q.Enqueue(audioMsg.buffer_array); + _audioBox.Add(audioMsg.user_id, q); + } + break; + default: + break; + } + }; + + _ws.OnError += (sender, e) => + { + enNfMessage("[AudioStreamer] error", "WS Error: " + e.Data, "notification-message-im"); + }; + + _ws.OnClose += (sender, e) => + { + enNfMessage + ( + "[AudioStreamer] disconnect", + String.Format("WS Close({0}:{1}): {2}", (ushort)e.Code, e.Code, e.Reason), + "notification-message-im" + ); + }; + + _notifyMsgState = new ThreadState(); + _notifyMsg = (state) => + { + while (_notifyMsgState.Enabled) + { + Thread.Sleep(500); + + if (_msgQ.Count > 0) + { + NfMessage msg = (NfMessage)_msgQ.Dequeue(); + #if NOTIFY + Notification nf = new Notification(msg.Summary, + msg.Body, + msg.Icon); + nf.AddHint("append", "allowed"); + nf.Show(); + #else + Console.WriteLine("{0}: {1}", msg.Summary, msg.Body); + #endif + } + } + + _notifyMsgState.Notification.Set(); + }; + + _sendHeartbeat = (state) => + { + var msg = createTextMessage("heartbeat", String.Empty); + _ws.Send(msg); + }; + } + + private byte[] createAudioMessage(float[,] buffer_array) + { + List msg = new List(); + + uint user_id = (uint)_user_id; + int ch_num = buffer_array.GetLength(0); + int buffer_length = buffer_array.GetLength(1); + + msg.AddRange(user_id.ToBytes(ByteOrder.BIG)); + msg.Add((byte)ch_num); + msg.AddRange(((uint)buffer_length).ToBytes(ByteOrder.BIG)); + + ch_num.Times(i => + { + buffer_length.Times(j => + { + msg.AddRange(buffer_array[i, j].ToBytes(ByteOrder.BIG)); + }); + }); + + return msg.ToArray(); + } + + private string createTextMessage(string type, string message) + { + var msg = new TextMessage + { + user_id = _user_id, + name = _name, + type = type, + message = message + }; + + return JsonConvert.SerializeObject(msg); + } + + private AudioMessage parseAudioMessage(byte[] data) + { + uint user_id = data.SubArray(0, 4).To(ByteOrder.BIG); + byte ch_num = data.SubArray(4, 1)[0]; + uint buffer_length = data.SubArray(5, 4).To(ByteOrder.BIG); + float[,] buffer_array = new float[ch_num, buffer_length]; + + int offset = 9; + ch_num.Times(i => + { + buffer_length.Times(j => + { + buffer_array[i, j] = data.SubArray(offset, 4).To(ByteOrder.BIG); + offset += 4; + }); + }); + + return new AudioMessage + { + user_id = user_id, + ch_num = ch_num, + buffer_length = buffer_length, + buffer_array = buffer_array + }; + } + + private NfMessage parseTextMessage(string data) + { + JObject msg = JObject.Parse(data); + uint user_id = (uint)msg["user_id"]; + string name = (string)msg["name"]; + string type = (string)msg["type"]; + + string message; + switch (type) + { + case "connection": + JArray users = (JArray)msg["message"]; + StringBuilder sb = new StringBuilder("Now keeping connection\n"); + foreach (JToken user in users) + { + sb.AppendFormat("user_id: {0} name: {1}\n", (uint)user["user_id"], (string)user["name"]); + } + message = sb.ToString().TrimEnd('\n'); + break; + case "connected": + _user_id = user_id; + message = String.Format("user_id: {0} name: {1}", user_id, name); + break; + case "message": + message = String.Format("{0}: {1}", name, (string)msg["message"]); + break; + case "start_music": + message = String.Format("{0}: Started playing music!", name); + break; + default: + message = "Received unknown type message: " + type; + break; + } + + return new NfMessage + { + Summary = String.Format("[AudioStreamer] {0}", type), + Body = message, + Icon = "notification-message-im" + }; + } + + private void enNfMessage(string summary, string body, string icon) + { + var msg = new NfMessage + { + Summary = summary, + Body = body, + Icon = icon + }; + + _msgQ.Enqueue(msg); + } + + public void Connect() + { + string name; + do + { + Console.Write("Your name > "); + name = Console.ReadLine(); + } + while (name == String.Empty); + + _name = name; + + _ws.Connect(); + + ThreadPool.QueueUserWorkItem(_notifyMsg); + _heartbeatTimer = new Timer(_sendHeartbeat, null, 30 * 1000, 30 * 1000); + } + + public void Disconnect() + { + var wait = new AutoResetEvent(false); + _heartbeatTimer.Dispose(wait); + wait.WaitOne(); + + _ws.Close(); + + _notifyMsgState.Enabled = false; + _notifyMsgState.Notification.WaitOne(); + } + + public void Dispose() + { + Disconnect(); + } + + public void Write(string data) + { + var msg = createTextMessage("message", data); + _ws.Send(msg); + } + + public void Write(FileInfo file) + { + throw new NotImplementedException(); + } + } +} diff --git a/wsclient/wsclient.csproj b/Example1/Example1.csproj similarity index 83% rename from wsclient/wsclient.csproj rename to Example1/Example1.csproj index 313d403f..95af031f 100644 --- a/wsclient/wsclient.csproj +++ b/Example1/Example1.csproj @@ -5,10 +5,10 @@ AnyCPU 9.0.21022 2.0 - {52805AEC-EFB1-4F42-BB8E-3ED4E692C568} + {390E2568-57B7-4D17-91E5-C29336368CCF} Exe - WsClient - wsclient + Example + example1 v3.5 @@ -16,7 +16,7 @@ full false bin\Debug - DEBUG + DEBUG; prompt 4 true @@ -34,7 +34,7 @@ full false bin\Debug_Ubuntu - DEBUG,NOTIFY + DEBUG;NOTIFY prompt 4 true @@ -43,26 +43,31 @@ none false bin\Release_Ubuntu - NOTIFY prompt 4 true + NOTIFY + False notify-sharp + + False + - + + + {B357BAC7-529E-4D81-A0D2-71041B19C8DE} websocket-sharp - \ No newline at end of file diff --git a/Example1/Program.cs b/Example1/Program.cs new file mode 100644 index 00000000..2e33eee3 --- /dev/null +++ b/Example1/Program.cs @@ -0,0 +1,35 @@ +using System; +using System.Threading; + +namespace Example +{ + public class Program + { + public static void Main(string[] args) + { + //using (AudioStreamer streamer = new AudioStreamer("ws://localhost:3000/socket")) + using (AudioStreamer streamer = new AudioStreamer("ws://agektmr.node-ninja.com:3000/socket")) + { + streamer.Connect(); + + Thread.Sleep(500); + Console.WriteLine("\nType \"exit\" to exit.\n"); + + string data; + while (true) + { + Thread.Sleep(500); + + Console.Write("> "); + data = Console.ReadLine(); + if (data == "exit") + { + break; + } + + streamer.Write(data); + } + } + } + } +} diff --git a/README.md b/README.md index 1fa7bab4..1f332f09 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,171 @@ # websocket-sharp # -A C# implementation of a WebSocket protocol client. +**websocket-sharp** is a C# implementation of a WebSocket protocol client. ## Usage ## -Please refer to wsclient/wsclient.cs. +### Step 1 ### +Required namespaces. + + using WebSocketSharp; + using WebSocketSharp.Frame; + +In `WebSocketSharp` namespace `WebSocket` class exists, in `WebSocketSharp.Frame` namespace WebSocket data frame resources (e.g. `WsFrame` class) exist. + +### Step 2 ### + +Creating instance of `WebSocket` class. + + using (WebSocket ws = new WebSocket("ws://example.com")) + { + ... + } + +So `WebSocket` class inherits `IDisposable` interface, you can use `using` statement. + +### Step 3 ### + +Setting of `WebSocket` event handlers. + +#### WebSocket.OnOpen event #### + +`WebSocket.OnOpen` event is emitted immediately after WebSocket connection has been established. + + ws.OnOpen += (sender, e) => + { + ... + }; + +So `e` has come across as `EventArgs.Empty`, there is no operation on `e`. + +#### WebSocket.OnMessage event #### + +`WebSocket.OnMessage` event is emitted each time WebSocket data frame is received. + + ws.OnMessage += (sender, e) => + { + ... + }; + +So **type** of received WebSocket data frame is stored in `e.Type` (`WebSocketSharp.MessageEventArgs.Type`, its type is `WebSocketSharp.Frame.Opcode`), you check it out and you determine which item you should operate. + + switch (e.Type) + { + case Opcode.TEXT: + ... + break; + case Opcode.BINARY: + ... + break; + default: + break; + } + +If `e.Type` is `Opcode.TEXT`, you operate `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, its type is `string`). + +if `e.Type` is `Opcode.BINARY`, you operate `e.RawData` (`WebSocketSharp.MessageEventArgs.RawData`, its type is `byte[]`). + +#### WebSocket.OnError event #### + +`WebSocket.OnError` event is emitted when some error is occurred. + + ws.OnError += (sender, e) => + { + ... + }; + +So error message is stored in `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, its type is `string`) , you operate it. + +#### WebSocket.OnClose event #### + +`WebSocket.OnClose` event is emitted when WebSocket connection is closed. + + ws.OnClose += (sender, e) => + { + ... + }; + +So close status code is stored in `e.Code` (`WebSocketSharp.CloseEventArgs.Code`, its type is `WebSocketSharp.Frame.CloseStatusCode`) and reason of close is stored in `e.Reason` (`WebSocketSharp.CloseEventArgs.Reason`, its type is `string`), you operate them. + +### Step 4 ### + +Connecting to server using WebSocket. + + ws.Connect(); + +### Step 5 ### + +Sending data. + + ws.Send(data); + +`WebSocket.Send` method is overloaded. + +data types are `string`, `byte[]` and `FileInfo` class. + +### Step 6 ### + +Closing WebSocket connection. + + ws.Close(code, reason); + +If you want to close WebSocket connection explicitly, you can use `Close` method. + +Type of `code` is `WebSocketSharp.Frame.CloseStatusCode`, type of `reason` is `string`. + +`WebSocket.Close` method is overloaded (In addition `Close()` and `Close(code)` exist). + +## Examples ## + +Examples of using **websocket-sharp**. + +### Example ### + +[Example] connects to the [Echo server] using the WebSocket. + +### Example1 ### + +[Example1] connects to the [Audio Data delivery server] using the WebSocket ([Example1] is only implemented a chat feature, still unfinished). + +[Example1] uses [Json.NET]. + +## Supported WebSocket Protocol ## + +**websocket-sharp** supports **[RFC 6455]**. + +- @**[branch: hybi-00]** supports older draft-ietf-hybi-thewebsocketprotocol-00 (**[hybi-00]**). +- @**[branch: draft75]** supports even more old draft-hixie-thewebsocketprotocol-75 (**[hixie-75]**). + +## Reference ## + +- **[The WebSocket Protocol]** +- **[The WebSocket API]** + +Thx for translating to japanese. + +- **[The WebSocket Protocol 日本語訳]** +- **[The WebSocket API 日本語訳]** + +## License ## + +Copyright © 2010 - 2012 sta.blockhead + +Licensed under the **[MIT License]**. + + +[Audio Data delivery server]: http://agektmr.node-ninja.com:3000/ +[branch: draft75]: https://github.com/sta/websocket-sharp/tree/draft75 +[branch: hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00 +[Echo server]: http://www.websocket.org/echo.html +[Example]: https://github.com/sta/websocket-sharp/tree/master/Example +[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1 +[hixie-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 +[hybi-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00 +[Json.NET]: http://james.newtonking.com/projects/json-net.aspx +[MIT License]: http://www.opensource.org/licenses/mit-license.php +[RFC 6455]: http://tools.ietf.org/html/rfc6455 +[The WebSocket API]: http://dev.w3.org/html5/websockets +[The WebSocket API 日本語訳]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html +[The WebSocket Protocol]: http://tools.ietf.org/html/rfc6455 +[The WebSocket Protocol 日本語訳]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html diff --git a/websocket-sharp.sln b/websocket-sharp.sln index 82aee85e..a7c94077 100644 --- a/websocket-sharp.sln +++ b/websocket-sharp.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "websocket-sharp", "websocket-sharp\websocket-sharp.csproj", "{B357BAC7-529E-4D81-A0D2-71041B19C8DE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wsclient", "wsclient\wsclient.csproj", "{52805AEC-EFB1-4F42-BB8E-3ED4E692C568}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example", "Example\Example.csproj", "{52805AEC-EFB1-4F42-BB8E-3ED4E692C568}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wsclient1", "wsclient1\wsclient1.csproj", "{B0B609B7-A81C-46B0-A9B8-82E9716D355B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example1", "Example1\Example1.csproj", "{390E2568-57B7-4D17-91E5-C29336368CCF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +15,14 @@ Global Release_Ubuntu|Any CPU = Release_Ubuntu|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {390E2568-57B7-4D17-91E5-C29336368CCF}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU + {390E2568-57B7-4D17-91E5-C29336368CCF}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU + {390E2568-57B7-4D17-91E5-C29336368CCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {390E2568-57B7-4D17-91E5-C29336368CCF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {390E2568-57B7-4D17-91E5-C29336368CCF}.Release_Ubuntu|Any CPU.ActiveCfg = Release_Ubuntu|Any CPU + {390E2568-57B7-4D17-91E5-C29336368CCF}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU + {390E2568-57B7-4D17-91E5-C29336368CCF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {390E2568-57B7-4D17-91E5-C29336368CCF}.Release|Any CPU.Build.0 = Release|Any CPU {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -23,14 +31,6 @@ Global {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release|Any CPU.ActiveCfg = Release|Any CPU {52805AEC-EFB1-4F42-BB8E-3ED4E692C568}.Release|Any CPU.Build.0 = Release|Any CPU - {B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU - {B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU - {B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Release_Ubuntu|Any CPU.ActiveCfg = Release_Ubuntu|Any CPU - {B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Release_Ubuntu|Any CPU.Build.0 = Release_Ubuntu|Any CPU - {B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0B609B7-A81C-46B0-A9B8-82E9716D355B}.Release|Any CPU.Build.0 = Release|Any CPU {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug_Ubuntu|Any CPU {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug_Ubuntu|Any CPU.Build.0 = Debug_Ubuntu|Any CPU {B357BAC7-529E-4D81-A0D2-71041B19C8DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU diff --git a/websocket-sharp.userprefs b/websocket-sharp.userprefs index 6c25aa51..e78c9e62 100644 --- a/websocket-sharp.userprefs +++ b/websocket-sharp.userprefs @@ -1,12 +1,12 @@  - - + + - + - + \ No newline at end of file diff --git a/websocket-sharp/AssemblyInfo.cs b/websocket-sharp/AssemblyInfo.cs index 89a8f31a..b32e6d63 100644 --- a/websocket-sharp/AssemblyInfo.cs +++ b/websocket-sharp/AssemblyInfo.cs @@ -17,7 +17,7 @@ using System.Runtime.CompilerServices; // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.0.0.*")] +[assembly: AssemblyVersion("1.0.1.*")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. diff --git a/websocket-sharp/ByteOrder.cs b/websocket-sharp/ByteOrder.cs new file mode 100644 index 00000000..a2959f9d --- /dev/null +++ b/websocket-sharp/ByteOrder.cs @@ -0,0 +1,38 @@ +#region MIT License +/** + * ByteOrder.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp +{ + public enum ByteOrder : byte + { + LITTLE = 0x0, + BIG = 0x1 + } +} diff --git a/websocket-sharp/CloseEventArgs.cs b/websocket-sharp/CloseEventArgs.cs new file mode 100644 index 00000000..a4ff419f --- /dev/null +++ b/websocket-sharp/CloseEventArgs.cs @@ -0,0 +1,87 @@ +#region MIT License +/** + * CloseEventArgs.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Text; +using WebSocketSharp.Frame; + +namespace WebSocketSharp +{ + public class CloseEventArgs : MessageEventArgs + { + private ushort _code; + private string _reason; + private bool _wasClean; + + public CloseStatusCode Code + { + get + { + return (CloseStatusCode)_code; + } + } + + public string Reason + { + get + { + return _reason; + } + } + + public bool WasClean + { + get + { + return _wasClean; + } + set + { + _wasClean = value; + } + } + + public CloseEventArgs(PayloadData data) + : base(Opcode.CLOSE, data) + { + _code = data.ToBytes().SubArray(0, 2).To(ByteOrder.BIG); + + if (data.Length > 2) + { + var buffer = data.ToBytes().SubArray(2, (int)(data.Length - 2)); + _reason = Encoding.UTF8.GetString(buffer); + } + else + { + _reason = String.Empty; + } + + _wasClean = false; + } + } +} diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index 07128ecf..00fa0677 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -4,7 +4,7 @@ * * The MIT License * - * Copyright (c) 2010 sta.blockhead + * Copyright (c) 2010-2012 sta.blockhead * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,19 +28,59 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Text; namespace WebSocketSharp { public static class Ext { - public static bool AreNotEqualDo( + public static bool EqualsAndSaveTo(this int value, char c, List dest) + { + byte b = (byte)value; + dest.Add(b); + return b == Convert.ToByte(c); + } + + public static string GetHeaderValue(this string src, string separater) + { + int i = src.IndexOf(separater); + return src.Substring(i + 1).Trim(); + } + + public static bool IsHostOrder(this ByteOrder order) + { + if (BitConverter.IsLittleEndian ^ (order == ByteOrder.LITTLE)) + {// true ^ false or false ^ true + return false; + } + else + {// true ^ true or false ^ false + return true; + } + } + + public static bool IsNullDo(this T value, Action act) + where T : class + { + if (value == null) + { + act(); + return true; + } + + return false; + } + + public static bool NotEqualsDo( this string expected, string actual, Func func, - out string ret) + out string ret, + bool ignoreCase) { - if (expected != actual) + if (String.Compare(expected, actual, ignoreCase) != 0) { ret = func(expected, actual); return true; @@ -50,106 +90,226 @@ namespace WebSocketSharp return false; } - public static bool EqualsWithSaveTo(this int asByte, char c, List dist) + public static byte[] ReadBytes(this TStream stream, ulong length, int bufferLength) + where TStream : System.IO.Stream { - byte b = (byte)asByte; - dist.Add(b); - return b == Convert.ToByte(c); - } + List readData = new List(); - public static uint GenerateKey(this Random rand, int space) - { - uint max = (uint)(0xffffffff / space); + ulong count = length / (ulong)bufferLength; + int remainder = (int)(length % (ulong)bufferLength); - int upper16 = (int)((max & 0xffff0000) >> 16); - int lower16 = (int)(max & 0x0000ffff); + byte[] buffer1 = new byte[bufferLength]; - return ((uint)rand.Next(upper16 + 1) << 16) + (uint)rand.Next(lower16 + 1); - } - - public static char GeneratePrintableASCIIwithoutSPandNum(this Random rand) - { - int ascii = rand.Next(2) == 0 ? rand.Next(33, 48) : rand.Next(58, 127); - return Convert.ToChar(ascii); - } - - public static string GenerateSecKey(this Random rand, out uint key) - { - int space = rand.Next(1, 13); - int ascii = rand.Next(1, 13); - - key = rand.GenerateKey(space); - - long mKey = key * space; - List secKey = new List(mKey.ToString().ToCharArray()); - - int i; - ascii.Times( () => + count.Times(() => { - i = rand.Next(secKey.Count + 1); - secKey.Insert(i, rand.GeneratePrintableASCIIwithoutSPandNum()); - } ); + stream.Read(buffer1, 0, bufferLength); + readData.AddRange(buffer1); + }); - space.Times( () => + if (remainder > 0) { - i = rand.Next(1, secKey.Count); - secKey.Insert(i, ' '); - } ); - - return new String(secKey.ToArray()); - } - - public static byte[] InitializeWithPrintableASCII(this byte[] bytes, Random rand) - { - for (int i = 0; i < bytes.Length; i++) - { - bytes[i] = (byte)rand.Next(32, 127); - } - - return bytes; - } - - public static bool IsValid(this string[] response, byte[] expectedCR, byte[] actualCR, out string message) - { - string expectedCRtoHexStr = BitConverter.ToString(expectedCR); - string actualCRtoHexStr = BitConverter.ToString(actualCR); - - Func> func = s => - { - return (e, a) => - { -#if DEBUG - Console.WriteLine("WS: Error @IsValid: Invalid {0} response.", s); - Console.WriteLine(" expected: {0}", e); - Console.WriteLine(" actual : {0}", a); -#endif - return String.Format("Invalid {0} response: {1}", s, a); - }; - }; - - Func func1 = func("handshake"); - Func func2 = func("challenge"); - - string msg; - if ("HTTP/1.1 101 WebSocket Protocol Handshake".AreNotEqualDo(response[0], func1, out msg) || - "Upgrade: WebSocket".AreNotEqualDo(response[1], func1, out msg) || - "Connection: Upgrade".AreNotEqualDo(response[2], func1, out msg) || - expectedCRtoHexStr.AreNotEqualDo(actualCRtoHexStr, func2, out msg)) - { - message = msg; - return false; + byte[] buffer2 = new byte[remainder]; + stream.Read(buffer2, 0, remainder); + readData.AddRange(buffer2); } - message = String.Empty; - return true; + return readData.ToArray(); } - public static void Times(this int n, Action act) + public static T[] SubArray(this T[] array, int startIndex, int length) { - for (int i = 0; i < n; i++) + if (startIndex == 0 && array.Length == length) + { + return array; + } + + T[] subArray = new T[length]; + Array.Copy(array, startIndex, subArray, 0, length); + return subArray; + } + + public static void Times(this T n, Action act) + where T : struct + { + if (typeof(T) != typeof(byte) && + typeof(T) != typeof(Int16) && + typeof(T) != typeof(Int32) && + typeof(T) != typeof(Int64) && + typeof(T) != typeof(UInt16) && + typeof(T) != typeof(UInt32) && + typeof(T) != typeof(UInt64)) + { + throw new NotSupportedException("Not supported Struct type: " + typeof(T).ToString()); + } + + ulong m = (ulong)(object)n; + + for (ulong i = 0; i < m; i++) { act(); } } + + public static void Times(this T n, Action act) + where T : struct + { + if (typeof(T) != typeof(byte) && + typeof(T) != typeof(Int16) && + typeof(T) != typeof(Int32) && + typeof(T) != typeof(Int64) && + typeof(T) != typeof(UInt16) && + typeof(T) != typeof(UInt32) && + typeof(T) != typeof(UInt64)) + { + throw new NotSupportedException("Not supported Struct type: " + typeof(T).ToString()); + } + + ulong m = (ulong)(object)n; + + for (ulong i = 0; i < m; i++) + { + act(i); + } + } + + public static T To(this byte[] src, ByteOrder srcOrder) + where T : struct + { + T dest; + byte[] buffer = src.ToHostOrder(srcOrder); + + if (typeof(T) == typeof(Boolean)) + { + dest = (T)(object)BitConverter.ToBoolean(buffer, 0); + } + else if (typeof(T) == typeof(Char)) + { + dest = (T)(object)BitConverter.ToChar(buffer, 0); + } + else if (typeof(T) == typeof(Double)) + { + dest = (T)(object)BitConverter.ToDouble(buffer, 0); + } + else if (typeof(T) == typeof(Int16)) + { + dest = (T)(object)BitConverter.ToInt16(buffer, 0); + } + else if (typeof(T) == typeof(Int32)) + { + dest = (T)(object)BitConverter.ToInt32(buffer, 0); + } + else if (typeof(T) == typeof(Int64)) + { + dest = (T)(object)BitConverter.ToInt64(buffer, 0); + } + else if (typeof(T) == typeof(Single)) + { + dest = (T)(object)BitConverter.ToSingle(buffer, 0); + } + else if (typeof(T) == typeof(UInt16)) + { + dest = (T)(object)BitConverter.ToUInt16(buffer, 0); + } + else if (typeof(T) == typeof(UInt32)) + { + dest = (T)(object)BitConverter.ToUInt32(buffer, 0); + } + else if (typeof(T) == typeof(UInt64)) + { + dest = (T)(object)BitConverter.ToUInt64(buffer, 0); + } + else + { + dest = default(T); + } + + return dest; + } + + public static byte[] ToBytes(this T value, ByteOrder order) + where T : struct + { + byte[] buffer; + + if (typeof(T) == typeof(Boolean)) + { + buffer = BitConverter.GetBytes((Boolean)(object)value); + } + else if (typeof(T) == typeof(Char)) + { + buffer = BitConverter.GetBytes((Char)(object)value); + } + else if (typeof(T) == typeof(Double)) + { + buffer = BitConverter.GetBytes((Double)(object)value); + } + else if (typeof(T) == typeof(Int16)) + { + buffer = BitConverter.GetBytes((Int16)(object)value); + } + else if (typeof(T) == typeof(Int32)) + { + buffer = BitConverter.GetBytes((Int32)(object)value); + } + else if (typeof(T) == typeof(Int64)) + { + buffer = BitConverter.GetBytes((Int64)(object)value); + } + else if (typeof(T) == typeof(Single)) + { + buffer = BitConverter.GetBytes((Single)(object)value); + } + else if (typeof(T) == typeof(UInt16)) + { + buffer = BitConverter.GetBytes((UInt16)(object)value); + } + else if (typeof(T) == typeof(UInt32)) + { + buffer = BitConverter.GetBytes((UInt32)(object)value); + } + else if (typeof(T) == typeof(UInt64)) + { + buffer = BitConverter.GetBytes((UInt64)(object)value); + } + else + { + buffer = new byte[]{}; + } + + return order.IsHostOrder() + ? buffer + : buffer.Reverse().ToArray(); + } + + public static byte[] ToHostOrder(this byte[] src, ByteOrder srcOrder) + { + byte[] buffer = new byte[src.Length]; + src.CopyTo(buffer, 0); + + return srcOrder.IsHostOrder() + ? buffer + : buffer.Reverse().ToArray(); + } + + public static string ToString(this T[] array, string separater) + { + int len; + StringBuilder sb; + + len = array.Length; + if (len == 0) + { + return String.Empty; + } + + sb = new StringBuilder(); + for (int i = 0; i < len - 1; i++) + { + sb.AppendFormat("{0}{1}", array[i].ToString(), separater); + } + sb.Append(array[len - 1].ToString()); + + return sb.ToString(); + } } } diff --git a/websocket-sharp/Frame/CloseStatusCode.cs b/websocket-sharp/Frame/CloseStatusCode.cs new file mode 100644 index 00000000..55ac982b --- /dev/null +++ b/websocket-sharp/Frame/CloseStatusCode.cs @@ -0,0 +1,59 @@ +#region MIT License +/** + * CloseStatusCode.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Frame +{ + public enum CloseStatusCode : ushort + { + /* + * Close Status Code + * + * Defined Status Codes: http://tools.ietf.org/html/rfc6455#section-7.4.1 + * + * "Reserved value" MUST NOT be set as a status code in a Close control frame by an endpoint. + * It is designated for use in applications expecting a status code to indicate that connection + * was closed due to a system grounds. + * + */ + NORMAL = 1000, // Normal closure. + AWAY = 1001, // A Server going down or a browser having navigated away from a page. + PROTOCOL_ERROR = 1002, // Terminating the connection due to a protocol error. + INCORRECT_DATA = 1003, // Received a type of data it cannot accept. + UNDEFINED = 1004, // Reserved value. Still undefined. + NO_STATUS_CODE = 1005, // Reserved value. + ABNORMAL = 1006, // Reserved value. Connection was closed abnormally. + INCONSISTENT_DATA = 1007, // Received data within a message that was not consistent with the type of the message. + POLICY_VIOLATION = 1008, // Received a message that violates its policy. + TOO_BIG = 1009, // Received a message that is too big. + IGNORE_EXTENSION = 1010, // Server ignored negotiated extensions. + SERVER_ERROR = 1011, // Server encountered an unexpected condition. + HANDSHAKE_FAILURE = 1015 // Reserved value. Failure to establish a connection. + } +} diff --git a/websocket-sharp/Frame/Fin.cs b/websocket-sharp/Frame/Fin.cs new file mode 100644 index 00000000..87428eb3 --- /dev/null +++ b/websocket-sharp/Frame/Fin.cs @@ -0,0 +1,38 @@ +#region MIT License +/** + * Fin.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Frame +{ + public enum Fin : byte + { + MORE = 0x0, + FINAL = 0x1 + } +} diff --git a/websocket-sharp/Frame/Mask.cs b/websocket-sharp/Frame/Mask.cs new file mode 100644 index 00000000..62e828f8 --- /dev/null +++ b/websocket-sharp/Frame/Mask.cs @@ -0,0 +1,38 @@ +#region MIT License +/** + * Mask.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Frame +{ + public enum Mask : byte + { + UNMASK = 0x0, + MASK = 0x1 + } +} diff --git a/websocket-sharp/Frame/Opcode.cs b/websocket-sharp/Frame/Opcode.cs new file mode 100644 index 00000000..d04155c4 --- /dev/null +++ b/websocket-sharp/Frame/Opcode.cs @@ -0,0 +1,43 @@ +#region MIT License +/** + * Opcode.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Frame +{ + [Flags] + public enum Opcode : byte + { + CONT = 0x0, + TEXT = 0x1, + BINARY = 0x2, + CLOSE = 0x8, + PING = 0x9, + PONG = 0xa + } +} diff --git a/websocket-sharp/Frame/PayloadData.cs b/websocket-sharp/Frame/PayloadData.cs new file mode 100644 index 00000000..ddbba73a --- /dev/null +++ b/websocket-sharp/Frame/PayloadData.cs @@ -0,0 +1,184 @@ +#region MIT License +/** + * PayloadData.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace WebSocketSharp.Frame +{ + public class PayloadData : IEnumerable + { + + #region Public Static Fields + + public static readonly ulong MaxLength; + + #endregion + + #region Properties + + public byte[] ExtensionData { get; private set; } + public byte[] ApplicationData { get; private set; } + public bool IsMasked { get; private set; } + + public ulong Length + { + get + { + return (ulong)(ExtensionData.LongLength + ApplicationData.LongLength); + } + } + + #endregion + + #region Static Constructor + + static PayloadData() + { + MaxLength = long.MaxValue; + } + + #endregion + + #region Public Constructors + + public PayloadData(string appData) + : this(Encoding.UTF8.GetBytes(appData)) + { + } + + public PayloadData(byte[] appData) + : this(new byte[]{}, appData) + { + } + + public PayloadData(byte[] appData, bool masked) + : this(new byte[]{}, appData, masked) + { + } + + public PayloadData(byte[] extData, byte[] appData) + : this(extData, appData, false) + { + } + + public PayloadData(byte[] extData, byte[] appData, bool masked) + { + Func func = s => () => + { + string message = String.Format("{0} must not be null.", s); + throw new ArgumentNullException(message); + }; + extData.IsNullDo(func("extData")); + appData.IsNullDo(func("appData")); + + if ((ulong)extData.LongLength + (ulong)appData.LongLength > MaxLength) + { + throw new ArgumentOutOfRangeException("Plus extData length and appData lenght must be less than MaxLength."); + } + + ExtensionData = extData; + ApplicationData = appData; + IsMasked = masked; + } + + #endregion + + #region Private Methods + + private void mask(byte[] src, byte[] key) + { + if (key.Length != 4) + { + throw new ArgumentOutOfRangeException("key length must be 4."); + } + + for (long i = 0; i < src.LongLength; i++) + { + src[i] = (byte)(src[i] ^ key[i % 4]); + } + } + + #endregion + + #region Public Methods + + public IEnumerator GetEnumerator() + { + foreach (byte b in ExtensionData) + { + yield return b; + } + foreach (byte b in ApplicationData) + { + yield return b; + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Mask(byte[] maskingKey) + { + if (ExtensionData.LongLength > 0) + { + mask(ExtensionData, maskingKey); + } + if (ApplicationData.LongLength > 0) + { + mask(ApplicationData, maskingKey); + } + + IsMasked = !IsMasked; + } + + public byte[] ToBytes() + { + if (ExtensionData.LongLength > 0) + { + return ExtensionData.Concat(ApplicationData).ToArray(); + } + else + { + return ApplicationData; + } + } + + public override string ToString() + { + return BitConverter.ToString(ToBytes()); + } + + #endregion + } +} diff --git a/websocket-sharp/Frame/Rsv.cs b/websocket-sharp/Frame/Rsv.cs new file mode 100644 index 00000000..1d31f854 --- /dev/null +++ b/websocket-sharp/Frame/Rsv.cs @@ -0,0 +1,38 @@ +#region MIT License +/** + * Rsv.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; + +namespace WebSocketSharp.Frame +{ + public enum Rsv : byte + { + OFF = 0x0, + ON = 0x1 + } +} diff --git a/websocket-sharp/Frame/WsFrame.cs b/websocket-sharp/Frame/WsFrame.cs new file mode 100644 index 00000000..267802c5 --- /dev/null +++ b/websocket-sharp/Frame/WsFrame.cs @@ -0,0 +1,461 @@ +#region MIT License +/** + * WsFrame.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; + +namespace WebSocketSharp.Frame +{ + public class WsFrame : IEnumerable + { + #region Private Static Fields + + private static readonly int _readBufferLen; + + #endregion + + #region Properties + + public Fin Fin { get; private set; } + public Rsv Rsv1 { get; private set; } + public Rsv Rsv2 { get; private set; } + public Rsv Rsv3 { get; private set; } + public Opcode Opcode { get; private set; } + public Mask Masked { get; private set; } + public byte PayloadLen { get; private set; } + public byte[] ExtPayloadLen { get; private set; } + public byte[] MaskingKey { get; private set; } + public PayloadData PayloadData { get; private set; } + + public ulong Length + { + get + { + return 2 + (ulong)(ExtPayloadLen.Length + MaskingKey.Length) + PayloadLength; + } + } + + public ulong PayloadLength + { + get + { + return PayloadData.Length; + } + } + + #endregion + + #region Static Constructor + + static WsFrame() + { + _readBufferLen = 1024; + } + + #endregion + + #region Private Constructors + + private WsFrame() + { + Rsv1 = Rsv.OFF; + Rsv2 = Rsv.OFF; + Rsv3 = Rsv.OFF; + ExtPayloadLen = new byte[]{}; + MaskingKey = new byte[]{}; + } + + #endregion + + #region Public Constructors + + public WsFrame(Opcode opcode, PayloadData payloadData) + : this(Fin.FINAL, opcode, payloadData) + { + } + + public WsFrame(Fin fin, Opcode opcode, PayloadData payloadData) + : this(fin, opcode, Mask.MASK, payloadData) + { + } + + public WsFrame(Fin fin, Opcode opcode, Mask mask, PayloadData payloadData) + : this() + { + Fin = fin; + Opcode = opcode; + Masked = mask; + + ulong dataLength = payloadData.Length; + if (dataLength < 126) + { + PayloadLen = (byte)dataLength; + } + else if (dataLength < 0x010000) + { + PayloadLen = (byte)126; + ExtPayloadLen = ((ushort)dataLength).ToBytes(ByteOrder.BIG); + } + else + { + PayloadLen = (byte)127; + ExtPayloadLen = dataLength.ToBytes(ByteOrder.BIG); + } + + PayloadData = payloadData; + if (Masked == Mask.MASK) + { + MaskingKey = new byte[4]; + var rand = new Random(); + rand.NextBytes(MaskingKey); + PayloadData.Mask(MaskingKey); + } + } + + #endregion + + #region Public Static Methods + + public static WsFrame Parse(byte[] src) + { + return Parse(src, true); + } + + public static WsFrame Parse(byte[] src, bool unmask) + { + using (MemoryStream ms = new MemoryStream(src)) + { + return Parse(ms, unmask); + } + } + + public static WsFrame Parse(TStream stream) + where TStream : System.IO.Stream + { + return Parse(stream, true); + } + + public static WsFrame Parse(TStream stream, bool unmask) + where TStream : System.IO.Stream + { + Fin fin; + Rsv rsv1, rsv2, rsv3; + Opcode opcode; + Mask masked; + byte payloadLen; + byte[] extPayloadLen = new byte[]{}; + byte[] maskingKey = new byte[]{}; + PayloadData payloadData; + + byte[] buffer1, buffer2, buffer3; + int buffer1Len = 2; + int buffer2Len = 0; + ulong buffer3Len = 0; + int maskingKeyLen = 4; + + buffer1 = new byte[buffer1Len]; + stream.Read(buffer1, 0, buffer1Len); + + // FIN + fin = (buffer1[0] & 0x80) == 0x80 + ? Fin.FINAL + : Fin.MORE; + // RSV1 + rsv1 = (buffer1[0] & 0x40) == 0x40 + ? Rsv.ON + : Rsv.OFF; + // RSV2 + rsv2 = (buffer1[0] & 0x20) == 0x20 + ? Rsv.ON + : Rsv.OFF; + // RSV3 + rsv3 = (buffer1[0] & 0x10) == 0x10 + ? Rsv.ON + : Rsv.OFF; + // opcode + opcode = (Opcode)(buffer1[0] & 0x0f); + // MASK + masked = (buffer1[1] & 0x80) == 0x80 + ? Mask.MASK + : Mask.UNMASK; + // Payload len + payloadLen = (byte)(buffer1[1] & 0x7f); + // Extended payload length + if (payloadLen <= 125) + { + buffer3Len = payloadLen; + } + else if (payloadLen == 126) + { + buffer2Len = 2; + } + else + { + buffer2Len = 8; + } + + if (buffer2Len > 0) + { + buffer2 = new byte[buffer2Len]; + stream.Read(buffer2, 0, buffer2Len); + extPayloadLen = buffer2; + switch (buffer2Len) + { + case 2: + buffer3Len = extPayloadLen.To(ByteOrder.BIG); + break; + case 8: + buffer3Len = extPayloadLen.To(ByteOrder.BIG); + break; + } + } + + if (buffer3Len > PayloadData.MaxLength) + { + throw new WsReceivedTooBigMessageException(); + } + // Masking-key + if (masked == Mask.MASK) + { + maskingKey = new byte[maskingKeyLen]; + stream.Read(maskingKey, 0, maskingKeyLen); + } + // Payload Data + if (buffer3Len <= (ulong)_readBufferLen) + { + buffer3 = new byte[buffer3Len]; + stream.Read(buffer3, 0, (int)buffer3Len); + } + else + { + buffer3 = stream.ReadBytes(buffer3Len, _readBufferLen); + } + + if (masked == Mask.MASK) + { + payloadData = new PayloadData(buffer3, true); + if (unmask == true) + { + payloadData.Mask(maskingKey); + masked = Mask.UNMASK; + maskingKey = new byte[]{}; + } + } + else + { + payloadData = new PayloadData(buffer3); + } + + return new WsFrame + { + Fin = fin, + Rsv1 = rsv1, + Rsv2 = rsv2, + Rsv3 = rsv3, + Opcode = opcode, + Masked = masked, + PayloadLen = payloadLen, + ExtPayloadLen = extPayloadLen, + MaskingKey = maskingKey, + PayloadData = payloadData + }; + } + + #endregion + + #region Public Methods + + public IEnumerator GetEnumerator() + { + foreach (byte b in ToBytes()) + { + yield return b; + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Print() + { + byte[] buffer; + long count, i, j; + int countDigit, remainder; + string countFmt, extPayloadLen, headerFmt, topLineFmt, bottomLineFmt, payloadData, spFmt; + + switch (ExtPayloadLen.Length) + { + case 2: + extPayloadLen = ExtPayloadLen.To(ByteOrder.BIG).ToString(); + break; + case 8: + extPayloadLen = ExtPayloadLen.To(ByteOrder.BIG).ToString(); + break; + default: + extPayloadLen = String.Empty; + break; + } + + if (((Opcode.TEXT | Opcode.PING | Opcode.PONG) & Opcode) == Opcode && + Masked == Mask.UNMASK && + PayloadLength > 0) + { + payloadData = Encoding.UTF8.GetString(PayloadData.ToBytes()); + } + else + { + payloadData = BitConverter.ToString(PayloadData.ToBytes()); + } + + headerFmt = @" + WsFrame: + + FIN={0}, RSV1={1}, RSV2={2}, RSV3={3}, Opcode={4}, + MASK={5}, Payload Len={6}, Extended Payload Len={7}, + Masking Key ={8}, + Payload Data={9}"; + + buffer = ToBytes(); + count = (long)(Length / 4); + remainder = (int)(Length % 4); + + if (count < 10000) + { + countDigit = 4; + countFmt = "{0,4}"; + } + else if (count < 0x010000) + { + countDigit = 4; + countFmt = "{0,4:X}"; + } + else if (count < 0x0100000000) + { + countDigit = 8; + countFmt = "{0,8:X}"; + } + else + { + countDigit = 16; + countFmt = "{0,16:X}"; + } + + spFmt = String.Format("{{0,{0}}}", countDigit); + + topLineFmt = String.Format(@" + {0} 01234567 89ABCDEF 01234567 89ABCDEF + {0}+--------+--------+--------+--------+", spFmt); + + Func> func = s => + { + long lineCount = 0; + string lineFmt = String.Format(" {0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|", s); + return (arg1, arg2, arg3, arg4) => + { + Console.WriteLine(lineFmt, ++lineCount, arg1, arg2, arg3, arg4); + }; + }; + var printLine = func(countFmt); + + bottomLineFmt = String.Format(" {0}+--------+--------+--------+--------+", spFmt); + + Console.WriteLine(headerFmt, + Fin, Rsv1, Rsv2, Rsv3, Opcode, + Masked, PayloadLen, extPayloadLen, + BitConverter.ToString(MaskingKey), + payloadData); + + Console.WriteLine(topLineFmt, String.Empty); + + for (i = 0; i <= count; i++) + { + j = i * 4; + if (i < count) + { + printLine( + Convert.ToString(buffer[j], 2).PadLeft(8, '0'), + Convert.ToString(buffer[j + 1], 2).PadLeft(8, '0'), + Convert.ToString(buffer[j + 2], 2).PadLeft(8, '0'), + Convert.ToString(buffer[j + 3], 2).PadLeft(8, '0')); + } + else if (i == count && remainder > 0) + { + printLine( + Convert.ToString(buffer[j], 2).PadLeft(8, '0'), + remainder >= 2 ? Convert.ToString(buffer[j + 1], 2).PadLeft(8, '0') : String.Empty, + remainder == 3 ? Convert.ToString(buffer[j + 2], 2).PadLeft(8, '0') : String.Empty, + String.Empty); + } + } + + Console.WriteLine(bottomLineFmt, String.Empty); + } + + public byte[] ToBytes() + { + var bytes = new List(); + + int first16 = (int)Fin; + first16 = (first16 << 1) + (int)Rsv1; + first16 = (first16 << 1) + (int)Rsv2; + first16 = (first16 << 1) + (int)Rsv3; + first16 = (first16 << 4) + (int)Opcode; + first16 = (first16 << 1) + (int)Masked; + first16 = (first16 << 7) + (int)PayloadLen; + bytes.AddRange(((ushort)first16).ToBytes(ByteOrder.BIG)); + + if (PayloadLen >= 126) + { + bytes.AddRange(ExtPayloadLen); + } + + if (Masked == Mask.MASK) + { + bytes.AddRange(MaskingKey); + } + + if (PayloadLen > 0) + { + bytes.AddRange(PayloadData.ToBytes()); + } + + return bytes.ToArray(); + } + + public override string ToString() + { + return BitConverter.ToString(ToBytes()); + } + + #endregion + } +} diff --git a/websocket-sharp/MessageEventArgs.cs b/websocket-sharp/MessageEventArgs.cs new file mode 100644 index 00000000..393f8e8c --- /dev/null +++ b/websocket-sharp/MessageEventArgs.cs @@ -0,0 +1,87 @@ +#region MIT License +/** + * MessageEventArgs.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Text; +using WebSocketSharp.Frame; + +namespace WebSocketSharp +{ + public class MessageEventArgs : EventArgs + { + private Opcode _type; + private PayloadData _data; + + public Opcode Type + { + get + { + return _type; + } + } + + public string Data + { + get + { + if (((Opcode.TEXT | Opcode.PING | Opcode.PONG) & _type) == _type) + { + if (_data.Length > 0) + { + return Encoding.UTF8.GetString(_data.ToBytes()); + } + else + { + return String.Empty; + } + } + + return _type.ToString(); + } + } + + public byte[] RawData + { + get + { + return _data.ToBytes(); + } + } + + public MessageEventArgs(string data) + : this(Opcode.TEXT, new PayloadData(data)) + { + } + + public MessageEventArgs(Opcode type, PayloadData data) + { + _type = type; + _data = data; + } + } +} diff --git a/websocket-sharp/IWsStream.cs b/websocket-sharp/Stream/IWsStream.cs similarity index 77% rename from websocket-sharp/IWsStream.cs rename to websocket-sharp/Stream/IWsStream.cs index 43b17b1b..27ba1e45 100644 --- a/websocket-sharp/IWsStream.cs +++ b/websocket-sharp/Stream/IWsStream.cs @@ -4,7 +4,7 @@ * * The MIT License * - * Copyright (c) 2010 sta.blockhead + * Copyright (c) 2010-2012 sta.blockhead * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,15 +27,18 @@ #endregion using System; +using WebSocketSharp.Frame; -namespace WebSocketSharp +namespace WebSocketSharp.Stream { public interface IWsStream : IDisposable { - void Close(); - int Read(byte[] buffer, int offset, int size); - int ReadByte(); - void Write(byte[] buffer, int offset, int count); - void WriteByte(byte value); + void Close(); + int Read(byte[] buffer, int offset, int size); + int ReadByte(); + WsFrame ReadFrame(); + void Write(byte[] buffer, int offset, int count); + void WriteByte(byte value); + void WriteFrame(WsFrame frame); } } diff --git a/websocket-sharp/WsStream.cs b/websocket-sharp/Stream/WsStream.cs similarity index 62% rename from websocket-sharp/WsStream.cs rename to websocket-sharp/Stream/WsStream.cs index 4f542ad5..ab7efecd 100644 --- a/websocket-sharp/WsStream.cs +++ b/websocket-sharp/Stream/WsStream.cs @@ -4,7 +4,7 @@ * * The MIT License * - * Copyright (c) 2010 sta.blockhead + * Copyright (c) 2010-2012 sta.blockhead * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,21 +32,24 @@ using System.IO; using System.Net.Security; using System.Net.Sockets; using System.Reflection; +using WebSocketSharp.Frame; -namespace WebSocketSharp +namespace WebSocketSharp.Stream { - public class WsStream : IWsStream - where T : Stream + public class WsStream : IWsStream + where TStream : System.IO.Stream { - private T innerStream; + private TStream _innerStream; + private Object _forRead; + private Object _forWrite; - public WsStream(T innerStream) + public WsStream(TStream innerStream) { - Type streamType = typeof(T); + Type streamType = typeof(TStream); if (streamType != typeof(NetworkStream) && streamType != typeof(SslStream)) { - throw new NotSupportedException("Unsupported Stream type: " + streamType.ToString()); + throw new NotSupportedException("Not supported Stream type: " + streamType.ToString()); } if (innerStream == null) @@ -54,37 +57,56 @@ namespace WebSocketSharp throw new ArgumentNullException("innerStream"); } - this.innerStream = innerStream; + _innerStream = innerStream; + _forRead = new object(); + _forWrite = new object(); } public void Close() { - innerStream.Close(); + _innerStream.Close(); } public void Dispose() { - innerStream.Dispose(); + _innerStream.Dispose(); } public int Read(byte[] buffer, int offset, int size) { - return innerStream.Read(buffer, offset, size); + return _innerStream.Read(buffer, offset, size); } public int ReadByte() { - return innerStream.ReadByte(); + return _innerStream.ReadByte(); + } + + public WsFrame ReadFrame() + { + lock (_forRead) + { + return WsFrame.Parse(_innerStream); + } } public void Write(byte[] buffer, int offset, int count) { - innerStream.Write(buffer, offset, count); + _innerStream.Write(buffer, offset, count); } public void WriteByte(byte value) { - innerStream.WriteByte(value); + _innerStream.WriteByte(value); + } + + public void WriteFrame(WsFrame frame) + { + lock (_forWrite) + { + var buffer = frame.ToBytes(); + _innerStream.Write(buffer, 0, buffer.Length); + } } } } diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 90ba1ab1..4b8bca5c 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -8,7 +8,7 @@ * The MIT License * * Copyright (c) 2009 Adam MacBeth - * Copyright (c) 2010 sta.blockhead + * Copyright (c) 2010-2012 sta.blockhead * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,228 +32,285 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Security; using System.Net.Sockets; +using System.Reflection; using System.Text; using System.Threading; +using System.Security.Authentication; using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using WebSocketSharp.Frame; +using WebSocketSharp.Stream; namespace WebSocketSharp { - public delegate void MessageEventHandler(object sender, string eventdata); - public class WebSocket : IDisposable { - private Uri uri; - public string Url + #region Private Const Fields + + private const string _guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + private const string _version = "13"; + + #endregion + + #region Private Fields + + private string _base64key; + private string _binaryType; + private string _extensions; + private Object _forClose; + private Object _forSend; + private int _fragmentLen; + private Thread _msgThread; + private NetworkStream _netStream; + private string _protocol; + private string _protocols; + private volatile WsState _readyState; + private SslStream _sslStream; + private TcpClient _tcpClient; + private Uri _uri; + private SynchronizedCollection _unTransmittedBuffer; + private IWsStream _wsStream; + + #endregion + + #region Properties + + public string BinaryType { - get { return uri.ToString(); } + get { return _binaryType; } } - private Object sync = new Object(); + public ulong BufferedAmount + { + get + { + ulong bufferedAmount = 0; + + lock (_unTransmittedBuffer.SyncRoot) + { + foreach (WsFrame frame in _unTransmittedBuffer) + { + bufferedAmount += frame.PayloadLength; + } + } + + return bufferedAmount; + } + } + + public string Extensions + { + get { return _extensions; } + } + + public string Protocol + { + get { return _protocol; } + } - private volatile WsState readyState; public WsState ReadyState { - get { return readyState; } + get { return _readyState; } private set { + _readyState = value; + switch (value) { case WsState.OPEN: - readyState = value; + messageThreadStart(); if (OnOpen != null) { OnOpen(this, EventArgs.Empty); } break; case WsState.CLOSING: + break; case WsState.CLOSED: - lock(sync) - { - close(value); - } + closeConnection(); break; } } } - private StringBuilder unTransmittedBuffer; - public String UnTransmittedBuffer + public SynchronizedCollection UnTransmittedBuffer { - get { return unTransmittedBuffer.ToString(); } + get { return _unTransmittedBuffer; } } - private long bufferedAmount; - public long BufferedAmount + public string Url { - get { return bufferedAmount; } + get { return _uri.ToString(); } } - private string protocol; - public string Protocol + #endregion + + #region Events + + public event EventHandler OnOpen; + public event EventHandler OnMessage; + public event EventHandler OnError; + public event EventHandler OnClose; + + #endregion + + #region Private Constructors + + private WebSocket() { - get { return protocol; } + _binaryType = String.Empty; + _extensions = String.Empty; + _forClose = new Object(); + _forSend = new Object(); + _fragmentLen = 1024; // Max value is int.MaxValue - 14. + _protocol = String.Empty; + _readyState = WsState.CONNECTING; + _unTransmittedBuffer = new SynchronizedCollection(); } - private TcpClient tcpClient; - private NetworkStream netStream; - private SslStream sslStream; - private IWsStream wsStream; - private Thread msgThread; + #endregion - public event EventHandler OnOpen; - public event MessageEventHandler OnMessage; - public event MessageEventHandler OnError; - public event EventHandler OnClose; + #region Public Constructors - public WebSocket(string url) - : this(url, String.Empty) + public WebSocket(string url, params string[] protocols) + : this() { - } - - public WebSocket(string url, string protocol) - { - this.uri = new Uri(url); - string scheme = uri.Scheme; + _uri = new Uri(url); + string scheme = _uri.Scheme; if (scheme != "ws" && scheme != "wss") { - throw new ArgumentException("Unsupported scheme: " + scheme); + throw new ArgumentException("Unsupported WebSocket URI scheme: " + scheme); } - this.readyState = WsState.CONNECTING; - this.unTransmittedBuffer = new StringBuilder(); - this.bufferedAmount = 0; - this.protocol = protocol; + _protocols = protocols.ToString(", "); } public WebSocket( - string url, - EventHandler onOpen, - MessageEventHandler onMessage, - MessageEventHandler onError, - EventHandler onClose) - : this(url, String.Empty, onOpen, onMessage, onError, onClose) + string url, + EventHandler onOpen, + EventHandler onMessage, + EventHandler onError, + EventHandler onClose, + params string[] protocols) + : this(url, protocols) { - } + OnOpen = onOpen; + OnMessage = onMessage; + OnError = onError; + OnClose = onClose; - public WebSocket( - string url, - string protocol, - EventHandler onOpen, - MessageEventHandler onMessage, - MessageEventHandler onError, - EventHandler onClose) - : this(url, protocol) - { - this.OnOpen += onOpen; - this.OnMessage += onMessage; - this.OnError += onError; - this.OnClose += onClose; - Connect(); } - public void Connect() + #endregion + + #region Private Methods + + private void close(PayloadData data) { - if (readyState == WsState.OPEN) + #if DEBUG + Console.WriteLine("WS: Info@close: Current thread IsBackground?: {0}", Thread.CurrentThread.IsBackground); + #endif + lock(_forClose) { - Console.WriteLine("WS: Info @Connect: Connection is already established."); - return; + if (_readyState == WsState.CLOSING || + _readyState == WsState.CLOSED) + { + return; + } + + if (OnClose != null) + { + OnClose(this, new CloseEventArgs(data)); + } + + if (_readyState == WsState.CONNECTING) + { + ReadyState = WsState.CLOSED; + return; + } + else + { + ReadyState = WsState.CLOSING; + } } - createConnection(); - doHandshake(); - - this.msgThread = new Thread(new ThreadStart(message)); - msgThread.IsBackground = true; - msgThread.Start(); + var frame = new WsFrame(Opcode.CLOSE, data); + closeHandshake(frame); + #if DEBUG + Console.WriteLine("WS: Info@close: Exit close method."); + #endif } - public void Send(string data) + private void close(CloseStatusCode code, string reason) { - if (readyState == WsState.CONNECTING) + byte[] buffer; + List data; + + data = new List(((ushort)code).ToBytes(ByteOrder.BIG)); + + if (reason != String.Empty) { - throw new InvalidOperationException("Handshake not complete."); + buffer = Encoding.UTF8.GetBytes(reason); + data.AddRange(buffer); } - byte[] dataBuffer = Encoding.UTF8.GetBytes(data); + close(new PayloadData(data.ToArray())); + } + private void closeConnection() + { + if (_wsStream != null) + { + _wsStream.Dispose(); + _wsStream = null; + } + else if (_netStream != null) + { + _netStream.Dispose(); + _netStream = null; + } + + if (_tcpClient != null) + { + _tcpClient.Close(); + _tcpClient = null; + } + } + + private void closeHandshake(WsFrame frame) + { try { - wsStream.WriteByte(0x00); - wsStream.Write(dataBuffer, 0, dataBuffer.Length); - wsStream.WriteByte(0xff); + _wsStream.WriteFrame(frame); } - catch (Exception e) + catch (Exception ex) { - unTransmittedBuffer.Append(data); - bufferedAmount += dataBuffer.Length; - - if (OnError != null) - { - OnError(this, e.Message); - } -#if DEBUG - Console.WriteLine("WS: Error @Send: {0}", e.Message); -#endif + _unTransmittedBuffer.Add(frame); + error(ex.Message); } - } - public void Close() - { - ReadyState = WsState.CLOSING; - } - - public void Dispose() - { - Close(); - } - - private void close(WsState state) - { -#if DEBUG - Console.WriteLine("WS: Info @close: Current thread IsBackground: {0}", Thread.CurrentThread.IsBackground); -#endif - if (readyState == WsState.CLOSING || - readyState == WsState.CLOSED) + if (!Thread.CurrentThread.IsBackground) { - return; + _msgThread.Join(5000); } - readyState = state; - - if (wsStream != null) - { - wsStream.Close(); - wsStream = null; - } - - if (tcpClient != null) - { - tcpClient.Close(); - tcpClient = null; - } - - if (OnClose != null) - { - OnClose(this, EventArgs.Empty); - } -#if DEBUG - Console.WriteLine("WS: Info @close: Exit close method."); -#endif + ReadyState = WsState.CLOSED; } private void createConnection() { - string scheme = uri.Scheme; - string host = uri.DnsSafeHost; - int port = uri.Port; + string scheme = _uri.Scheme; + string host = _uri.DnsSafeHost; + int port = _uri.Port; if (port <= 0) { @@ -267,229 +324,610 @@ namespace WebSocketSharp } } - this.tcpClient = new TcpClient(host, port); - this.netStream = tcpClient.GetStream(); + _tcpClient = new TcpClient(host, port); + _netStream = _tcpClient.GetStream(); if (scheme == "wss") { - this.sslStream = new SslStream(netStream); - sslStream.AuthenticateAsClient(host); - this.wsStream = new WsStream(sslStream); + RemoteCertificateValidationCallback validation = (sender, certificate, chain, sslPolicyErrors) => + { + // Temporary implementation + return true; + }; + + _sslStream = new SslStream(_netStream, false, validation); + _sslStream.AuthenticateAsClient(host); + + _wsStream = new WsStream(_sslStream); } else { - this.wsStream = new WsStream(netStream); + _wsStream = new WsStream(_netStream); } } - private void doHandshake() + private string createExpectedKey() { - byte[] expectedCR, actualCR; - string request = createOpeningHandshake(out expectedCR); -#if DEBUG - Console.WriteLine("WS: Info @doHandshake: Handshake from client: \n{0}", request); -#endif - string[] response = sendOpeningHandshake(request, out actualCR); -#if DEBUG - Console.WriteLine("WS: Info @doHandshake: Handshake from server:"); - foreach (string s in response) - { - Console.WriteLine("{0}", s); - } -#endif - string msg; - if (!(response.IsValid(expectedCR, actualCR, out msg))) - { - throw new IOException(msg); - } + byte[] keySrc; + SHA1 sha1 = new SHA1CryptoServiceProvider(); + StringBuilder sb = new StringBuilder(_base64key); - for (int i = 3; i < response.Length; i++) - { - if (response[i].Contains("Sec-WebSocket-Protocol:")) - { - int j = response[i].IndexOf(":"); - protocol = response[i].Substring(j + 1).Trim(); - break; - } - } -#if DEBUG - Console.WriteLine("WS: Info @doHandshake: Sub protocol: {0}", protocol); -#endif - ReadyState = WsState.OPEN; + sb.Append(_guid); + keySrc = sha1.ComputeHash(Encoding.UTF8.GetBytes(sb.ToString())); + + return Convert.ToBase64String(keySrc); } - private string createOpeningHandshake(out byte[] expectedCR) + private string createOpeningHandshake() { - string path = uri.PathAndQuery; - string host = uri.DnsSafeHost; - string origin = "http://" + host; + byte[] keySrc; + int port; + string crlf, host, origin, path; + string reqConnection, reqHost, reqMethod, reqOrigin, reqUpgrade; + string secWsKey, secWsProtocol, secWsVersion; + Random rand; - int port = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port; + path = _uri.PathAndQuery; + + host = _uri.DnsSafeHost; + port = ((IPEndPoint)_tcpClient.Client.RemoteEndPoint).Port; if (port != 80) { host += ":" + port; } - string subProtocol = protocol != String.Empty - ? String.Format("Sec-WebSocket-Protocol: {0}\r\n", protocol) - : protocol; + origin = "http://" + host; - Random rand = new Random(); + keySrc = new byte[16]; + rand = new Random(); + rand.NextBytes(keySrc); + _base64key = Convert.ToBase64String(keySrc); - uint key1, key2; - string secKey1 = rand.GenerateSecKey(out key1); - string secKey2 = rand.GenerateSecKey(out key2); + crlf = "\r\n"; - byte[] key3 = new byte[8].InitializeWithPrintableASCII(rand); + reqMethod = String.Format("GET {0} HTTP/1.1{1}", path, crlf); + reqHost = String.Format("Host: {0}{1}", host, crlf); + reqUpgrade = String.Format("Upgrade: websocket{0}", crlf); + reqConnection = String.Format("Connection: Upgrade{0}", crlf); + reqOrigin = String.Format("Origin: {0}{1}", origin, crlf); + secWsKey = String.Format("Sec-WebSocket-Key: {0}{1}", _base64key, crlf); + + secWsProtocol = _protocols != String.Empty + ? String.Format("Sec-WebSocket-Protocol: {0}{1}", _protocols, crlf) + : _protocols; - string secKeys = "Sec-WebSocket-Key1: {0}\r\n" + - "Sec-WebSocket-Key2: {1}\r\n"; - secKeys = String.Format(secKeys, secKey1, secKey2); + secWsVersion = String.Format("Sec-WebSocket-Version: {0}{1}", _version, crlf); - string key3ToAscii = Encoding.ASCII.GetString(key3); - - expectedCR = createExpectedCR(key1, key2, key3); - - return "GET " + path + " HTTP/1.1\r\n" + - "Upgrade: WebSocket\r\n" + - "Connection: Upgrade\r\n" + - subProtocol + - "Host: " + host + "\r\n" + - "Origin: " + origin + "\r\n" + - secKeys + - "\r\n" + - key3ToAscii; + return reqMethod + + reqHost + + reqUpgrade + + reqConnection + + secWsKey + + reqOrigin + + secWsProtocol + + secWsVersion + + crlf; } - private byte[] createExpectedCR(uint key1, uint key2, byte[] key3) + private void doHandshake() { - byte[] key1Bytes = BitConverter.GetBytes(key1); - byte[] key2Bytes = BitConverter.GetBytes(key2); + string msg, request; + string[] response; - Array.Reverse(key1Bytes); - Array.Reverse(key2Bytes); - - byte[] concatKeys = key1Bytes.Concat(key2Bytes).Concat(key3).ToArray(); - - MD5 md5 = MD5.Create(); - return md5.ComputeHash(concatKeys); - } - - private string[] sendOpeningHandshake(string openingHandshake, out byte[] challengeResponse) - { - challengeResponse = new byte[16]; - List rawdata = new List(); - - byte[] sendBuffer = Encoding.UTF8.GetBytes(openingHandshake); - wsStream.Write(sendBuffer, 0, sendBuffer.Length); - - while (true) + request = createOpeningHandshake(); + #if DEBUG + Console.WriteLine("WS: Info@doHandshake: Opening handshake from client:\n{0}", request); + #endif + response = sendOpeningHandshake(request); + #if DEBUG + Console.WriteLine("WS: Info@doHandshake: Opening handshake from server:"); + foreach (string s in response) { - if (wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) && - wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata) && - wsStream.ReadByte().EqualsWithSaveTo('\r', rawdata) && - wsStream.ReadByte().EqualsWithSaveTo('\n', rawdata)) - { - wsStream.Read(challengeResponse, 0, challengeResponse.Length); - break; - } + Console.WriteLine("{0}", s); + } + #endif + if (!isValidResponse(response, out msg)) + { + throw new InvalidOperationException(msg); } - return Encoding.UTF8.GetString(rawdata.ToArray()) - .Replace("\r\n", "\n").Replace("\n\n", "\n") - .Split('\n'); + ReadyState = WsState.OPEN; + } + + private void error(string message) + { + var callerFrame = new StackFrame(1); + var caller = callerFrame.GetMethod(); + + if (OnError != null) + { + OnError(this, new MessageEventArgs(message)); + } + else + { + Console.WriteLine("WS: Error@{0}: {1}", caller.Name, message); + } + } + + private bool isValidResponse(string[] response, out string message) + { + Func> func; + string resUpgrade, resConnection; + string secWsAccept, secWsVersion; + string[] resStatus; + List extensionList = new List(); + + func = s => + { + return (e, a) => + { + return String.Format("Invalid response {0} value: {1}(expected: {2})", s, a, e); + }; + }; + + resStatus = response[0].Split(' '); + if ("HTTP/1.1".NotEqualsDo(resStatus[0], func("HTTP Version"), out message, false)) + { + return false; + } + if ("101".NotEqualsDo(resStatus[1], func("Status Code"), out message, false)) + { + return false; + } + + for (int i = 1; i < response.Length; i++) + { + if (response[i].Contains("Upgrade:")) + { + resUpgrade = response[i].GetHeaderValue(":"); + if ("websocket".NotEqualsDo(resUpgrade, func("Upgrade"), out message, true)) + { + return false; + } + } + else if (response[i].Contains("Connection:")) + { + resConnection = response[i].GetHeaderValue(":"); + if ("Upgrade".NotEqualsDo(resConnection, func("Connection"), out message, true)) + { + return false; + } + } + else if (response[i].Contains("Sec-WebSocket-Accept:")) + { + secWsAccept = response[i].GetHeaderValue(":"); + if (createExpectedKey().NotEqualsDo(secWsAccept, func("Sec-WebSocket-Accept"), out message, false)) + { + return false; + } + } + else if (response[i].Contains("Sec-WebSocket-Extensions:")) + { + extensionList.Add(response[i].GetHeaderValue(":")); + } + else if (response[i].Contains("Sec-WebSocket-Protocol:")) + { + _protocol = response[i].GetHeaderValue(":"); + #if DEBUG + Console.WriteLine("WS: Info@isValidResponse: Sub protocol: {0}", _protocol); + #endif + } + else if (response[i].Contains("Sec-WebSocket-Version:")) + { + secWsVersion = response[i].GetHeaderValue(":"); + #if DEBUG + Console.WriteLine("WS: Info@isValidResponse: Version: {0}", secWsVersion); + #endif + } + else + { + Console.WriteLine("WS: Info@isValidResponse: Unsupported response header line: {0}", response[i]); + } + } + #if DEBUG + foreach (string s in extensionList) + { + Console.WriteLine("WS: Info@isValidResponse: Extensions: {0}", s); + } + #endif + message = String.Empty; + return true; } private void message() { -#if DEBUG - Console.WriteLine("WS: Info @message: Current thread IsBackground: {0}", Thread.CurrentThread.IsBackground); -#endif - string data; - while (readyState == WsState.OPEN) + #if DEBUG + Console.WriteLine("WS: Info@message: Current thread IsBackground?: {0}", Thread.CurrentThread.IsBackground); + #endif + MessageEventArgs eventArgs; + while (_readyState == WsState.OPEN) { - data = receive(); - - if (OnMessage != null && data != null) + try { - OnMessage(this, data); + eventArgs = receive(); + + if (OnMessage != null && eventArgs != null) + { + OnMessage(this, eventArgs); + } + } + catch (WsReceivedTooBigMessageException ex) + { + close(CloseStatusCode.TOO_BIG, ex.Message); } } -#if DEBUG - Console.WriteLine("WS: Info @message: Exit message method."); -#endif + #if DEBUG + Console.WriteLine("WS: Info@message: Exit message method."); + #endif } - private string receive() + private void messageThreadStart() { - try + _msgThread = new Thread(new ThreadStart(message)); + _msgThread.IsBackground = true; + _msgThread.Start(); + } + + private MessageEventArgs receive() + { + List dataBuffer; + MessageEventArgs eventArgs; + Fin fin; + WsFrame frame; + Opcode opcode; + PayloadData payloadData; + + frame = _wsStream.ReadFrame(); + if ((frame.Fin == Fin.FINAL && frame.Opcode == Opcode.CONT) || + (frame.Fin == Fin.MORE && frame.Opcode == Opcode.CONT)) { - byte frame_type = (byte)wsStream.ReadByte(); - byte b; + return null; + } - if ((frame_type & 0x80) == 0x80) - { - // Skip data frame - int len = 0; - int b_v; - - do - { - b = (byte)wsStream.ReadByte(); - b_v = b & 0x7f; - len = len * 128 + b_v; - } - while ((b & 0x80) == 0x80); - - for (int i = 0; i < len; i++) - { - wsStream.ReadByte(); - } - - if (frame_type == 0xff && len == 0) - { - ReadyState = WsState.CLOSED; -#if DEBUG - Console.WriteLine("WS: Info @receive: Server start closing handshake."); -#endif - } - } - else if (frame_type == 0x00) - { - List raw_data = new List(); + fin = frame.Fin; + opcode = frame.Opcode; + payloadData = frame.PayloadData; + eventArgs = null; + switch (fin) + { + case Fin.MORE: + dataBuffer = new List(payloadData.ToBytes()); while (true) { - b = (byte)wsStream.ReadByte(); + frame = _wsStream.ReadFrame(); - if (b == 0xff) + if (frame.Fin == Fin.MORE) { + if (frame.Opcode == Opcode.CONT) + {// MORE & CONT + dataBuffer.AddRange(frame.PayloadData.ToBytes()); + } + else + { + #if DEBUG + Console.WriteLine("WS: Info@receive: Client starts closing handshake."); + #endif + close(CloseStatusCode.INCORRECT_DATA, String.Empty); + return null; + } + } + else if (frame.Opcode == Opcode.CONT) + {// FINAL & CONT + dataBuffer.AddRange(frame.PayloadData.ToBytes()); break; } - - raw_data.Add(b); + else if (frame.Opcode == Opcode.CLOSE) + {// FINAL & CLOSE + #if DEBUG + Console.WriteLine("WS: Info@receive: Server starts closing handshake."); + #endif + close(frame.PayloadData); + return null; + } + else if (frame.Opcode == Opcode.PING) + {// FINAL & PING + pong(frame.PayloadData); + if (OnMessage != null) + { + OnMessage(this, new MessageEventArgs(frame.Opcode, frame.PayloadData)); + } + } + else if (frame.Opcode == Opcode.PONG) + {// FINAL & PONG + if (OnMessage != null) + { + OnMessage(this, new MessageEventArgs(frame.Opcode, frame.PayloadData)); + } + } + else + {// FINAL & (TEXT | BINARY) + #if DEBUG + Console.WriteLine("WS: Info@receive: Client starts closing handshake."); + #endif + close(CloseStatusCode.INCORRECT_DATA, String.Empty); + return null; + } } - return Encoding.UTF8.GetString(raw_data.ToArray()); - } - } - catch (Exception e) - { - if (readyState == WsState.OPEN) - { - if (OnError != null) + eventArgs = new MessageEventArgs(opcode, new PayloadData(dataBuffer.ToArray())); + break; + case Fin.FINAL: + switch (opcode) { - OnError(this, e.Message); + case Opcode.TEXT: + case Opcode.BINARY: + case Opcode.PONG: + goto default; + case Opcode.CLOSE: + #if DEBUG + Console.WriteLine("WS: Info@receive: Server starts closing handshake."); + #endif + close(payloadData); + break; + case Opcode.PING: + pong(payloadData); + goto default; + default: + eventArgs = new MessageEventArgs(opcode, payloadData); + break; } + + break; + } - ReadyState = WsState.CLOSED; -#if DEBUG - Console.WriteLine("WS: Error @receive: {0}", e.Message); -#endif + return eventArgs; + } + + private void pong(PayloadData data) + { + var frame = new WsFrame(Opcode.PONG, data); + send(frame); + } + + private void pong(string data) + { + var payloadData = new PayloadData(data); + pong(payloadData); + } + + private bool send(WsFrame frame) + { + if (_readyState != WsState.OPEN) + { + var msg = "Connection isn't established or connection was closed."; + error(msg); + + return false; + } + + try + { + if (_unTransmittedBuffer.Count == 0) + { + _wsStream.WriteFrame(frame); + } + else + { + _unTransmittedBuffer.Add(frame); + } + } + catch (Exception ex) + { + _unTransmittedBuffer.Add(frame); + error(ex.Message); + + return false; + } + + return true; + } + + private void send(Opcode opcode, PayloadData data) + { + using (MemoryStream ms = new MemoryStream(data.ToBytes())) + { + send(opcode, ms); + } + } + + private void send(Opcode opcode, TStream stream) + where TStream : System.IO.Stream + { + if (_unTransmittedBuffer.Count > 0) + { + var msg = "Current data can not be sent because there is untransmitted data."; + error(msg); + } + + lock(_forSend) + { + var length = stream.Length; + if (length <= _fragmentLen) + { + var buffer = new byte[length]; + stream.Read(buffer, 0, (int)length); + var frame = new WsFrame(opcode, new PayloadData(buffer)); + send(frame); + } + else + { + sendFragmented(opcode, stream); + } + } + } + + private ulong sendFragmented(Opcode opcode, TStream stream) + where TStream : System.IO.Stream + { + if (_readyState != WsState.OPEN) + { + var msg = "Connection isn't established or connection was closed."; + error(msg); + + return 0; + } + + WsFrame frame; + PayloadData payloadData; + + var buffer1 = new byte[_fragmentLen]; + var buffer2 = new byte[_fragmentLen]; + ulong readLen = 0; + int tmpLen1 = 0; + int tmpLen2 = 0; + + tmpLen1 = stream.Read(buffer1, 0, _fragmentLen); + while (tmpLen1 > 0) + { + payloadData = new PayloadData(buffer1.SubArray(0, tmpLen1)); + + tmpLen2 = stream.Read(buffer2, 0, _fragmentLen); + if (tmpLen2 > 0) + { + if (readLen > 0) + { + frame = new WsFrame(Fin.MORE, Opcode.CONT, payloadData); + } + else + { + frame = new WsFrame(Fin.MORE, opcode, payloadData); + } + } + else + { + if (readLen > 0) + { + frame = new WsFrame(Opcode.CONT, payloadData); + } + else + { + frame = new WsFrame(opcode, payloadData); + } + } + + readLen += (ulong)tmpLen1; + send(frame); + + if (tmpLen2 == 0) break; + payloadData = new PayloadData(buffer2.SubArray(0, tmpLen2)); + + tmpLen1 = stream.Read(buffer1, 0, _fragmentLen); + if (tmpLen1 > 0) + { + frame = new WsFrame(Fin.MORE, Opcode.CONT, payloadData); + } + else + { + frame = new WsFrame(Opcode.CONT, payloadData); + } + + readLen += (ulong)tmpLen2; + send(frame); + } + + return readLen; + } + + private string[] sendOpeningHandshake(string value) + { + var readData = new List(); + var buffer = Encoding.UTF8.GetBytes(value); + + _wsStream.Write(buffer, 0, buffer.Length); + + while (true) + { + if (_wsStream.ReadByte().EqualsAndSaveTo('\r', readData) && + _wsStream.ReadByte().EqualsAndSaveTo('\n', readData) && + _wsStream.ReadByte().EqualsAndSaveTo('\r', readData) && + _wsStream.ReadByte().EqualsAndSaveTo('\n', readData)) + { + break; } } - return null; + return Encoding.UTF8.GetString(readData.ToArray()) + .Replace("\r\n", "\n").Replace("\n\n", "\n").TrimEnd('\n') + .Split('\n'); } + + #endregion + + #region Public Methods + + public void Connect() + { + if (_readyState == WsState.OPEN) + { + Console.WriteLine("WS: Info@Connect: Connection is already established."); + return; + } + + try + { + createConnection(); + doHandshake(); + } + catch (Exception ex) + { + error(ex.Message); + close(CloseStatusCode.HANDSHAKE_FAILURE, ex.Message); + } + } + + public void Close() + { + Close(CloseStatusCode.NORMAL); + } + + public void Close(CloseStatusCode code) + { + Close(code, String.Empty); + } + + public void Close(CloseStatusCode code, string reason) + { + close(code, reason); + } + + public void Dispose() + { + Close(CloseStatusCode.AWAY); + } + + public void Ping() + { + Ping(String.Empty); + } + + public void Ping(string data) + { + var payloadData = new PayloadData(data); + var frame = new WsFrame(Opcode.PING, payloadData); + send(frame); + } + + public void Send(string data) + { + var payloadData = new PayloadData(data); + send(Opcode.TEXT, payloadData); + } + + public void Send(byte[] data) + { + var payloadData = new PayloadData(data); + send(Opcode.BINARY, payloadData); + } + + public void Send(FileInfo file) + { + using (FileStream fs = file.OpenRead()) + { + send(Opcode.BINARY, fs); + } + } + + #endregion } } diff --git a/websocket-sharp/WsReceivedTooBigMessageException.cs b/websocket-sharp/WsReceivedTooBigMessageException.cs new file mode 100644 index 00000000..bf50e89e --- /dev/null +++ b/websocket-sharp/WsReceivedTooBigMessageException.cs @@ -0,0 +1,54 @@ +#region MIT License +/** + * WsReceivedTooBigMessageException.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using WebSocketSharp.Frame; + +namespace WebSocketSharp +{ + public class WsReceivedTooBigMessageException : Exception + { + private static readonly string _defaultMessage; + + static WsReceivedTooBigMessageException() + { + _defaultMessage = String.Format( + "Client received a payload data bigger than the allowable value({0} bytes).", PayloadData.MaxLength); + } + + public WsReceivedTooBigMessageException() + : this(_defaultMessage) + { + } + + public WsReceivedTooBigMessageException(string message) + : base(message) + { + } + } +} diff --git a/websocket-sharp/WsState.cs b/websocket-sharp/WsState.cs index 0de3717e..130c6691 100644 --- a/websocket-sharp/WsState.cs +++ b/websocket-sharp/WsState.cs @@ -4,7 +4,7 @@ * * The MIT License * - * Copyright (c) 2010 sta.blockhead + * Copyright (c) 2010-2012 sta.blockhead * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll b/websocket-sharp/bin/Debug/websocket-sharp.dll deleted file mode 100755 index d89cb9274607886e02c9910191d4bca37d78360c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15872 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 diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb b/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb deleted file mode 100644 index 6bad58473dff7d025b2d3e90d0328437a7947bf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4763 zcmcIo3vd)w7JaX~)0ycvpUi}qm$$VV`c@DWKw!z5q?MM;oa1L9=TNrogd!}JVE zb}3O35RF)3f`xok2Z&cl-8zcV@sdOD+x``gut{F+T4;|9yU4*|^*GT$tNDq;|M_otuy_Zr$J{ zLW^xp8`VlJ-gVS*D(m_|&P_i|Ba<(8p^~O3=Fd8{alxLNo||_>ULR}`@2~jehsQoWQWWhv zdAeY5?BSerQhd4d&rvJO^o?SbNmnd;C%KF>A^4 zo*TSm%4M&jl|_9~6>E&2JGAzl{ROvlE}5}%*H<2Y__m^XL-t*rx#%y4H&za8J#zUw zDV>8wBC4+et5|xTnz-f@*YvGl9SGOt(B}NSzrVEoqmr4u&prN{JMiQ+#QVSO#9ZX} zU%TD+jcYC1_vf(Cmo;lqwIS1>TyLnp z9%&W`1-0C1YEX>?{LH*HBM@BZNIaA>o_qo(z%(LJ{{1vobDGkbeJ4~*?QLo_^=C1+ zO!dbifoQY4uTD<}Ek3$jZHlItx65m>@v1f;fV*I#w~z>w#K0X%RlOe1@t( z39Up;!2R)*4fa;>n-?v@Qfmv!g(xJ~hZ@yL-ULFEW8tta5wXG7WDF^!tk^%}03Wl~ zD(tp)V+b{<`51pTq7_%}^J<&$xb0b6mkoP0owgB46g9y{ z84ScjcImMFxSfYW*8H_g&VA)f`zgJhY!C~z&&`=A-&}|%B_&_MGgf?i{9&}1?IN$8A{m?1(I6q2gLx%0w zPU#!x`TpAFDbfQeD^lV+%>N|6qyoJveM$6Tk?B`tF;cg2^VN0lkudYwyJ z@7j=1`%U#rE@`K07gw7vhvQ1V+$LoBZ&^iJLE(WqykAuOqf0vEItDv|QWb^0$`|!b ziB(st5t3y1YR@ou$n6Hto^9}*8!45Rtil^7iZ5YWjj2jKV|8sS^HQ1C;b$9m^98sfKuEq&oW$Mt61#!oQTyJfDyHO&UM($)If zA5v;NevYM;`P$WvIR2$NwC^}}on;RTiN@+n6rBh3d zi5s_=A?u>A>MLA;Z*_I`Ue?A`HdO0qW9@bOSO;I@omA;m>WTq`SR|@ZD_tO4Xh2HV zi<)SOs9G2&t4fISbJZf$60d4RNRFrrV=A1IjkSl*p>)zzL#_@Q9DEajUerx#(u1^H zcW8q^ZRJ(U+zLfm7q6{0x~7HQs^pAioviJ!_@iEMlc*vpLJECY5BZJ(($@o?NF&5< zV|8lt*z!=3ekibHP4%PtYebQ_o>)yqK9RX1k0f)-Cl*tmN0Ow7FIYt+ro}4JszyWp zP(4lvJTyR@rQzbUsU&!TDdn#u#pk1Uki-Q%nGxH(XDV~9Y>N&YFLwYWwJA)vi$P-bl zoWDpA#CkO-Bw66jd_H9|rInN@)e&EVIzQSRR;f%?#cnuBdf{aDDpdGEg;cmTM5Wn2 zD%?k*q3bDbCU?@eDYd*xUo!)KmYy}Gb94uG^&`L9mI-SF?(MT8WsJqzZ37w8#-8T+ zV;>Z7JT*4{`C+3~AMsr>^9oP;d;P-z|r;c-!=7 z#xpu^n&J4Yc|?-Mk%CN_-;%}l`I*X-Qr?;=@69}xY19WwrSn# zkxzThaCQ7xlX+7x11@8faKR&7^eoTfx6MZ}iRxeDoHH-c0O-v$zG$E`Ma~+1K)gG| zn-gjnHHaVnu|P1IIQon9MtnFw%;%s*V_)!P*JTOov$kYy#lrD*$Nc}+ok!WXoqXB$ zfkMZ?4Ffk1>=%ug8I6asg|_UD>^{+$Xu5aTC8AMi_Cu2!=FiWM_biv{cz)U5n3kjB zJrV-bNNsKYD*kkZ=dy*a?48+rvyp(P>1gh&0DQ@o9|gApBIJYMmjV3Ay||nN_?LiT zxTJCcfAhe_Kr-YL;8y^&;WER`^N`UX%ljd}0Pv>uQ}77@Eurk;g8(#Iav^vOfUZie z1m6LmlaZUiApjkP{0Mj%fb(763|Uc-} z7__ybh()FK))ut(h}KrC_GoK+@YMFSr}nM2J(s>ptG#&i)Shb9R$ImQ`#fvUjilDo z_xwJ;KYqW#dG>lPYprKJ>silw_S$>ms*68K1`)aN{on(l$8qIPy}%C#BVY%rz80WI zy+4@pxVG{KQ`)!oq#^^!M0YaQ7wL@k_b1Yk&GATbus_n%A8BfBi}WSB;x)y^zNt>r zYnq8xY6e|DuVPK6w-+fe#jlw}SA)We@h9SZkK@YPMR3t`?2H(ZCUkIRTtubvU+(Il zEPzjCgs7DZ$BCY1L!A0~k*MfY+DE`kBSfA&xh~)<^6;8;d{-Lyt@{ALld)nv`JV{U zrkZ3b*$JZPb{qvB=*RHQ`_#iAHOY8y0)nFJi(qnF*WsJ@sV7>Nhf48-X{8a+v!D8i zDqied8C#7qk7w*pM`I${)Z4o%*3(aYsm??)9 zr|c-v$k>hlk5WUmCY7N@^l$6W`CMiKC7)?TVJqKBtvXa|Q3d!wZQV$~8+<<9tk{@< zlD>o+pqf_ig~v3fX%szpM5fr>!>xP6o|9pWZbAaa@tt7~ zaR=T+IiM;h!YImkESieiFo$g{f`X(U>~Ynz8T4w`jWEmvpKh38R}@zCnXqRCy$vSX zwx5Mk6QY%%b4ioZ;>W7z#wj+)F~+h%mOI)8%*xq-{o1e+6Jei> z5q_(T5UQO*Z^58&5Ui^x1Wo_5aC*lU@GfQfdR}~1I64VU9AN6bEaa>E8tUfBL#j}I zGRrg7k-xrB9!^&%j|ui2V5%d3aiM&63NrdcSe~hle08CGc4jj2Q&^sJns>}K=?9o|uQ7vfnWzNSz-H|creLaY|?DTU&>InNUp;&c)JJ)112 zdv40}#DzFR#J^Q2o}2MJaUsqW@mmYUa}%B?F2ouUj~9yP<~vVZh_gg|L7{kVy7R<^ zSS#X~RSL^~;xnSyy3B=G=VVGuGC&eZ8JBk!-!Nc;dhhpMBS;lx}t^jGT^Q37=l zb8OW0nTxm=**dFJ^HAR(E~Mnm>By z2yd9fP&^|Gzi=Ug2=S&4$t7F~_IJTV=*v$rT#+2udK4aI>PG4umcWF%^dW|crNDh= z@;nSQdM?Tfr=W(JT$RPq8YR~QHPxn751}h{SMpAlfHu=Pt&sk{hQ!2-!WB*3H5}qD z+`~u%TzbGYTrOAlFy`H*M`1jZZQ&-k31My9`Vd#}nSOl_7c3)s0T^k78_kTuAk%%O z6@^m1ML(5|;KS>#{z!FUJM_yMO21sl^ov1HFr%>kU+Q=4y3+4QtjiXWe!1}9?Dy2V zAFW@^6UNIkApLS7(=XN_#tRqwOXD58uJrpC>rU2(*sH52)Ru@J!bR=yHlIGk4w_ho zIr3Z4MqC_96N*K3@JjL|no%w`y@}oMl#M=5Vma_dzsA&`Kr7^txZp{^Yke=AfZAk5 zS8y3#Mbv;b%!wp>GB0D)C9cIEro(!KZfPUFT$ex4m6u&LuDqnG&(KeXI4x$!=G^;I z$OPDahO^cTA69!aq7kQKGy~t+_|{?7VqF6@l}9hcSVa9m3P`m;88{7K~d^_>ok8j4_q1qz3fy8XvMg`x^Oix{iYJQi5Llue; z2`GwL^0^Wh0pcD+?j&?e?jlkjV=XYrJn4MDlZ~rG7?*2d1#0V36hG0+hM8Q4j1XiW zOQ_*x{4hXj{(zG=xYxtO>_F}aMcFdqSeu7t_Ldg4Y6wwrkZhRQgzk$}hGjxPbF zd{Lwc<_Rzfwo5wV0A^5`!D5GcepNry7 z8S~-uJLOF%7kR?xa8)O$$3R*LAE(IIHQeLZu?ttNDbg)Z3Z5aigf3m#fDZwDVw3#3 z@HW~DrawALGU4pS9 zz-R2$2YSezXRu;t#Qk6-5&&rg5iK!*lHaOYvzT4Qn>>sjElJ0tSAbKTyd4Cu?292+ zRjJBCQc18v0XtwOQYh(4i(%G0c?|MJ$u9%iZcjALf}Z5RaU%|9CEoz%i4HQ$mz<<$ z5i@xK5ZmPldXqgsl|dX5%!3u1zkm?pDftGE3WK{5b&9LJ zH$qiyTG;m7J*~pF?w(d@`|h4L&NlC!Hs1E%J#B*Ry?fe3yXfv|lkDQVr%m?U9o+$K zc|R{A7?$HJ@{Kd$82;oWv}~yWWkq39vnY8JND?AE#o>^v4tX?rZPy(kck*3uY_~|; zu8NHzm+kT%>^b*m2>ZGxNKq_4bCCp})K2txrCuTNh}UGO)+g}3|h$C3r&^J*Q0uB zFNh;d61vX_-%)WRq+z(K$Y&B)aTRy+Otfsf!*`g;g(xLPKy`&VpD~>ipJbazR6ydA zu_Y=(R^7+oy@qYwkxa47KD4rME)*9M`y{8vF!sm6wan!0*@i0eyQ-_pv~ui2S}Bt1 z9y9sWUufm`nU4Q0+Y09O6kUq-D5AdUHIs&W%yHK}kf}411!PF$L9)%lK_#xnVC!IO z)j=#PjF5_hFt$n70K()^4HvoSE_*caS#{%oU;~gF^ID< zc*q2mwy1TAL%ZxgiN#LSA-4iomgmm|_%*zl;AnPop*8m2U)KN$JvtK>M;=fHD=b9J zgpVPC!AfTWb|Uuo6X>7(dgKi(aZBw@r$JEmrp&fqvG`$VoIJ{%tw)_|-pBdFn+UHp zWLmr~crVxaer6WR{L%H3CiFK`*P>SH69B`!z3D>?D-zd%pvsB;+$`4YdTPN~k>@!3 zXksm@7kd-fPt1yXOec902;t^J4rGeFh{vR;i%^%!sujIR(Lye70@26}xy$^XkZGIY z#azKQD;D>_{p+3wu-%DUAtLz(G~yj7zvD&Aay@Xr$U?bAsU!JE9or-MyNrGG$Zudx zmA0@k%c|>M`fDwGJ1a1`9#e}OERSPtUG*k;4Udh7U*)Y|2%!wC1|(;iCox$~uo6|Z zQy791;5KA?s`AytLmcsif4$~k9pzKJ4sh}fBl#p5lWzTWJJE~n;?;r-*#`viPQFlF zZrby&%%9@$>v&PuO$Era2Q~!oO)$_BE%EB%BK=k z-iB*Y^9%?uAGsXi_|-O2SjJd2rnFm)_2!rLhQZsp1;NtEuVac>5K5ZiYUiHidW_vk z<=Br@B3OsL6?Vqn0>Y(`I57_j;Va@fnjP>mJIEsQL}ifT`Gz3~*y!M7D(ZeRv> zmkGER!OlwH*)HYAH=rFpE01ECO_$pv=h#HWnOuBft#~nDy=Cu*_}=Vh;8@#OgREbI zhZJ7Qg2}VIxgqOASnn?9j;%yL8HV3ZNZbhFB9A_V1m3mnoCT=l`H7@K#U(l(2J|>$ z2tmFx46pJMzF`QtbOc+Okviy&Q0|KQp#K^9cXODl%sm9hMbslGmv;|g6LLVRDwr$e z!>7#EHcS@lr}WAzhg{)pA$K@rhC>#st5_$)FpzqH5i;w3iRQdv+l(R_O&9%(N}&1} zvhertQl2Ml_}dx-D1^hF)FuqpFGCC)8H@v|2(ghN!v^u!K}CXyAhz2!w{1j*YAGAp z)*@a+b?_O?d)T%L)EQHAgubPPN^l36-q3+n(195~ryOD5c5_^wLeE1sg1+Q2kx$ZV zLo#c4F*~{ywhs32Ehr)p7K}sf(Xp z7sR{@Gdi1_DdZuMK|HK3}f-QaK4B|&o|>ZGhqV8 zP(^zbGT>fZgZ;+D>cp0%P8J+8=L6zX)iM(Z7~B9qNYT~7EzV@5 zJ_{;)2B{y7V4Su-*$^%99G2PPN?Dv0QLOIi!x6M&NVk>S8fT)05~|G5F6t3!pYC`! zJN7VU)1{7wL>o_9to4qixE4tFr7rZFU&9^qREji+& zfxT3djSxSZ#XTH6)b}i=OFd=rna^SX>iN-Pr1xY#J1dK`MUxeN z921Md@*Z#+2e<`!#+z(~KnnAWdpBeFPF$UH?z?iu&!AXM=j(fzeKO2-6Q3P}cCpYl zC^^IBc0|jBd`kV#32_3}0M?(Jqv=E3W#+hSi2LFb^6CB)aBY%J$T{J%WIxtH#e5PE z6PC*EL8JOVs`_8;=;dg2H&Z9zj0zUzy&QWjkJIVjNQ}UkIQnKaB(gfyxUqa)a(g-J zg1MI5o7WnDLbb&-PZcxI7Q)ePw5*4tJ?gSuF0v6uaX0~vDi5MuU5z#8if-Z})gT5{ zxT7&fLbYeo6KEGx4xhN3s~OQaUtG~XzPO_aTmou!`OK=l+ZtFu-F%LZNzA$>K+FhS zg|;b8wPelKMEL2+2$le^ndn|7W9>|5oY#&N&@^ap6GfAPqRq_Eq@ZYs zEJ{uaiU#czO$v&JIIL(=P&C9|MU#S}&B@TDplEY5G$|+=rdidM0%)OHFXx2vsobVV zlNj8=9%X=oJsY=e)T6sW+Q{pFjxN@bpv3rTI7bTOH?^ww}5{eAI}R%E}0W zK03e5tq=A?mKldH&p&^-Z5y?@ANHfmv5?Tdt^6)zIag0*2!}xdq+=!HL#1}H%x%b5 zLbfk#7oQAIm3s zFfhDyBl7}kWPXgyAGQMpBlF{yDG;)4yHee=+LITTqfQ+*9>Tqp>?hnwiG#z|(}4mb zyF|iyBU>YN0p{{b+g(u)tC6ivB|{$c=n31U1wEGR#k{z-E#ru0mt3!OD}rQE*e*ft zo-@02s-qjO5Djt9Mcf5$h9F&$`Z)Rwd5wi)0I%)gQ~_zVJ2StM0oz5AK!?034kDqT z9W)ahN9>@L;5cOmJqZp}cF@ZQxVYjTr%x5!d@9QnGr=(h1&dcY7d#0LUnqDJ93|`^ zbPUz%a*qf7>=eSP4tC~`W&=g=n75xLf5&7v}gvPEn@wK9>E@N`KQ z;H=MEAt6ag$Y00nDvun!pZoGByRn~!JbHA5N2o`4;W8dCa%D=F_k`S5q!f#J+Ywd*zr7Si9zuiW{os5cKQ(Ql2Ri(iHS@7fwxY#arD2{pX z;Y|5;CKahOZ13Lru(~`dxEk7}9)QRQlZ1}7UWyt0BG??yNp4pjAM z7pn4WGdhl>_2?GH5LJLx>d~z^Y@8n5mczy?drKCFV{2t{RuuIn>d^s~M9k9oAREWr z*b>qpiD~biR^`Q6cl1FhW_wk3-iC5`TT$JsFo0+Lwu_5B))Hi{WZS0qCx)hao z{>|%J%JZ&@*;?({vIqO z-q9P-IC8fe`Qnb=#Ck2Af?4LzRU>QBA?HUoGab3mI>tFak^&k74QoNsq@ZZ+8JZM8 zZQH@5+F>C4-CPl!r{^+e}EzcJXKDXrd z>=ZT>8AF1{aMHXVsJwm)r^Wo7joF0#-16dq^t}iB4Gy#y0^)pX5iTdgfo$fa4=v8J zWkIm-XWChvJPr4R`Vaz|%Vk92em?dA=>zk!5S!S%q&M);1mv4Dt3WD{mOvKi*mz?!cuE+A>o}Lrgg|youTR5MPG5N4-K? zt>aEXXQ7IXQd=RaHlEBp3I}#n;FqZ(ewu@Fd3*{{%XejV%>2&4IiR!e=|jA{CuBAp zeTbJoTx^<81p?kguu)VP*m7KW8tTTw(11&A5Zrd2t@==tZN=9-TX{&wcB*XE3l`go zuV(fo61EjqFV+1N0OMrWm1Q%G4Ug@G94TurAq_F*&@kdG+lw#5+$-$GE!W+m+F>Es zi!Zv=(1*Bo#$HZG2jE@9JuDL*-iAwNVuUorltaVYnXM1;MRioEI${fe&O+#jFAC9z zxOS!^HC{C_JTI&x*Bm`BhQtjo<|P>@VYlQJAW;}EuHPY(h^ct@G;Og|Ybh4+vJH-;OEl?TG>Fe7lx}0dM5Bz1l z3Ai17a*g_Z$LZ&-Z)sv-=L6r?F0A^h-#ZzE@p#4F1Odeh@kR6UZsGm7Vqwd3yzk*U z1>cMC#r%t`3s(zYreoD|6H?}On8!GluDq+nA(7}oi+RlP;Y86ygs1~tF0c#GM+XGn zEtKa3zD93CM%P$=ipKIY1kM(?Uf?AHV*oG)gV~JtXMuWLm2pkf4oxs}-mV8pm-hisZn6&hOt#*$0-qQ7I%Is*ioD*WT>?Mh zyV+;by+z#b<;DHQ&`01Gidml(0ha78;ql&I&V4;4@Mi+w7Z?sReU`xU0eut?bDO&a zeoElOVQ%N!Vb=MCl>Y$8pU<-s!J{6S`Hq36xhQ!<+?!Xt&@6Fv3ni`?^4gR=3yfvuvo4)0#!ZJL}cmY`#_cI2eD9nj@#N8iN) zD+Nv!SnJzsXtYRRqi-{0*7&}PSKKb~eI0O%$P5S^@*M}|E53gM{D$ut!0-Bg1o#8r zzX1NicLMM=-%EgR`d$WnU!dFnJGV{6{&xT;`QLY&=BmJE+Ay*{@Q$@%WRt+Sz&=2Y z(t-B?uMCh!qlW^OfL{%;=HCpQg~;MBX(w)Brf0**X(hFQX8~$tT9^?ESv;1BfU_x8 z!ehC*Z<&BbcpnFSa0!}OKg?y91O{L_qX}ENQhx@8TFN=aP z?}m{Efy)K17uY4RU*NF7YX#mW@R-1d1^%PJ9|C6de<^rAT7DTYLwPN@4wN?mGn99N z@4-s%3)Dkg_6jT!SO&O&#)aZujZP1-{>ub*hR#C#91d;G_O-TbHCkQ|XwYNuUW5LP zdI6uL&4AydIN;mG?SP$SOz$gW`p&YMkl!oitEGHH*+X7~E-4qu@+VOqEq`4(w{UYg zw{Tba=oSznrLWf_SPJwhYV}?KZz-ChuwL(j*d6eAPI&vhmm?lDIoKxab;F`d9qe=7 zF1MEsI9Rjwc_TnGPE++BG#4WdU+Q2l(+<2Dx9N1ndzlWn!_+lZVZSx|j7sV{Lt&O{ znLeI+qYC@I_Y3Zcbf1G=qkT@BOjFNd-oDB&<6JsIpA_s`U`1v`Jpv=fD$LWUmN$O7 z)^n+Uff=P<2kQoQ7TxDygZ|~XqxzMDT?1@7MW(BIw*s3%mpa%HU^D492m7*rvsptw zaj>rgn?0m$g?=@@bNe6pPcuzanp9Ooy!8}Eugyg>qw$D>hbQqYt zPJuC;QFO$dO)F-q9+nnO!&=-Z*gjfbbPT*1NHJj-V2_z|Xpe(kRx}Ie^{+TsU(t8W zd9)QbFD!XAc=KruZUY#*1#Ql!+Z^nE!Q|Bd@SYOMJ#&=g4~iavvpnbmL z{TPyU^p=CYC0H%;AMU{_uE&0Moop)msHFH9cDnnr*dw%%o_4T;#qiKFUsjRu%#}>>ay7V z)-qa=#U3*osa>#_wJu{8HB*;e5e`bif1dus(n zmU8ch=)B^mtrnWqvkX%#p9rF@;I@`O3cj8ypGy7$Y`@4)bIT+8;Wt4U>?)@@4;9%VQCOYC^-1{ba z%fYz!O;prC_`Ixf@0}EJFz&sJMg&vwB~Hf$<2g!Mae5|;b$hz$-?P{io^5nw8Mmpd z)K6a&>?Q4J>Bl_%^r&Fhdj41G^}wDKY@g>}OK$@9U5EFx(!-tvJ?rrPqx247FF3r{ z!5g4oIlOnl8=%)6o^BuZTtV+RJimPhFjph%a;>Kfukt3TNU(jLD*FhqN{3f%f5DTY zh{Kz2KLBio!>hL+_M~Z^!)vuaWu&Rz;azTfJ%hBu;SJai=!4Ym@U8}L2VLs$4uQ9W zwmQ5c_G6x%G~nB#Yf??4bk8dF(H1VdE{&Ub;`PYw4%*yy+(sNJ9>$#3z5Nx04vCsqhb@YnE`zP@B)9ViJdGPkrdk*h+p=Y$~$+eO-+vj;N zRBl{PrGj1SVSC;{^AwNnD&6h9fkp&VcDa%6Qj&C|=K=jjddI=oE(dAeDsEHR>(x9E|%rOcMoD{T-$mxF65-cbMuNjQcxG^@6GX4$}(3uAzI%naB4>9mx50 ziUS(d4X6>nm8#QKQa&tD$=oUB2ZZ}5pg~{v>d3l|qwJ=qh5H!V)ai%9eNx*0SCn;n zK`2bu=s$#_TFWo1eqR+C)uZY?pRQU{y3O=+%d-JBQe{3PHE0>2i&g@g1hr;)9Q{~QXs>H;zKp%h} zeE-uxoTU^|sdfY4I7FVcbf$JEP8u4uFW`KEccF1~KzopmqShm{5X8>Q+ehm1E_P+sN*IokrKzjwyqyG-j*8c!FUVk6(bls&f^a(5#7#28D;AsM* z0&4`$6SzqG5jE=dfaA1wZ7p4($F!fy7=KE=`c{;8>jT>DLg^Jd^vbAv#TvbGKf6b` zuL3?ouhPRhkM2qRcI^$Jlw!P})ArB{`WLl#@n-HrD2I*5w2#qL;~zAyM1NZ{@pq{g z+;Q45dRCjF-9rDOouwTzPH3~WdyQ97eo}uA@UbjK(HpeqjB33>`xSPP7VUkbR=*YY zT%dFL9K947z%rd@?FL$_Rl3&bYqit$4SEA{UU`w^ntQ}UV%logG-}W;c3rB!N*yS_ zN(om?A4j`fw`&(^U#7Tzk#@6dyM6`A1GF3P3VpZsGuI<@7uwh8^8)vQK8x6fkI;Ut z&V7S!Q{eX<|ds?+Qjd-L#)W3)xXVIg81F-)h^FQ@RA@c@Ws5jpMmsi0T zVfpv;~tyZ*J>SIzT`adg~V1^8XF&3IS)m3a|lSbn0T$rJ9lF%IqEu9^4*AcpcIr0EP_ zkkh0W3Z2FxB{?rpf`tyfPP# z=IAn)hqlsYz+UPG9H3snG+p6xD8XzmdIYoTYUXV~*S&yPIsdvtG&x5<0G_ptYN@8`Xb;;d9d&iI<| z5a63WzA=1Xpxb{wG71ejt_K;eAO8Y~O5>3;Oh$GPf!rU9e}P4z2VMrW16-aca9ZF$ zQLYW(cUsgWlo?t8&j{|3@_m62%6|w%0RJo$y<{57`#mkluYO~%27F!M+X8R)aNR%I zZJd1tHv$#~xrOlpZ}(gZ%CsQsFhgK<8FT9dt|;S{759TOt~;;%all;JgKS5~xPpK> z_5uT=4I!SCVw^5e#>@E2VS!SN8c+0)6Jhn^X`=^}N^U-on&j zqY}VI>7fa&>Nq1S2Rsk8b^MlZ9BQ49_H=3i)Q}}jLb(f2qi(dJ(-uIDdXTf|h-*_& z-j1h3I&A~g@QdGRDE9(tc=CBB%KdL#?@=ios z9r+i-T{tyG21#>4zX4~MI)3XjALSeI&NQ-BK#gv~IiyYp1%8qiqkI>h;Oq1mmRYCW1h_~$q=jjPb_?M7D3@Y?U5RJ5Gn{{qJJ%iBu(n@& zS~K-ZeMrAX|5yD5-7;8eSlfx~my8p}e;7@kV_w$?XT4E8P_xED*P3PHCi0sYv?{?n19ed zM*;mPMf3-0r9MtO-I$~;FsigQ$oV>q+1g6vc>9g>w5yQsoNinI-YS$^aow)HYg_?2 z9o~e$hoiai#S?1y^ko|MPtAw2AKxN;i}4NMi;w(Cz}}wCw6Z6a-ZY!qcBj(uzM95F zZ*ROa-IM4~)tndak0*ONsiCWj8Wa6H;>ollM(v4ZyVG$}5C5s9zbn40bqlo(ZcfST z0MwrB>7!*mX{TB|NiC_BJ?V6Byt%)tC)S_qE*Yl==?|^!NNkUzr@nz0sLKcYJ2%ax z=DvaSZmQ`_Cz6E5*%PZ_MX0Y zinZiw&InstX&vfNOLPBVUpyJx+#AR6F~)VV{_Z$N){sobc9VjQiGkhJzIz}}>jwMN zXpPG&V*OpcaXK%aW^8#f(dSTF`qQ%)U>xbWa~Lj|N9z@dFQD-S#MaH*U}E&-m=8wk zjHPLHBHcDPFpx;5<6X_WI^zR83yyK1;j%=cHxA3e^iHX9Yb*&=E=`F+3AwP2gh$}7Qm~EM6OJz|8|>-r z!gM>vZs)(I*)T8=@9$ckNcLfr3d!)>;>jI7o$*!p>!ZD(^>=PfCi;7>jCbYy5JO*| z?4j;>x}&XgYrHQ`iGhxm{`eJxvEClIMnke2^VpxxnM_2{*1AL@O{>rz`%Xrot?V!` z0!Ec)w{!*v5p;wh=Wyw=aWI)gfuAVeC z??5xq73SoU@|Yww#e3u3F)Ssx{pOzjIQvaJi9Z>-J`BKlhwLwzDeg>&RoHgx+n3i-d*?u7Zx0XM zvE1r-x~7fwN~fr?H-U*SwD_ucDiy;5IzNFwILgg5^{3imTjDDcskGp0;MqKP&6$}) zi#rp^?auOq?VS=2GaYY4xarx_gOw5AfSK-!@p5R4_4aPYfC`j~cMf7eyQwYJ>$K1? znBEH2rE)_mGmaGvvm2AU2hs`0>((R_J9_e*wasa$MoHn1I~Y$wAF-C27-dQXzcnyVzDfe5>WOvtV-|Wk;i&QS z) zGc$$AK0r$l76*IdOX(Db{2AX1SN;iX;mz>omvMFf{+l!cK0TnEqz^T2QA4Od1+@yM?-(2zYV??-#rIyF6l{0Xjm6V z%XPCWC^;E!AJCg>ygiZYsH1zZr;9px|K=Q{ zW3$Au?eX0x_VmY+yCvo6K+uWzvqXw`O{l2Pr8Zu#9b23g3fHENzErof?R4~KBY6k@ z=6E{Mndqf#2~EKxy0G%u>snG961@mu*p!@L<>XmNMEeFnMpu#{pjs*$-aFFS&8Y*S zpE?Hn+mo^WR39?Tc-JyX52<5k#tU2fITBE7e`bqn?Qc#d5wKeO)sU7f-O|w!>zmpc zLxM3IUQmF~r@>?|ehsfilA?raE|F~x(N~(o_9XjatgEZT=`$%ib_P?7j22m5hM?H0 ztt?Zailv&*vJ}c8by;rG1QiR!yBhi=)G`T+J~Ne!V(U}$!U(T0XFfP==b_A9KZb3E z4x@C+c(FCdNER<4&Ug^lkm18`u$^>57`uF)ln|O7Z@&P}*oGb3 zk>eRe+|M=AmB^LjV*WlS0XZcoV5z9+K#oBEHkDK{4L=0Io{~@zh&P{6-8p*F8s2=w z{kO2wE;)4+eBXgLmgd(k%*$UgzCC7wQFDrLO4Z(q-IX(%HHqGy&fVe#DTEE&X(g#M zml_dLLkMDR6bO!rj8JP1jt=r1MJ~UYF*R3ni^NOwlTuj<|gV$^Nm!8xQi6ojU>`=L2lx>ur9V!$^tS-hxiwV4tB7P zoiSu}d^f}uWFL{5ip#|dGXm_8pzx7x4@bEI2~}dgS?xpnml9TY$9)G7cbyMf+w4=;ta5)5ZI&{3f2HbK$(-F z%*{~d3dPAnSjs7KTgrAK=@gloGmUWaQ05lcP6P@mnRb-{vu!(QUi-2RSfMUAL-XB{f{w za1pIp*V^9N*t)W#dEL6!b=0!Dv31=#M1YQ_hV}+pzq+Y;dCO|7{MD@;ZS4*1>)SdS zTbr7xVVTniS6JQF($?O*+Nraqb!AKAMI9SjT30r-x3sRN_SV)8UV|;?p-yv0^G3+F zF{7<{-G=6MPR}bERySd{xS+XXc|*&}_3N5x6{HEhL)G=GS2eU+n#TV-v06Ftw%?U{!3FGwda>i`p}J21a{0PBIXhEn)_DKAKJ;XVu4JMua_wc%_# zt;?4aWAH!uz$e}lbFo&kDX{4#RYnP)H$+pt?Kh%u1=AARh z?Ak}}zGO4*G?v!zkTRz;9}+B3p+FS(3W(ujRQSt1eZ*ceV!b$6S>Bf>zN&j&G0J?3 zCA()cn8RQ$1EiXck#Mu(lt5!6%~z&8n;KFn+>H0`ZtubAX+s+4tDA8EktH|9Q=Q2k zIV&8^MAovUr+ZKx5sbyg`BMMx(F|k&U4xzJ(F{K8OZIec9fO4oyer-pOK#8A%DPUD z8wPo`7^eIOj^6 zY7Er;*ZOG2lcXMLJ=b?cH09nBXs?E-We%P#)!|841KttG`wDm()r_Y~vuPem^YE;x z3DlXO%*WFtE;XXm0PSkQX++KWD9^?}GVro{$yW52hP@ZzN!Bb_xESv{(V6F=&324Z zX&%9|Hq0umfy8X+Fgr6J<5q};(s`qFW@`F+w8@rW`zTBA#C0?5l$#aDE;AcJ>&HL7 zg~xriU_2LvZ8*}CTG1*FsPXL|-S6BsX=Ns!j-BcQGx4jiIDCs+R&6=Dp7UXK*2rw) zBo(?P;1Q#0FaEIF8_**jq~wjMplA1NJTs&#M*Bq<`dR_ou@9v%_c8Hf?z>giM!$@{ z8#wa{r6TZO_P{=H*^hdl1N-bE%&cR>p8w~1R9X5^ALbarag!sTS}7^E^Q;eReY6kLg_-%t#k(G~ zxB-@AkLg0R#L*da=atEG%Cpo48*j#SKxS~PH9<2!Opn4Dgx0J67A;O~C9|68s=uYR zzqE&NY|kG*uQV0y*|Q^JC5~9RctCA`OaEifXLd~8qub=2i}$}6Vxa2(e_(GKVUj@K%$;V8#r8NItj@cu}wV5D3FV;Z^U)XBs_w3vn) z;!q#KSEW*$(G3qNlaesbG8_n*!$|`Vp3AImM3NFtwYZ%WHV95OGD%pbA1GlU1#tT~ z5g22mC^Uzf$gu{fdgO4z8gLr08ybvlD)f072cjL2Q{g8fwF(!Y+AboF)F9eYi;uUC zD6n0!HF65U##FpH;GG4t9xn8@LT}_8G=}d0;BF|85OpJHBxCx`Fjcp#H=a>8teOgC zVy@jQ^>|j<3)tjpFsx?O+36zS?H2V?PzrL1xFt|Xa`3bxDP+r zneT(>g_zsrAaX^v5zi$5K)!`m((d=d2sJ<0lt2CLf`3>Zx_(q5~GH#1YD!OtTyxHb2`c-IS7hb^2 zwT`7coo_Tb!WH&ENDom+v&w_xi~uNRz$_20!0+A- z6Yo`;_`?L!s$ouYyCb?bvC>nj>0k%T4WH(>B8F#@+vD*24=EobKI;!Ggs7tZBpd%)7v$*)wrAS>Yb@8f;9~U=i zlia#MLtwE$Q=sDdq+BG>66h7^FDX?@PbO9!Blc%iX;t;C!m%xR36UB=I#Td)0 zdcg5YZay%{z$GMxgJIc@_Q-F6nsN<*360)>;?TSnK58#hFr7-^I@oSm%jsDpYXW5zKZJ-RkB<3(gXpAx&Z?VH`N5hZS)1 z+%rcqw9kze0|7WU`W0iqjUzgisz2gF!x*9-GQ8zMN6@1x2Ftlo=nyQ& z5GJ|HfhoVuhb#W44uM>J0^#B)(F1<(M`u<1dH>08 z9s1++@89r?*mLK)Z|RHQ_u05w8O9pN$x$3P8+Pu%*`@03-+VJT8uOCWwPP6vEc+1jrYkvPkDiAEctZ~D) z-Ws@f|H(i8;fqUm{^P$t`>{iB75(VVgD-sRTaVYBQ}hoNKa1>o%0~v=T}3(z@zc^c zcIbAbgxv58#|=vZdXeQ);n9x(<+eChxGdf8heL5xl*s0>uv&T2UEsU%9y>1$_>EbL}6C8&MRtS4j0E!1D zM@%h%icYnHOXVbIogDI5SjUI(pAY`($dp>}DCx_&-%B&LDkQYqm6CC*${9p3|811A0e!;-wI1wCq34v3e6etaxX8E8|E_QIWNti)5 z!kCH_0TXq~f)k-{u&ms|`ogvuEVJhYXV^=E_4Yh_3G~N!0P3M0RH?{?!ZLsP{A1i%M*YJ>UpO95>h4wc#P6CM?@HVIrH#s!ndw8>sU_w;i%6x3D$Fb;*wn#tjA#d zm`j2yW^JI|oxY#5`1z9<}P6%~y88<6X&pE-2Np1^!94@-WbNF^}#%Wdv%{R$E zbOKw#wqjEbtgtKgSZDimvwhY~w}O-0KA+E%aS)H?&rH6feJ+eTv*9UXBRgC%b2}Sq z9)l(ZbubxQGguFE)as_+>sTaM&d$sF$^|+}$Opk^@e+d1AuF;pAM3Ue@grC+?O)3E z_pz0+&s&-o?N8KAp9O2ObCzjTvh$Qz4(V)-<}^eaPmlEU4fNt=YrN&jua`y=TOzSY z_N~E4=544*r+Tp!X&0g?eldqL&B7+-WkvjWgo^Q6TFqvDvw17tH^N_eL_nu@J$xZv zvt6C{0xMq6N$gB3$JXS_={z4{=N1_L-PDz znW^sTtABmWJbnCWzMC%iX7zmYKSCk%%`d(3uls&cwfuzXZM}Ba*r6@G){2MJGk}x2S4$T8#n&f z^Rpx4F8F!d#9wS&{ImM6cD?$C@4toLwEw^L;lB?j|KGBaLJio2^7l3(Pkje2BtNulO@nYPHKj03Y}CLNfDoh51*}L#}7ANo&xK&k)p2 z^yrrE6Pa4vp`MMlYjGF58Ib=LzK*);Y`F_JEPU`%cs5HEf!tJ)<71;f+KNBP3Qa!L35Gjc(x02K3!}VYv;QARGHld9a?83I?rvU1_p2z&x z+8IGsriu1_a)`tF;E5;B4EWsibif|5CeJw^@-RO)yAjxW3uO3A>q2l(eHMD^`F-JY zBG#`CzhBCYkIrtL1f#)&*2_4%nV-L0_Yx~#6pPSDa;yZk+ nt>#mCGanK4p{*p2e%LC6asFR^&;b6x2kGqC|NrOza~AkNXa-L)ixC2Ndrytc8Bzk=jX$&#=YY)N?K4@iQ%T8-tkcX!q^ zD`Vlvh>+93iQ(XwBtRh$=a7&zIV358P?8WzK1;#@=M+j~QoBu{A!*YD(j;v${oOY+ z+Li4jZc zOrm}+>?S(RjyU(4B&t4__BQZZlgOyx8v(w#0&gim({!)>_;ZR|nC?3RD!|T2O0(K6Q1NUh!K0$yguC z+@A|yLtVDhoy%=aXA6{fGqz({EhD)c1(Lje%cRl#R&)phFZqH@;M|?}4-!pYSor@c zHPNcmTwkKBBwC_P1+&?UEO@6KqGn*F%|LJ&Y+{HgheqI@u1g)<%tI1;lm6Y znrplk)6pu$!}TO|>VwKv1%2PO)#13D3`4FBZ4tK$U}6?zgu-X_cCfkdQG^xiIw-5B zQNo9r)2`u$Q2_Wvr}=)L>LYD&wqIA8O}_^x@6{W2MRfW0?1rDb_10T5_-D{3zyz1Z zlq7l|iKyaHbp&o#m&RtE)nS|NVj4##nI!1dhJ$j^j)7WZICViep*o9Dmh0~c$2A^d zeKiawXM%|hW#R%RLT^!?RVG3O>7khFw`|9tkrvYs41QEJEJjRdbP?!0X6PS}k7A>j z5wBkxet}+j!o|-2~cz@g1@vA}$HH>%bGO5jui)82y;+ zBKjf|P^HRAF3O4v-H{0doGKq?XhUQqqC3YWDtZAumz6qqPvP(oIUfhACuf7#Z3MVM zu0NZYKHsz--Vd4dU`W1Lx{;1_fzfQ}JRqk4rLCdf(H%)S}+6)6=A ztO!*Vbr{+TBZ4|s?6;dTWO|)wcU~PER@sj6pq*D&ZdX~yhF99jc+k$PE87{=E%(Q? z89iX$OXahP!#qkrW+T_^2MyCOrc{L*uIWKo@T{TB{kyFn1z8CORt!lykG?F5@(~ka zZG=ap4XQ!qxI#v`1QcXL)aoyz`=lr5fpSW$F^j1azDJt%IlzFx1jl@h(7KfTI}29%@h&G?IOpCq8zd@8W9_7y6%j^ z1`kgnBS&6_Jo5a>CC-t{aBs)Ws*pydOXOKeJUP^9j?6*M^R1d50M3_l3?h@QtN~3U zN0AF8Av@^&tThO83b2bhkpF0LMM!Y>eRH{J!^65fbArqAVMJC?$whlPRG^Z}vY42D zFmbe21e5b?HcAX7=kl*WWrWA0B0c%#6{vwnMcP`4aegb4|=t;PNAaVx!Z_KNz5U=#`y$@qVwT|R-e$@cxi}f zG5sDaL~o%krivCZtPTl1rpGiae5bHPg!NE7l*BC2SHr;+3%P5d{)USZM%$IZ!!hF? zC!}J5TL*GGqSqr`!KC#dCBicE#KPE5YyfU|0EoQZhVh{o_8AEyW`v>c^HArkK|^m= zdOc_e0xi+nNE_MT+*faGIw1;kMU0aeGv_w64vFQX+8=<8tg{QCG#5c=ccWAjZXQ^} zb0Orgnc<_D(NeMpH5hcx2i`gdU6J-WusQdYZ9<NsXM;w?6AK#j6ANZJy`p?kOg*vSV&^XfGCOo)L8J4OC^s1=7R+&86y@e{ ztm?#q=1726#i~yv-w92NdHt>;L=s_L!hYr|5V4=(N0px3f=5U|J;aOk60t*Bl7y$1 zR40+X;X}h7z?1hGbLmyc!Gw;f&9$P(SG&j*kw`^KgJ%(>YN$RmEsb${)SGK`maMn$ z7Jg+ukB*!#=x`DIU8V>8NHEjr0Y5zJ)761`bpRR{LHwm{7!+!|8Brz-(`_sjp5ujo zoR{G@uqbA;XvVF-bk^D3Axl zZ->WW9us6;WZ)nVHmvzRPl0|t$Wya1zgNTmGepc!Ip8FA?~@QRBw)uO6zdW1<@%~n z^Nm9_hN!+aysJ7?!M^4P&{3aIy&Z44(WNmJQ&Ekn#)enGfkOerc3?puW3|XW7m1nZ z+#gscmT`SG0++;aC$#A%cmjmaxyLarBu*u5F9ZV+)5;@|2)&HapqH-#Na#}z>EMI4 z?5$qxJgqVGg}helHi#)-#{|En_YYcA1w4d`c}Ix;8PDHFP)?PcY+=-8j?>WjeoX3l+fy{sO!RZ~ zao)z9J&d}6`QH1Od7HNPb~CeoAwx+!n;#8_=YViAlq1)(1z09|zbDRCT<*gSakS5W za`+(T1TWLM4Nn&21<{Ui-dRAts0*G%f1!Fk)Ukhw;a(1?)0MOpFel1~1-xCrPlFzz zuZr^b03-C0D4!Paw}4TKNi1QZfbG&IywOUD@`!*31UxL=4EiSp{Gx!*3Hob-zglJq zJ%CZ#D({q|^kG1qJ|{nd^4H|=p!`cwZc(_lL+MqbGzzGbqj1|p0v-d5(EZA1Kz~&E zE5IKKNGkI*2-qlKhk!c-+^%!&m_DiNgzW~(n*@BnfX4*9$L86_;v6rl!C^eo9va3P)hp!5>pzxfP%Ac2 ztf5`6RT8vIV8^IOZ&2!JQeb~J>oIy59=>A=+od#6<9u$%b;HU<)H;RP${hMEFq8hw z=n73J^XWT2HVAA1{n*EbLpLi(_zOJFBCv(j=wmklOA;^dEaf&}i)hft?uC@aRP?cj zfGwe;z+j827Syh zxbEE^Ms>ztWI`yLXTiW~7Z%S=b?QT)OFRh_nEll9iT#CH*x(1V-4%58i!n>S0vWZL8gzfh7M};G1kz|0VhEmW_Z!VZO( zs+*^ImeHNm2hRKOMyrt?qn*?VIEwN&C=dE$*@k1V z_Iq?IBtJ)Y)1A_bfcF57i`tv$esHqnQ&{oXl1~Gk0eoC~74UDQ0(v`)4QRQ;LSqe*Q0(_oUDJ!Ml(V)^Ug(XkEDQy5x zM7mO11PRAs;e^6=en8m*x+!gwdSUY}X|D89|bFa8ker z1pK;yrv)U5TPYIjG6kF`;OFHhq9-5@m%+9qXskk86yVxf+)Xc)T8`6lnshvHrC<<%^9N}Eev2P z?iiqiIjMo(0BBGg^R$){fHJZhA79n%$CbpnNrp+xGkHkg5_j0)HyOjU3TH1<&kQ6vpzFlOE1l(A1JC*$#CICE)j1HfBq{3d`}#Tu%MN`(O%< zS|xn59V?We!etx4=-N4pb~@RTwIy3XzicO;F41-;E4Wjcy;k00z6_|H&M34ON%O&E6Aba?zt+cVjxUf7C(8Mqm)vVpuR_BmG6V zitQ{L+*8QdLOlCo`{0#rw8<**K)BRdELxCI=4FWwyB znJ&;^rr4Fsf-&e*pH*r}*_r)T$)&EG?RwI>3vMdC$J%VW-oOmlFdPBb6NDR@U2i-4 z5d~H{&u03i;2}b^rMI6_Zf-hFD6}$T7}as=94qaGF_{_4b#$iNP(Uvjwbv zg%Rse{~k(>4ZGqDPlHZ2FS{m(67CO2^Lols>zZ8Y>ntg4RgcvB7ld8_VU&)b6ZXj{!_`$_aYuFo;l;G{b^qV5lP8V|mUg+h52&JHa z4C06Pw7I!fWGgg*Q?Ihd*Jp-?Itz9og;{Eix6;~PcLz_d>GWl^cKx2Ap>%$JCXJlY ziV?Kn6%owcHd%*?NI=#Ir86aDQ`&>{Nsd(_!Qk%1$fVK-twEd8uIPV;MvzV6YK#U< zfgR)^caU4;@e0TTc+*tkWGLe2dPuRyN~r-b_KoqB@fv&mp#6~1i)539^*30oa(Z(b z7HPom9<0MSAx%!%-nGrQ9)-N076uU+Ew_T3yQ6+0>n|Wr7O1}v;<@4}TIAU`$ zz-+~Sz^i1pBAJ~_?(ydW!U!R`jKOjSE3ldsc+HyL$Uc{l*_+1BqA+T03nJ99GFBD~ zB>SSG;}`1mIUSzrET>o!12;58UHyH1JzayneVeF%pr?|{Pyq$r$4)~?5_LvrE==OR2-;4?%Tl3Xi4oEsm^mXIb&Sl5P; z{ikM}wa4G2O)+*`ZpO)q?M<0Ikb?2vlN}xNb`=+@&KJ{#@$)O-=aI2Y>HLZ=yEyJ- zNB3T!3R8Z>%BP+E4KIl}Uci;FN(}GMwd|YPmMZBta@1DOcgk8$J!~g^Lio zNLO6i&tGm58BxyR-M59hQKqFf<9suSlg{NhN4MZMakq-+PSj)HOg3di`x5E~$N`S+ z3}`mwm^d$;r)R--d_NckXBzq~S`DuAWzoVeNGRYBK?aFgfids&)|A=_8<^e$iLBj0 zxdSJ9mv%ry4lPGSeJ^AkoT8X?82y+4FX9rsMIqls885z?P0%em1gfXq@@05!yn3Vs z*fl03GC$kk*ROcHy1X{aU0pFf%=wDO3XV#M>X zmZOKQ1^=SJw&`P&LM_K$g~u`hXJs!kkY&Rbucuw`29GeeWql>s6(ES=#@2X7#^4J>}Uo-G;X}!+5S|aA!pvv)w#$K~!^Q$ad)YIi z!1tnN`fA77EU?)? z)OhTMckj4p<>^}uQ%=YUN=Q?bP+dH%M59qzk7}kQB}l7_*GL*(w`q!MN`|4CvSAp& z6+I54a8=+7t8;dF!hL>ycPX1H$crQ0eK0op>5!=yO`2igi8dGm*p7k0g)hATG6Mx*@&W$gr#eY^$B*B6Fdg`|ROd3h zHWlwE7d8Cnt!JM;_M0WoeDELBCpT!v^VUNj%Q&C>_1|9htNYCVsQP+w-@o5-JoHoz zx>t^bC~S`gVNn~6kRlt32sgw`rqZ`AeX$;V^0z}Crn z1dlB4Jnk{vGjVUn-GdvkfQX91tZ22VNzr&uyb*srHKq=7fQeY^5fG70v05$yhU7*l z!7{9e(1my!Jw=$;h9cYt1Q-4pQ3Df1iqQ}FyU9CroG2Zn^Uie z`2TK+_XlRid!$xqc_!zV%hS zbj5oH`+AqfJv958+l%&xyN-Rb?$sZzdo=e*-LntRId#YLPd@kFWr?rd@r!3)`G+Hk znFl^seZ_Bk8=AA5Yo2&@bEfsSfBN``uKe(t*IrnzBoF+n`yc;u+25NV`G9*@*L^DdwWgN*Pk;94$t6Fz_lx^J^_N>8oq6Q0`Xkj3-1+*++V^yv za(-p6T(bMwp^e8&FKmD9?>Z0sfT!aBU%~_YYZ~$Uy~*hg;UOiQkmx)*^KHhxYd6s? zoZ|fJ7G)($JFw0T0ruc)YYMyaetf4J!m|&*tLhh=UsZo`*89pM;VTc5yeEFtEH0!) z|9g#3z@r!E8H{VJcemjdHmjRTo2IG6CLou~s} z=_Gue#Fqxt<%HHE^m+S4-e==CrhsX*;nSTbkI#2}_6zJ_&+-Y*!IPzwEqS|kY(`W` zQzO+4S$u9~D~gaDc#P-|%j4i%0Xd%Uc+bdo@ed3;;k7QB2bdLJ<#-6{%Oh{1e|x}_ z#(n<&`}{MBw{HwiV^D)J9xLzh=s64J- ir1RU8JY+dI^Rib6{d^l2nDCQLk~uj4|N1}Yf&T`O650{~ diff --git a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 962b537401fdaa7afcff07cdc9cad133ba166dbb..936a5130484fa755e88a1a012a8e99fc71c080da 100644 GIT binary patch literal 14194 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 literal 4763 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 - - notify-sharp - + - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/websocket-sharp/websocket-sharp.pidb b/websocket-sharp/websocket-sharp.pidb index 49eb985da4346aacf1bb0970c64e3e9bf420a8f4..6174b8d3549e987dcefeddad94c58f87d9e70521 100644 GIT binary patch literal 33247 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 diff --git a/wsclient/bin/Debug/websocket-sharp.dll b/wsclient/bin/Debug/websocket-sharp.dll deleted file mode 100755 index d89cb9274607886e02c9910191d4bca37d78360c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15872 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 diff --git a/wsclient/bin/Debug/websocket-sharp.dll.mdb b/wsclient/bin/Debug/websocket-sharp.dll.mdb deleted file mode 100644 index 6bad58473dff7d025b2d3e90d0328437a7947bf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4763 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 diff --git a/wsclient/bin/Debug_Ubuntu/websocket-sharp.dll b/wsclient/bin/Debug_Ubuntu/websocket-sharp.dll deleted file mode 100755 index 169f41039300b2b0bc33c2549d964e465100581c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15872 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 diff --git a/wsclient/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/wsclient/bin/Debug_Ubuntu/websocket-sharp.dll.mdb deleted file mode 100644 index 962b537401fdaa7afcff07cdc9cad133ba166dbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4763 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 N?G+nLiX2{qegdg!9#H@Q diff --git a/wsclient/bin/Release/websocket-sharp.dll b/wsclient/bin/Release/websocket-sharp.dll deleted file mode 100755 index 0ab8c1670c6df0b9b99711ad0e9e9f28443e7e47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14336 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 diff --git a/wsclient/bin/Release_Ubuntu/websocket-sharp.dll b/wsclient/bin/Release_Ubuntu/websocket-sharp.dll deleted file mode 100755 index a8ac04500e5ae3f9eb8b5f678c46768d239951ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14336 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 - { - ws.Send("Hi, all!"); - }; - - ws.OnMessage += (o, s) => - { -#if NOTIFY - Notification nf = new Notification("[WebSocket] Message", - s, - "notification-message-im"); - nf.AddHint("append", "allowed"); - nf.Show(); -#else - Console.WriteLine("[WebSocket] Message: {0}", s); -#endif - }; - - ws.OnError += (o, s) => - { - Console.WriteLine("[WebSocket] Error : {0}", s); - }; - - /*ws.OnClose += (o, e) => - { - //Do something. - }; - */ - ws.Connect(); - - Thread.Sleep(500); - Console.WriteLine("\nType \"exit\" to exit.\n"); - - string data; - while (true) - { - Thread.Sleep(500); - - Console.Write("> "); - data = Console.ReadLine(); - if (data == "exit") - { - break; - } - - ws.Send(data); - } - } - } - } -} diff --git a/wsclient/wsclient.pidb b/wsclient/wsclient.pidb deleted file mode 100644 index 3175c85f9a2693f94c5aa49a42be0e450bed19e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3211 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 fQ3N{Q18S diff --git a/wsclient1/bin/Debug/websocket-sharp.dll.mdb b/wsclient1/bin/Debug/websocket-sharp.dll.mdb deleted file mode 100644 index ca151b40ec01094d51fe86deab6c50975a2ab456..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4767 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 diff --git a/wsclient1/bin/Debug/wsclient1.exe b/wsclient1/bin/Debug/wsclient1.exe deleted file mode 100755 index cf137213e1b95a5a931c7305b460ee19acafc591..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4608 zcmeHKU2Ggz75-+kyYX)7jn_$$E1WQPQq@hHt?eW(9x6mBeJE;G3GpNP1bLz_NUhWtcz_Cc2rmfLeCN*o z*-iovJOOt--`w+i&pr3td&d*cehb?GMER_*18?&!Evxa~utss}Q}3kkX5v=Q+s62< zp6Nx~H>;kz;8_*3XgQ7>m<45eOO9zf=ICVJthgnWX>U*Nuem;x1ICSQ_tcfYaySg=LK}=zvjC}iUM1g2~0{S3p^@`*xcrT z`!@6b4Z6bw+FJBVq@Qk~Gl5zTNPm_QpOqgsghh1mgetRB^^p*4XLm+|Grh4gi=;=&9ksHzun^? zRqqi(e0y8Mry#j2YThQdkIs_b5lZ@G3$*Zx!ejoDeXOkHu2?$e*}`H8C6CbxM^l7! zG#zufbCO4YvA(|k!A{LOMl(v>9pt}%fc@d_utdJe{&_yX=Oe1pSabE!4-9%Qv%js6 zb(IvmLGRWEI^*%s2qP7-ZYT4nP8xcZ!+N|lnCZ_P>3@9iaS_K*CEjEj_pNe|Fk!Dr zKOcCuv%rCYH#rwsseNbjc%M0Vjl6v)%Wi@1=Qt55>wQn19UJAl-sr-ZxjzEgPW8H{ z3v}|KOxGD*Y5Dzpiw}{@BXZymwTR=~ifP2Lmzcz7cseBUMPeL_aEaHo^i_>N(|Fbp z{p-dnJhOhR@i!X(q%j&1{vM4-HRdB1BXPVylyN^0;Mnr(z&~)C8Ipb)QR5VGmvNfd zt8svwk4(|O-qoeGZfojAWQ{4(yL(0U0!|t8oRwLlibjR=@2^o+QgLK!)D>#VIb|Tn zR2Y~gMqst{oxAicBLRsaO-$hdjXlIYco=JV1Os>;{luFZzl$R{hS&M@;2oU6Fn z(HX@vv^s&$YP2-k8ZT;G(RfYc4WhyM3HIQJcoi93fKT-C72*|*U)A^xjo;Duvc~V@ zIgTqrLyvHSrvS@ctHgR{YA^GVnX@8wV*cW%&0*TdcgT(Zrr>s)VdnTl~myjiMkNhht+!Hwi0=qttYcqj}>_jqM?wm(eUurOVyreJ^-(9oi%y1^j~`@X6a z$}7`$P*%eMkD0NE3lDt`Gt?*`ugANp7%32ONKSy*8230huZgjerjk%Pyd%g5xe#p159jOc9m^;q~(X~JlG>&u@%_rT!~ zZ^X=q(cRT{Ztjh*cjbPtx7~~zsZ?j8vz@<06o%0zkm4PeiXjq7rJ^QDc8yf`ws>cP zPdm>LV^6AmJITFs$e)8wxAAS3eBhTMhymsVkf4wbs_il0n@tYVtz&A7*49x9TzNpD}?fES5 zUdz$=UgR*j=eV}B#2lvB8{^8JCOt-cl6`4EjsE51@ccCJ?n_ts2@<|fXlZzFx46|@ zx%UlvwYZK?vf|2IoiR9==gLakuW$QlN-c7I%B5OuN*yf+-iRKiQ-d)D)UwH6xPzw- ztrOP0;9=G(bHE#GCvDHr(q)A%ajyi7Mv?X#qYSWe`}rK=jrVEZef8cT?>uSyd5;(v zp@#~qUE*9}RxDCV%gu()#&I_5^l3liv|6BbS$nL~m&|H``&9nN5MM*QqYa&EP?ILeo?_CSa`2KY<*VT&ojFRW{C4EI< z77;xT%TZ7N>0ZC$3P)C8V9E;4!}1Acmou!RDN|hf*y)-0Nq@D I6B&R%04WzimH+?% diff --git a/wsclient1/bin/Debug_Ubuntu/websocket-sharp.dll b/wsclient1/bin/Debug_Ubuntu/websocket-sharp.dll deleted file mode 100755 index 7136652b6633f58c058e4b1f6b4ccb148318ad00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15872 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 diff --git a/wsclient1/bin/Debug_Ubuntu/wsclient1.exe b/wsclient1/bin/Debug_Ubuntu/wsclient1.exe deleted file mode 100755 index 20fc61d8a8b82e8b47766a2a8b25fdadde2aeaca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5120 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 F{|0!5)?xqv diff --git a/wsclient1/bin/Release/wsclient1.exe b/wsclient1/bin/Release/wsclient1.exe deleted file mode 100755 index 425622337393861aa1ff36cdb2c7c609b908a366..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4608 zcmeHKUu;`f8UJ0^b`y7T*F>S{jpU#;Tx2Vz`9f^Z=*XOgqq_G2s&irArG1^B+ z8oP`*kRV3_lV;YR4Brx+$ycN)Zm3}`& zR^GoscbY(3i(ZlRb1if_P%8oHkJ|~9>A7+~t<3}$(w^@X$kefA*pZ2D35e`W+EZnh zidwWl9r4Afx3&y$x|Npx`k_vf{Ee0|!|vt!Tc~sF%Y5$N=EqzwyP~En+d;)IxSmq! zV!4clr*Pg8#4y_j+}Q~jbj0xD=Sgp@+x?yYN4fhW{Tw=R_|pRk{EePTq*e*hBdNWg z#JTu!pJ64|gr)h3Rnno9amIbBB-Vtb`MXw0htk-FR9Kq-$SO@jDJ!||Sy-Ci;c<|v z_XHunv#s5yAh9QE-Xpi4&Jx}+O8R9BwD1bTWBwBTtgOVISSse(!eR*}PS6U+lY~?> z6?3_B632hDzP|q9Zp}JDGfLcDczWn*5ywy^-eDRKta6VqVQ)x3 z7kIW);=sULoQtf~feSf&z#P0m-htC)H_!JAoQRb5foCsFjPu=SbYaXr8i8!5M%~i| zy7*A0>x{0n{87Hehsfm-Iq>It#BpxL6yn%VOyKi89TNBoF^(m;#M@f>y2f8=ykLm_ zZR7hqvwo`acN+hqF&Yv6K8?pU<|0=kalA~FaX%E`*z)VdKX8v3l70$N<1BHHagNxh zagdykP0_#I-L19mY3h5(7&D~z_KECeoHZ6XE3-}&j0)#JP^YS-;>gsg8`P9@%0QN> zFfdPyz-s9`59nJ)J0yk_F^R`C_7eBuajfA94C31uAl}jV102H%{De<0-oYu1;5$@HLawY-6=SaByJdwr&koe2?bLgip^YZPod>r%pS`+lmF=L0 zoN|ho7`OeZ>sxsmhh2s1exYnL?m>)9xy9wOI@x5U)rvxP#i~?ka6bG9z{ttP`FX2y zuwWII)WBwvPFkfyo5`clSBmBFP#BT!$;$lvK$x~sVY*OF!5}MOLyMjo21haK`>K*J z*JkaYtVRPKGx_B}HL^9M7Ry{3+jTY+$CY33?5gmZ>J2Z<=AvC%_N)hqD^<&>ZMS1S zipzyyyI{<%);znkbRW^IXBAb&@~$+kW|p16uBb7W!vuETmep!X!}?0smC~YRv$}H1 zyJi=Z&r%2(&nic82CCRJ#pBnR!DsLke`Th&0E=%q@q7g2ALlNX-%~t73*=km;z$Cs zsPQ~kFwsX`flYoNseqQ|1}80_H?foCpuM4m&wdGW)W{>J$GgIQfG<;LT6=Uz7rCb~ z_#nM0YWVzFD6#hpEpITwn-8(b!sE~7WAfKx@xWNdbT<4(Ec~c6VYL1HYtLVNZ1|%W zV`jwY>2ABY@a9Y1*&priFylrt+11|F!C!k6hS4UF`5jKv^V!1VuqY9`{jz5jeKg(v#RG@C%aNmx?;Ke z-Rr&)6{V%Wzx&!BpT9YA>+;wy_WsPSiQU7S+(7&$1`qH}O$GyVyPYp;@?Co=1H9LA zG`<%ZCif!OcAl8U40{t?*>j{Ph-cWB_RHvBKMBuI1Mk0blb;~r`;?Z3_jZe0&6RuK zpjV6Qc!m{M=ITtq!6H{y+ChEW&r)iU>r*b(YE$ZHIq+t5m`)AG6i~}1zjPl@omwZX zd%l51^-Io-#M_EgyLjQ%2{pv4UGO z$Zh;DayYK%G+m#otfFL~;ZLYAo7>}R&h5!9`3tM2$Ve-+_w?5VL)G!h`@gQ4;Wv6j M3j6=tCVodc^w>1&1mK6Hq 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 QjM{%a@Wy_>{oiHa-@Y-bHUIzs diff --git a/wsclient1/wsclient1.cs b/wsclient1/wsclient1.cs deleted file mode 100644 index edc78115..00000000 --- a/wsclient1/wsclient1.cs +++ /dev/null @@ -1,65 +0,0 @@ -#if NOTIFY -using Notifications; -#endif -using System; -using System.Threading; -using WebSocketSharp; - -namespace Example -{ - public class Program - { - public static void Main(string[] args) - { - EventHandler onOpen = (o, e) => - { - Console.WriteLine("[WebSocket] Opened."); - }; - - MessageEventHandler onMessage = (o, s) => - { -#if NOTIFY - Notification nf = new Notification("[WebSocket] Message", - s, - "notification-message-im"); - nf.AddHint("append", "allowed"); - nf.Show(); -#else - Console.WriteLine("[WebSocket] Message: {0}", s); -#endif - }; - - MessageEventHandler onError = (o, s) => - { - Console.WriteLine("[WebSocket] Error : {0}", s); - }; - - EventHandler onClose = (o, e) => - { - Console.WriteLine("[WebSocket] Closed."); - }; - - //using (WebSocket ws = new WebSocket("ws://localhost:8000/", onOpen, onMessage, onError, onClose)) - using (WebSocket ws = new WebSocket("ws://localhost:8000/", "chat", onOpen, onMessage, onError, onClose)) - { - Thread.Sleep(500); - Console.WriteLine("\nType \"exit\" to exit.\n"); - - string data; - while (true) - { - Thread.Sleep(500); - - Console.Write("> "); - data = Console.ReadLine(); - if (data == "exit") - { - break; - } - - ws.Send(data); - } - } - } - } -} diff --git a/wsclient1/wsclient1.csproj b/wsclient1/wsclient1.csproj deleted file mode 100644 index ea2c1449..00000000 --- a/wsclient1/wsclient1.csproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - Debug - AnyCPU - 9.0.21022 - 2.0 - {B0B609B7-A81C-46B0-A9B8-82E9716D355B} - Exe - wsclient1 - wsclient1 - v3.5 - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - true - - - none - false - bin\Release - prompt - 4 - true - - - full - false - bin\Debug_Ubuntu - prompt - 4 - true - true - DEBUG,NOTIFY - - - none - false - bin\Release_Ubuntu - NOTIFY - prompt - 4 - true - - - - - notify-sharp - - - - - - - - - {B357BAC7-529E-4D81-A0D2-71041B19C8DE} - websocket-sharp - - - - \ No newline at end of file diff --git a/wsclient1/wsclient1.pidb b/wsclient1/wsclient1.pidb deleted file mode 100644 index 21166ed030adebd6b886f4316406f041aa2d5a33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3216 zcmcguTW{P%6t)xFYj0BOmP@&WvMrQyN$gE1AZ--dbd$7Eb5pa8kfJKgIu7ZgeN54c;mlN&Np6fvsE^PfH=~eIWsuKC!f(sj*+u<{AJm5WP?XalJ zrOUtVvM9`Y1(&9cX{I?gVcVK^=k_a*IYG!70~*KD1&Lu9gs!YHnUSn;zrp0;S}3zd zddL%Lne?%EgNuXeh(*NJmDR7;muqwLjm@Ra+U)%O#rgx99&IdbZY64HrWIgFW zV*>> zwZsbznE9l*S`>oy;7{1s+>;bI)?P@_C+)qXJhVtf+g6gG5^kA95W4GWk}mNh9;F=$ zRl!Y&`26^8;R0_djlFFyLJFW~3<2$Ju$apZ3;1%9i5^bcL7HUb7HJ`llgvnnW!%tD zdi5Y1&UYQ2kKw>8<+1_gPQ3=q|8>$KhV!Izh;r0YSH7YpvJyCFP^pPXD7$b0hI0W3 ziR)YhatW2oIuwF7I1je`{3W8C%UHU&OQqnzT~N8tXL@^Di^c zh3a^d^E%KQgj{G0aG^E8guXXN2G>L0;uJLfa6*hu>@%vDO!7w})Zsr11*2NLzXnm2 zIqwVa%bMSn!jHnHAJd*c=T-fF0p5=y9VW)z)|-Up&UQSOK`Ka~2LW)867UugcTW{S zb;(cCENu1iQZ-ZcZVhcHfpE1F_%;zc{T!>E*_AI>!{Iggv_pl{MaaO6);olXy67T? zuU5>vjk2!b3kmOLf<@Dnt!^_418S_Q`z<8hD0=)@RT8Ar_kaBA{&Md()fyZW?Xr$w zR#A;S(b~z+zZc)H(%N~CkPcg-06G;QMZxF>B>Z@qqW`m=cv-(U2AVwLrfIyW4>wTh%UpMTQ z%?}8lM=yvi9pTS)Z%@03n_Mcx<_#jwpzhFV8>g{jet7EXLN!#Fm+nSSHE$9+n{kE& zsO#ydrdJ3Rof&i9nLi@R`54R6HNxtpn2o8?j$m!*R8m=k%K(4R@8T-3Tb~dr{N&