From 64ec8cd4f4813644de7a0333326addb14e1a212e Mon Sep 17 00:00:00 2001 From: sta Date: Fri, 15 Nov 2013 06:21:00 -0800 Subject: [PATCH 01/27] Create gh-pages branch via GitHub --- images/body-bg.jpg | Bin 0 -> 3188 bytes images/download-button.png | Bin 0 -> 31731 bytes images/github-button.png | Bin 0 -> 3219 bytes images/header-bg.jpg | Bin 0 -> 10442 bytes images/highlight-bg.jpg | Bin 0 -> 34222 bytes images/sidebar-bg.jpg | Bin 0 -> 3200 bytes index.html | 508 +++++++++++++++++++++++++++++++++++ javascripts/main.js | 1 + params.json | 1 + stylesheets/print.css | 226 ++++++++++++++++ stylesheets/pygment_trac.css | 69 +++++ stylesheets/stylesheet.css | 479 +++++++++++++++++++++++++++++++++ 12 files changed, 1284 insertions(+) create mode 100644 images/body-bg.jpg create mode 100644 images/download-button.png create mode 100644 images/github-button.png create mode 100644 images/header-bg.jpg create mode 100644 images/highlight-bg.jpg create mode 100644 images/sidebar-bg.jpg create mode 100644 index.html create mode 100644 javascripts/main.js create mode 100644 params.json create mode 100644 stylesheets/print.css create mode 100644 stylesheets/pygment_trac.css create mode 100644 stylesheets/stylesheet.css diff --git a/images/body-bg.jpg b/images/body-bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0e0f861ba5b4fe8f3cd97b1ac83dea17a97a357a GIT binary patch literal 3188 zcmaJ>30M=?7QQo+NkS4r5JAO-F`^(s79cDU%wPaFP+TY!5rQE=iX<@vS=?r(mF6h-Rfsx05m!(aHa zYQg*$No8ke3$lF#T79Ze92gil%;D|rWwr3i%+(l@a=bK|Q(iKJsxp;&wa%c{YOrC( zq?Ot%LonYO>0c>i=w8wOW3B#X7#aEhO*1lv3ot^PX;`9q9q&I9XD-Xtsf0^Znc6J9 zQe`!tG7Q#9<$6_;L91V;)vkJ3#i%r`L7SPT)nW3bewe%1M<5z0p2$Ze5o8E_#gZ4b z^bv|AQg5+TB(gr!G0Z(ONvYNhW2cXhM@CBLX)+B-8l`GpXfWUEPM}sNOT$A#L&Lp& zy!|EeaIrW{JUcYRCoIfY;_oe&NPNTPFR`IoWmbktV|a;8evS2cD|WbVGIUnYp(?$4 zjVd`@ug$LXRZJr>bh`Ced?-yVzjtyrNo7~yai{H-fqZdqGxc=@Wwt;(w@QE9BB zp|{R}qrOa_B)W5Z(E*l^wy z2tg2(hT72SHnwaVwyho4Dt2}wMlU{`zqB`TuQUqHlfbAi~9;>9U7!AnBtbX3>6145Lr)!w#a#b$!Vi(Hd@7lx#tv-W@=Ns=NY@`d?QMRi7K-A*ZS?QS_aVSRv;ypG4+ z?cFkKJ8j(chhV8&K|jw`+j)oi6LU6_ASGvYq@eRF0_J1U-u^Ac_ygyg#2NXX07! z_bK4BKj21p^{73@QT0taPk%F99$`?-Df|x-f1?lbID<*C)ocRH!) zAqA@?u*<|PPL1bc5qTcO&ztx7gB4BdsMX)XG*7S9FnF}D)##Xy-m$sYkK284hc@YB za1(1S;!TR-IUdI*ZS94hYkxI4d8N>1%-jZcBY?0oSY9&QD3N!Z=cvxF?oWCl<8R7OxoMpbc}l zL-l}BSa=_ve>R@lSHax((34#nJEnwOv$~osf*ng+&3FWIj5C(8d(p*~_iCIcP!*ri z!HK46v`RO5^nDsH4XR}oEYi6i3E#}z3L2bAMMi5gVssc=cb~R*p<>2$=<+guxbGZg zQW00c>l7$(h^{a>hw#i!5D2`n~gv(`EK$(l3CNl&mFZj*g&lmd_-n%I{ws&5nsj;Hi@2cC`IN4>bF@ zB0i-IdyhV^k-6E0jMpe<47Q|iuM#2K&kkYWk9WQHeF05Ih^va}C25cF-5XwroL2yn{ef{jk;fCm zc|X-MKUq!@lOJLb>sqq21X}edD1f_w+_Axpd6?0KEMQNh>@Mv4h%vM<8|vsMLC8+x zx%L4hs|C72MbH_Bx`WA0`@9i+Y%}I`k-b|HZ}uS$?#|evv)^t*RA`<+W1a4RdRmjn zvwHyjvURMAYou^bC4*I)B$iJvM_2= a0v2=O8*;~w+wK-QqIt&}ZG8~S%|8KWPLbRI literal 0 HcmV?d00001 diff --git a/images/download-button.png b/images/download-button.png new file mode 100644 index 0000000000000000000000000000000000000000..df3f09a63a211e698b43cfdbd51a1f3c2c6c4b96 GIT binary patch literal 31731 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 literal 0 HcmV?d00001 diff --git a/images/github-button.png b/images/github-button.png new file mode 100644 index 0000000000000000000000000000000000000000..efe07f9ad2d7b2b1cf47139223cb874ef2ee51dd GIT binary patch literal 3219 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 wM@^Z%c#pr@F5B46h4YIV^>|0=nv8djYW_Vxb5~ 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 G(W(sMe`~M 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 DGStm7 literal 0 HcmV?d00001 diff --git a/images/sidebar-bg.jpg b/images/sidebar-bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..42890fe73838b8dd1116757bc048d8bc6eed6e29 GIT binary patch literal 3200 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 MjbhoBxZpqk3)=H0UjP6A literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 000000000..ac3d2ce51 --- /dev/null +++ b/index.html @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + websocket-sharp by sta + + + +
+
+

websocket-sharp

+

A C# implementation of the WebSocket protocol client and server

+ View project onGitHub +
+
+ +
+
+
+

+Usage

+ +

+WebSocket Client

+ +
using System;
+using WebSocketSharp;
+
+namespace Example
+{
+  public class Program
+  {
+    public static void Main (string [] args)
+    {
+      using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa"))
+      {
+        ws.OnMessage += (sender, e) =>
+        {
+          Console.WriteLine ("Laputa says: " + e.Data);
+        };
+
+        ws.Connect ();
+        ws.Send ("BALUS");
+        Console.ReadKey (true);
+      }
+    }
+  }
+}
+
+ +

+Step 1

+ +

Required namespace.

+ +
using WebSocketSharp;
+
+ +

The WebSocket class exists in the WebSocketSharp namespace.

+ +

+Step 2

+ +

Creating an instance of the WebSocket class with the specified WebSocket URL to connect.

+ +
using (var ws = new WebSocket ("ws://example.com"))
+{
+  ...
+}
+
+ +

The WebSocket class inherits the IDisposable interface, so you can use the using statement.

+ +

+Step 3

+ +

Setting the WebSocket events.

+ +
+WebSocket.OnOpen Event
+ +

A WebSocket.OnOpen event occurs when the WebSocket connection has been established.

+ +
ws.OnOpen += (sender, e) =>
+{
+  ...
+};
+
+ +

e has passed as EventArgs.Empty, so you don't use e.

+ +
+WebSocket.OnMessage Event
+ +

A WebSocket.OnMessage event occurs when the WebSocket receives a WebSocket data frame.

+ +
ws.OnMessage += (sender, e) =>
+{
+  ...
+};
+
+ +

e.Type (WebSocketSharp.MessageEventArgs.Type, its type is WebSocketSharp.Opcode) indicates the type of a received data. So by checking it, you determine which item you should use.

+ +

If e.Type equals Opcode.TEXT, you use e.Data (WebSocketSharp.MessageEventArgs.Data, its type is string) that contains a received Text data.

+ +

If e.Type equals Opcode.BINARY, you use e.RawData (WebSocketSharp.MessageEventArgs.RawData, its type is byte []) that contains a received Binary data.

+ +
if (e.Type == Opcode.TEXT)
+{
+  // Do something with e.Data
+  return;
+}
+
+if (e.Type == Opcode.BINARY)
+{
+  // Do something with e.RawData
+  return;
+}
+
+ +
+WebSocket.OnError Event
+ +

A WebSocket.OnError event occurs when the WebSocket gets an error.

+ +
ws.OnError += (sender, e) =>
+{
+  ...
+};
+
+ +

e.Message (WebSocketSharp.ErrorEventArgs.Message, its type is string) contains an error message, so you use it.

+ +
+WebSocket.OnClose Event
+ +

A WebSocket.OnClose event occurs when the WebSocket connection has been closed.

+ +
ws.OnClose += (sender, e) =>
+{
+  ...
+};
+
+ +

e.Code (WebSocketSharp.CloseEventArgs.Code, its type is ushort) contains a status code indicating the reason for closure and e.Reason (WebSocketSharp.CloseEventArgs.Reason, its type is string) contains the reason for closure, so you use them.

+ +

+Step 4

+ +

Connecting to the WebSocket server.

+ +
ws.Connect ();
+
+ +

+Step 5

+ +

Sending a data.

+ +
ws.Send (data);
+
+ +

The Send method is overloaded.

+ +

The types of data are string, byte [] and System.IO.FileInfo class.

+ +

In addition, the Send (stream, length) method exists, too.

+ +

These methods don't wait for the send to be complete. This means that these methods behave asynchronously.

+ +

If you want to do something when the send is complete, you use any of some Send (data, completed) methods.

+ +

+Step 6

+ +

Closing the WebSocket connection.

+ +
ws.Close (code, reason);
+
+ +

If you want to close the WebSocket connection explicitly, you use the Close method.

+ +

The Close method is overloaded.

+ +

The types of code are WebSocketSharp.CloseStatusCode and ushort, and the type of reason is string.

+ +

In addition, the Close () and Close (code) methods exist, too.

+ +

+WebSocket Server

+ +
using System;
+using WebSocketSharp;
+using WebSocketSharp.Server;
+
+namespace Example
+{
+  public class Laputa : WebSocketService
+  {
+    protected override void OnMessage (MessageEventArgs e)
+    {
+      var msg = e.Data.ToLower () == "balus"
+              ? "I've been balused already..."
+              : "I'm not available now.";
+
+      Send (msg);
+    }
+  }
+
+  public class Program
+  {
+    public static void Main (string [] args)
+    {
+      var wssv = new WebSocketServer ("ws://dragonsnest.far");
+      wssv.AddWebSocketService<Laputa> ("/Laputa");
+      wssv.Start ();
+      Console.ReadKey (true);
+      wssv.Stop ();
+    }
+  }
+}
+
+ +

+Step 1

+ +

Required namespace.

+ +
using WebSocketSharp.Server;
+
+ +

The WebSocketService and WebSocketServer classes exist in the WebSocketSharp.Server namespace.

+ +

+Step 2

+ +

Creating the class that inherits the WebSocketService class.

+ +

For example, if you want to provide an echo service,

+ +
using System;
+using WebSocketSharp;
+using WebSocketSharp.Server;
+
+public class Echo : WebSocketService
+{
+  protected override void OnMessage (MessageEventArgs e)
+  {
+    Send (e.Data);
+  }
+}
+
+ +

And if you want to provide a chat service,

+ +
using System;
+using WebSocketSharp;
+using WebSocketSharp.Server;
+
+public class Chat : WebSocketService
+{
+  private string _suffix;
+
+  public Chat ()
+    : this (String.Empty)
+  {
+  }
+
+  public Chat (string suffix)
+  {
+    _suffix = suffix;
+  }
+
+  protected override void OnMessage (MessageEventArgs e)
+  {
+    Sessions.Broadcast (e.Data + _suffix);
+  }
+}
+
+ +

If you override the OnMessage method, it is bound to the server side WebSocket.OnMessage event.

+ +

In addition, if you override the OnOpen, OnError and OnClose methods, each of them is bound to each server side event of WebSocket.OnOpen, WebSocket.OnError and WebSocket.OnClose.

+ +

+Step 3

+ +

Creating an instance of the WebSocketServer class.

+ +
var wssv = new WebSocketServer (4649);
+wssv.AddWebSocketService<Echo> ("/Echo");
+wssv.AddWebSocketService<Chat> ("/Chat");
+wssv.AddWebSocketService<Chat> ("/ChatWithNiceBoat", () => new Chat (" Nice boat."));
+
+ +

You can add any WebSocket service with a specified path to the service to your WebSocketServer by using the WebSocketServer.AddWebSocketService<TWithNew> or WebSocketServer.AddWebSocketService<T> method.

+ +

The type of TWithNew must inherit the WebSocketService class and must have a public parameterless constructor.

+ +

The type of T must inherit WebSocketService class.

+ +

So you can use the classes created in Step 2.

+ +

If you create an instance of the WebSocketServer class without the port number, the WebSocketServer set the port number to 80 automatically. So it is necessary to run with root permission.

+ +
$ sudo mono example2.exe
+
+ +

+Step 4

+ +

Starting the server.

+ +
wssv.Start ();
+
+ +

+Step 5

+ +

Stopping the server.

+ +
wssv.Stop ();
+
+ +

+HTTP Server with the WebSocket

+ +

I modified the System.Net.HttpListener, System.Net.HttpListenerContext and some other classes of Mono to create the HTTP server that can upgrade the connection to the WebSocket connection when receives a WebSocket connection request.

+ +

You can add any WebSocket service with a specified path to the service to your HttpServer by using the HttpServer.AddWebSocketService<TWithNew> or HttpServer.AddWebSocketService<T> method.

+ +
var httpsv = new HttpServer (4649);
+httpsv.AddWebSocketService<Echo> ("/Echo");
+httpsv.AddWebSocketService<Chat> ("/Chat");
+httpsv.AddWebSocketService<Chat> ("/ChatWithNiceBoat", () => new Chat (" Nice boat."));
+
+ +

For more information, could you see Example3?

+ +

+WebSocket Extensions

+ +

+Per-message Compression

+ +

websocket-sharp supports Per-message Compression extension. (But, does not support with extension parameters.)

+ +

If you want to enable this extension as a WebSocket client, you should do like the following.

+ +
ws.Compression = CompressionMethod.DEFLATE;
+
+ +

And then your client sends the following header in the opening handshake to a WebSocket server.

+ +
Sec-WebSocket-Extensions: permessage-deflate
+
+ +

If the server supports this extension, responds the same header. And when your client receives the header, enables this extension.

+ +

+Secure Connection

+ +

As a WebSocket Client, creating an instance of the WebSocket class with the WebSocket URL with wss scheme.

+ +
using (var ws = new WebSocket ("wss://example.com"))
+{
+  ...
+}
+
+ +

If you want to set the custom validation for the server certificate, you use the WebSocket.ServerCertificateValidationCallback property.

+ +
ws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
+{
+  // Do something to validate the server certificate.
+  return true; // The server certificate is valid.
+};
+
+ +

If you set this property to nothing, the validation does nothing with the server certificate, always returns valid.

+ +

As a WebSocket Server, creating an instance of the WebSocketServer or HttpServer class with some settings for the secure connection.

+ +
var wssv = new WebSocketServer (4649, true);
+wssv.Certificate = new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");
+
+ +

+Logging

+ +

The WebSocket class includes own logging functions.

+ +

The WebSocket.Log property provides the logging functions.

+ +

If you want to change the current logging level (the default is LogLevel.ERROR), you use the WebSocket.Log.Level property.

+ +
ws.Log.Level = LogLevel.DEBUG;
+
+ +

The above means that the logging outputs with a less than LogLevel.DEBUG are not outputted.

+ +

And if you want to output a log, you use any of some output methods. The following outputs a log with LogLevel.DEBUG.

+ +
ws.Log.Debug ("This is a debug message.");
+
+ +

The WebSocketServer and HttpServer classes include the same logging functions.

+ +

+Required Environment

+ +

C# 3.0, .NET 3.5 compatible or later.

+ +

+Examples

+ +

Examples 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 the chat feature, still unfinished).

+ +

And Example1 uses Json.NET.

+ +

+Example2

+ +

Example2 starts a WebSocket server.

+ +

+Example3

+ +

Example3 starts an HTTP server that can upgrade the connection to the WebSocket connection.

+ +

Could you access to http://localhost:4649 to do WebSocket Echo Test with your web browser after Example3 running?

+ +

+websocket-sharp for Unity

+ +

websocket-sharp has now been displayed on the Unity Asset Store!

+ +

+Supported WebSocket Specifications

+ +

websocket-sharp supports RFC 6455.

+ +

websocket-sharp is based on the following WebSocket references.

+ +

Thanks for translating to japanese.

+ +

+License

+ +

websocket-sharp is provided under The MIT License.

+
+ + +
+
+ + + + \ No newline at end of file diff --git a/javascripts/main.js b/javascripts/main.js new file mode 100644 index 000000000..d8135d37b --- /dev/null +++ b/javascripts/main.js @@ -0,0 +1 @@ +console.log('This would be the main JS file.'); diff --git a/params.json b/params.json new file mode 100644 index 000000000..1de32ca08 --- /dev/null +++ b/params.json @@ -0,0 +1 @@ +{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\"))\r\n {\r\n ws.OnMessage += (sender, e) =>\r\n {\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n };\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the specified WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\"))\r\n{\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as `EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket data frame.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e.Type` (`WebSocketSharp.MessageEventArgs.Type`, its type is `WebSocketSharp.Opcode`) indicates the type of a received data. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` equals `Opcode.TEXT`, you use `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, its type is `string`) that contains a received **Text** data.\r\n\r\nIf `e.Type` equals `Opcode.BINARY`, you use `e.RawData` (`WebSocketSharp.MessageEventArgs.RawData`, its type is `byte []`) that contains a received **Binary** data.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT)\r\n{\r\n // Do something with e.Data\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY)\r\n{\r\n // Do something with e.RawData\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, its type is `string`) contains an error message, so you use it.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e.Code` (`WebSocketSharp.CloseEventArgs.Code`, its type is `ushort`) contains a status code indicating the reason for closure and `e.Reason` (`WebSocketSharp.CloseEventArgs.Reason`, its type is `string`) contains the reason for closure, so you use them.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nSending a data.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `Send` method is overloaded.\r\n\r\nThe types of `data` are `string`, `byte []` and `System.IO.FileInfo` class.\r\n\r\nIn addition, the `Send (stream, length)` method exists, too.\r\n\r\nThese methods don't wait for the send to be complete. This means that these methods behave asynchronously.\r\n\r\nIf you want to do something when the send is complete, you use any of some `Send (data, completed)` methods.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you want to close the WebSocket connection explicitly, you use the `Close` method.\r\n\r\nThe `Close` method is overloaded.\r\n\r\nThe types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, and the type of `reason` is `string`.\r\n\r\nIn addition, the `Close ()` and `Close (code)` methods exist, too.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketService\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data.ToLower () == \"balus\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketService` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you want to provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you want to provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (String.Empty)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nIf you override the `OnMessage` method, it is bound to the server side `WebSocket.OnMessage` event.\r\n\r\nIn addition, if you override the `OnOpen`, `OnError` and `OnClose` methods, each of them is bound to each server side event of `WebSocket.OnOpen`, `WebSocket.OnError` and `WebSocket.OnClose`.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service with a specified path to the service to your `WebSocketServer` by using the `WebSocketServer.AddWebSocketService` or `WebSocketServer.AddWebSocketService` method.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2**.\r\n\r\nIf you create an instance of the `WebSocketServer` class without the port number, the `WebSocketServer` set the port number to **80** automatically. So it is necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the server.\r\n\r\n```cs\r\nwssv.Stop ();\r\n```\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext` and some other classes of [Mono] to create the HTTP server that can upgrade the connection to the WebSocket connection when receives a WebSocket connection request.\r\n\r\nYou can add any WebSocket service with a specified path to the service to your `HttpServer` by using the `HttpServer.AddWebSocketService` or `HttpServer.AddWebSocketService` method.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\n**websocket-sharp** supports **[Per-message Compression][compression]** extension. (But, does not support with [extension parameters].)\r\n\r\nIf you want to enable this extension as a WebSocket client, you should do like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your client sends the following header in the opening handshake to a WebSocket server.\r\n\r\n```\r\nSec-WebSocket-Extensions: permessage-deflate\r\n```\r\n\r\nIf the server supports this extension, responds the same header. And when your client receives the header, enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nAs a **WebSocket Client**, creating an instance of the `WebSocket` class with the WebSocket URL with **wss** scheme.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\"))\r\n{\r\n ...\r\n}\r\n```\r\n\r\nIf you want to set the custom validation for the server certificate, you use the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>\r\n{\r\n // Do something to validate the server certificate.\r\n return true; // The server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, always returns valid.\r\n\r\nAs a **WebSocket Server**, creating an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes own logging functions.\r\n\r\nThe `WebSocket.Log` property provides the logging functions.\r\n\r\nIf you want to change the current logging level (the default is `LogLevel.ERROR`), you use the `WebSocket.Log.Level` property.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThe above means that the logging outputs with a less than `LogLevel.DEBUG` are not outputted.\r\n\r\nAnd if you want to output a log, you use any of some output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging functions.\r\n\r\n## Required Environment ##\r\n\r\nC# **3.0**, .NET **3.5** compatible or later.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n[Example] connects to the [Echo server] using the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n[Example1] connects to the [Audio Data delivery server] using the WebSocket ([Example1] is only implemented the chat feature, still unfinished).\r\n\r\nAnd [Example1] uses [Json.NET].\r\n\r\n### Example2 ###\r\n\r\n[Example2] starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n[Example3] starts an HTTP server that can upgrade the connection to the WebSocket connection.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after [Example3] running?\r\n\r\n## websocket-sharp for Unity ##\r\n\r\n**websocket-sharp** has now been displayed on the **Unity Asset Store**!\r\n\r\n- **[websocket-sharp for Unity]**\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\n**websocket-sharp** supports **[RFC 6455]**.\r\n\r\n- **[branch: hybi-00]** supports older draft-ietf-hybi-thewebsocketprotocol-00 ( **[hybi-00]** ).\r\n- **[branch: draft75]** supports even more old draft-hixie-thewebsocketprotocol-75 ( **[hixie-75]** ).\r\n\r\n**websocket-sharp** is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol]**\r\n- **[The WebSocket API]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳]**\r\n- **[The WebSocket API 日本語訳]**\r\n\r\n## License ##\r\n\r\n**websocket-sharp** is provided under **[The MIT License](LICENSE.txt)**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000/\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com/\r\n[RFC 6455]: http://tools.ietf.org/html/rfc6455\r\n[The WebSocket API]: http://www.w3.org/TR/websockets/\r\n[The WebSocket API 日本語訳]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[The WebSocket Protocol]: http://tools.ietf.org/html/rfc6455\r\n[The WebSocket Protocol 日本語訳]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n[branch: draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[branch: hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hixie-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[hybi-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[websocket-sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/stylesheets/print.css b/stylesheets/print.css new file mode 100644 index 000000000..541695bfd --- /dev/null +++ b/stylesheets/print.css @@ -0,0 +1,226 @@ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +body { + font-size: 13px; + line-height: 1.5; + font-family: 'Helvetica Neue', Helvetica, Arial, serif; + color: #000; +} + +a { + color: #d5000d; + font-weight: bold; +} + +header { + padding-top: 35px; + padding-bottom: 10px; +} + +header h1 { + font-weight: bold; + letter-spacing: -1px; + font-size: 48px; + color: #303030; + line-height: 1.2; +} + +header h2 { + letter-spacing: -1px; + font-size: 24px; + color: #aaa; + font-weight: normal; + line-height: 1.3; +} +#downloads { + display: none; +} +#main_content { + padding-top: 20px; +} + +code, pre { + font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal; + color: #222; + margin-bottom: 30px; + font-size: 12px; +} + +code { + padding: 0 3px; +} + +pre { + border: solid 1px #ddd; + padding: 20px; + overflow: auto; +} +pre code { + padding: 0; +} + +ul, ol, dl { + margin-bottom: 20px; +} + + +/* COMMON STYLES */ + +table { + width: 100%; + border: 1px solid #ebebeb; +} + +th { + font-weight: 500; +} + +td { + border: 1px solid #ebebeb; + text-align: center; + font-weight: 300; +} + +form { + background: #f2f2f2; + padding: 20px; + +} + + +/* GENERAL ELEMENT TYPE STYLES */ + +h1 { + font-size: 2.8em; +} + +h2 { + font-size: 22px; + font-weight: bold; + color: #303030; + margin-bottom: 8px; +} + +h3 { + color: #d5000d; + font-size: 18px; + font-weight: bold; + margin-bottom: 8px; +} + +h4 { + font-size: 16px; + color: #303030; + font-weight: bold; +} + +h5 { + font-size: 1em; + color: #303030; +} + +h6 { + font-size: .8em; + color: #303030; +} + +p { + font-weight: 300; + margin-bottom: 20px; +} + +a { + text-decoration: none; +} + +p a { + font-weight: 400; +} + +blockquote { + font-size: 1.6em; + border-left: 10px solid #e9e9e9; + margin-bottom: 20px; + padding: 0 0 0 30px; +} + +ul li { + list-style: disc inside; + padding-left: 20px; +} + +ol li { + list-style: decimal inside; + padding-left: 3px; +} + +dl dd { + font-style: italic; + font-weight: 100; +} + +footer { + margin-top: 40px; + padding-top: 20px; + padding-bottom: 30px; + font-size: 13px; + color: #aaa; +} + +footer a { + color: #666; +} + +/* MISC */ +.clearfix:after { + clear: both; + content: '.'; + display: block; + visibility: hidden; + height: 0; +} + +.clearfix {display: inline-block;} +* html .clearfix {height: 1%;} +.clearfix {display: block;} \ No newline at end of file diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css new file mode 100644 index 000000000..c6a6452d2 --- /dev/null +++ b/stylesheets/pygment_trac.css @@ -0,0 +1,69 @@ +.highlight { background: #ffffff; } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d14 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d14 } /* Literal.String.Backtick */ +.highlight .sc { color: #d14 } /* Literal.String.Char */ +.highlight .sd { color: #d14 } /* Literal.String.Doc */ +.highlight .s2 { color: #d14 } /* Literal.String.Double */ +.highlight .se { color: #d14 } /* Literal.String.Escape */ +.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ +.highlight .si { color: #d14 } /* Literal.String.Interpol */ +.highlight .sx { color: #d14 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d14 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ + +.type-csharp .highlight .k { color: #0000FF } +.type-csharp .highlight .kt { color: #0000FF } +.type-csharp .highlight .nf { color: #000000; font-weight: normal } +.type-csharp .highlight .nc { color: #2B91AF } +.type-csharp .highlight .nn { color: #000000 } +.type-csharp .highlight .s { color: #A31515 } +.type-csharp .highlight .sc { color: #A31515 } diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css new file mode 100644 index 000000000..7e3b8f0ee --- /dev/null +++ b/stylesheets/stylesheet.css @@ -0,0 +1,479 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} + +/* LAYOUT STYLES */ +body { + font-size: 15px; + line-height: 1.5; + background: #fafafa url(../images/body-bg.jpg) 0 0 repeat; + font-family: 'Helvetica Neue', Helvetica, Arial, serif; + font-weight: 400; + color: #666; +} + +a { + color: #2879d0; +} +a:hover { + color: #2268b2; +} + +header { + padding-top: 40px; + padding-bottom: 40px; + font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; + background: #2e7bcf url(../images/header-bg.jpg) 0 0 repeat-x; + border-bottom: solid 1px #275da1; +} + +header h1 { + letter-spacing: -1px; + font-size: 72px; + color: #fff; + line-height: 1; + margin-bottom: 0.2em; + width: 540px; +} + +header h2 { + font-size: 26px; + color: #9ddcff; + font-weight: normal; + line-height: 1.3; + width: 540px; + letter-spacing: 0; +} + +.inner { + position: relative; + width: 940px; + margin: 0 auto; +} + +#content-wrapper { + border-top: solid 1px #fff; + padding-top: 30px; +} + +#main-content { + width: 690px; + float: left; +} + +#main-content img { + max-width: 100%; +} + +aside#sidebar { + width: 200px; + padding-left: 20px; + min-height: 504px; + float: right; + background: transparent url(../images/sidebar-bg.jpg) 0 0 no-repeat; + font-size: 12px; + line-height: 1.3; +} + +aside#sidebar p.repo-owner, +aside#sidebar p.repo-owner a { + font-weight: bold; +} + +#downloads { + margin-bottom: 40px; +} + +a.button { + width: 134px; + height: 58px; + line-height: 1.2; + font-size: 23px; + color: #fff; + padding-left: 68px; + padding-top: 22px; + font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; +} +a.button small { + display: block; + font-size: 11px; +} +header a.button { + position: absolute; + right: 0; + top: 0; + background: transparent url(../images/github-button.png) 0 0 no-repeat; +} +aside a.button { + width: 138px; + padding-left: 64px; + display: block; + background: transparent url(../images/download-button.png) 0 0 no-repeat; + margin-bottom: 20px; + font-size: 21px; +} + +code, pre { + font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; + color: #222; + margin-bottom: 30px; + font-size: 13px; +} + +code { + background-color: #f2f8fc; + border: solid 1px #dbe7f3; + padding: 0 3px; +} + +pre { + padding: 20px; + background: #fff; + text-shadow: none; + overflow: auto; + border: solid 1px #f2f2f2; +} +pre code { + color: #2879d0; + background-color: #fff; + border: none; + padding: 0; +} + +ul, ol, dl { + margin-bottom: 20px; +} + + +/* COMMON STYLES */ + +hr { + height: 1px; + line-height: 1px; + margin-top: 1em; + padding-bottom: 1em; + border: none; + background: transparent url('../images/hr.png') 0 0 no-repeat; +} + +table { + width: 100%; + border: 1px solid #ebebeb; +} + +th { + font-weight: 500; +} + +td { + border: 1px solid #ebebeb; + text-align: center; + font-weight: 300; +} + +form { + background: #f2f2f2; + padding: 20px; + +} + + +/* GENERAL ELEMENT TYPE STYLES */ + +#main-content h1 { + font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; + font-size: 2.8em; + letter-spacing: -1px; + color: #474747; +} + +#main-content h1:before { + content: "/"; + color: #9ddcff; + padding-right: 0.3em; + margin-left: -0.9em; +} + +#main-content h2 { + font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; + font-size: 22px; + font-weight: bold; + margin-bottom: 8px; + color: #474747; +} +#main-content h2:before { + content: "//"; + color: #9ddcff; + padding-right: 0.3em; + margin-left: -1.5em; +} + +#main-content h3 { + font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; + font-size: 18px; + font-weight: bold; + margin-top: 24px; + margin-bottom: 8px; + color: #474747; +} + +#main-content h3:before { + content: "///"; + color: #9ddcff; + padding-right: 0.3em; + margin-left: -2em; +} + +#main-content h4 { + font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; + font-size: 15px; + font-weight: bold; + color: #474747; +} + +h4:before { + content: "////"; + color: #9ddcff; + padding-right: 0.3em; + margin-left: -2.8em; +} + +#main-content h5 { + font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; + font-size: 14px; + color: #474747; +} +h5:before { + content: "/////"; + color: #9ddcff; + padding-right: 0.3em; + margin-left: -3.2em; +} + +#main-content h6 { + font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; + font-size: .8em; + color: #474747; +} +h6:before { + content: "//////"; + color: #9ddcff; + padding-right: 0.3em; + margin-left: -3.7em; +} + +p { + margin-bottom: 20px; +} + +a { + text-decoration: none; +} + +p a { + font-weight: 400; +} + +blockquote { + font-size: 1.6em; + border-left: 10px solid #e9e9e9; + margin-bottom: 20px; + padding: 0 0 0 30px; +} + +ul li { + list-style: disc inside; + padding-left: 20px; +} + +ol li { + list-style: decimal inside; + padding-left: 3px; +} + +dl dd { + font-style: italic; + font-weight: 100; +} + +footer { + background: transparent url('../images/hr.png') 0 0 no-repeat; + margin-top: 40px; + padding-top: 20px; + padding-bottom: 30px; + font-size: 13px; + color: #aaa; +} + +footer a { + color: #666; +} +footer a:hover { + color: #444; +} + +/* MISC */ +.clearfix:after { + clear: both; + content: '.'; + display: block; + visibility: hidden; + height: 0; +} + +.clearfix {display: inline-block;} +* html .clearfix {height: 1%;} +.clearfix {display: block;} + +/* #Media Queries +================================================== */ + +/* Smaller than standard 960 (devices and browsers) */ +@media only screen and (max-width: 959px) {} + +/* Tablet Portrait size to standard 960 (devices and browsers) */ +@media only screen and (min-width: 768px) and (max-width: 959px) { + .inner { + width: 740px; + } + header h1, header h2 { + width: 340px; + } + header h1 { + font-size: 60px; + } + header h2 { + font-size: 30px; + } + #main-content { + width: 490px; + } + #main-content h1:before, + #main-content h2:before, + #main-content h3:before, + #main-content h4:before, + #main-content h5:before, + #main-content h6:before { + content: none; + padding-right: 0; + margin-left: 0; + } +} + +/* All Mobile Sizes (devices and browser) */ +@media only screen and (max-width: 767px) { + .inner { + width: 93%; + } + header { + padding: 20px 0; + } + header .inner { + position: relative; + } + header h1, header h2 { + width: 100%; + } + header h1 { + font-size: 48px; + } + header h2 { + font-size: 24px; + } + header a.button { + background-image: none; + width: auto; + height: auto; + display: inline-block; + margin-top: 15px; + padding: 5px 10px; + position: relative; + text-align: center; + font-size: 13px; + line-height: 1; + background-color: #9ddcff; + color: #2879d0; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + } + header a.button small { + font-size: 13px; + display: inline; + } + #main-content, + aside#sidebar { + float: none; + width: 100% ! important; + } + aside#sidebar { + background-image: none; + margin-top: 20px; + border-top: solid 1px #ddd; + padding: 20px 0; + min-height: 0; + } + aside#sidebar a.button { + display: none; + } + #main-content h1:before, + #main-content h2:before, + #main-content h3:before, + #main-content h4:before, + #main-content h5:before, + #main-content h6:before { + content: none; + padding-right: 0; + margin-left: 0; + } +} + +/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ +@media only screen and (min-width: 480px) and (max-width: 767px) {} + +/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ +@media only screen and (max-width: 479px) {} From 0b23dc202f257caeb3fb9c61bc262f6af894c01e Mon Sep 17 00:00:00 2001 From: sta Date: Fri, 15 Nov 2013 22:39:43 -0800 Subject: [PATCH 02/27] Create gh-pages branch via GitHub --- index.html | 2 +- params.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index ac3d2ce51..828750987 100644 --- a/index.html +++ b/index.html @@ -483,7 +483,7 @@

License

-

websocket-sharp is provided under The MIT License.

+

websocket-sharp is provided under The MIT License.

diff --git a/params.json b/params.json index 200be84ab..9b9fcf5b4 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"# Welcome to websocket-sharp! #\r\n\r\n**websocket-sharp** supports the followings.\r\n\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Branches ##\r\n\r\n- **[master]** for production releases.\r\n- **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.\r\n- **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.\r\n\r\n## Build ##\r\n\r\n**websocket-sharp** is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) that you built it yourself to the library references of your project.\r\n\r\nIf you use websocket-sharp.dll in your **[Unity]** project, you should add it to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\n**websocket-sharp** has now been displayed on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\n**websocket-sharp** has now been displayed on the **Unity Asset Store**.\r\n\r\n- **[websocket-sharp for Unity]**\r\n\r\nIt's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\"))\r\n {\r\n ws.OnMessage += (sender, e) =>\r\n {\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n };\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the specified WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\"))\r\n{\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as `EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket data frame.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e.Type` (`WebSocketSharp.MessageEventArgs.Type`, its type is `WebSocketSharp.Opcode`) indicates the type of a received data. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` equals `Opcode.TEXT`, you use `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, its type is `string`) that contains a received **Text** data.\r\n\r\nIf `e.Type` equals `Opcode.BINARY`, you use `e.RawData` (`WebSocketSharp.MessageEventArgs.RawData`, its type is `byte []`) that contains a received **Binary** data.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT)\r\n{\r\n // Do something with e.Data\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY)\r\n{\r\n // Do something with e.RawData\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, its type is `string`) contains an error message, so you use it.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e.Code` (`WebSocketSharp.CloseEventArgs.Code`, its type is `ushort`) contains a status code indicating the reason for closure and `e.Reason` (`WebSocketSharp.CloseEventArgs.Reason`, its type is `string`) contains the reason for closure, so you use them.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nSending a data.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nThe types of `data` are `string`, `byte []` and `System.IO.FileInfo`.\r\n\r\nIn addition, the `WebSocket.Send (stream, length)` method exists, too.\r\n\r\nThese methods don't wait for the send to be complete. It means these methods behave asynchronously.\r\n\r\nIf you do something when the send is complete, you use any of some `WebSocket.Send (data, completed)` methods.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you explicitly close the WebSocket connection, you use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nThe types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, and the type of `reason` is `string`.\r\n\r\nIn addition, the `WebSocket.Close ()` and `WebSocket.Close (code)` methods exist, too.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketService\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketService` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nIf you override the `WebSocketService.OnMessage` method, it's bound to the server side `WebSocket.OnMessage` event.\r\n\r\nAnd if you override the `WebSocketService.OnOpen`, `WebSocketService.OnError` and `WebSocketService.OnClose` methods, each of them is bound to each server side event of `WebSocket.OnOpen`, `WebSocket.OnError` and `WebSocket.OnClose`.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client of the current session to the WebSocket service.\r\n\r\nThe `WebSocketService.Sessions` (its type is `WebSocketSharp.Server.WebSocketSessionManager`) property provides some functions for the sessions to the WebSocket service.\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method sends a data to all clients of the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service with the specified path to the service to your `WebSocketServer` by using the `WebSocketServer.AddWebSocketService` or `WebSocketServer.AddWebSocketService` method.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2**.\r\n\r\nIf you create an instance of the `WebSocketServer` class without the port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the server.\r\n\r\n```cs\r\nwssv.Stop ();\r\n```\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext` and some other classes of [Mono] to create the HTTP server that can upgrade the connection to the WebSocket connection when it receives a WebSocket connection request.\r\n\r\nYou can add any WebSocket service with the specified path to the service to your `HttpServer` by using the `HttpServer.AddWebSocketService` or `HttpServer.AddWebSocketService` method.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\n**websocket-sharp** supports **[Per-message Compression][compression]** extension. (But it doesn't support with [extension parameters].)\r\n\r\nIf you enable this extension as a WebSocket client, you should do like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your WebSocket client sends the following header in the opening handshake to a WebSocket server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it responds the same header. And when your client receives the header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nAs a **WebSocket Client**, creating an instance of the `WebSocket` class with the specified **wss** scheme URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\"))\r\n{\r\n ...\r\n}\r\n```\r\n\r\nIf you set the custom validation for the server certificate, you use the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>\r\n{\r\n // Do something to validate the server certificate.\r\n return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate and returns valid.\r\n\r\nAs a **WebSocket Server**, creating an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes own logging functions.\r\n\r\nThe `WebSocket.Log` property provides the logging functions.\r\n\r\nIf you change the current logging level (the default is `LogLevel.ERROR`), you use the `WebSocket.Log.Level` property.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThe above means that the logging outputs with a less than `LogLevel.DEBUG` are not outputted.\r\n\r\nAnd if you output a log, you use any of some output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging functions.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n[Example] connects to the [Echo server] using the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n[Example1] connects to the [Audio Data delivery server] using the WebSocket ([Example1] is only implemented the chat feature, still unfinished).\r\n\r\nAnd [Example1] uses [Json.NET].\r\n\r\n### Example2 ###\r\n\r\n[Example2] starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n[Example3] starts an HTTP server that can upgrade the connection to the WebSocket connection.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after [Example3] running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\n**websocket-sharp** supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\n**websocket-sharp** is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[master]: https://github.com/sta/websocket-sharp/tree/master\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n[websocket-sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"# Welcome to websocket-sharp! #\r\n\r\n**websocket-sharp** supports the followings.\r\n\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Branches ##\r\n\r\n- **[master]** for production releases.\r\n- **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.\r\n- **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.\r\n\r\n## Build ##\r\n\r\n**websocket-sharp** is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) built yourself to the library references of your project.\r\n\r\nIf you use that websocket-sharp.dll in your **[Unity]** project, you should add it to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\n**websocket-sharp** is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\n**websocket-sharp** is available on the **Unity Asset Store**.\r\n\r\n- **[websocket-sharp for Unity]**\r\n\r\nIt's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) => {\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n };\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the specified WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as `EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket data frame.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e.Type` (`WebSocketSharp.MessageEventArgs.Type`, its type is `WebSocketSharp.Opcode`) indicates the type of a received data. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` equals `Opcode.TEXT`, you use `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, its type is `string`) that contains a received **Text** data.\r\n\r\nIf `e.Type` equals `Opcode.BINARY`, you use `e.RawData` (`WebSocketSharp.MessageEventArgs.RawData`, its type is `byte []`) that contains a received **Binary** data.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT) {\r\n // Do something with e.Data\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY) {\r\n // Do something with e.RawData\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, its type is `string`) contains an error message, so you use it.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e.Code` (`WebSocketSharp.CloseEventArgs.Code`, its type is `ushort`) contains a status code indicating the reason for closure and `e.Reason` (`WebSocketSharp.CloseEventArgs.Reason`, its type is `string`) contains the reason for closure, so you use them.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nSending a data.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nThe types of `data` are `string`, `byte []` and `System.IO.FileInfo`.\r\n\r\nIn addition, the `WebSocket.Send (stream, length)` method exists, too.\r\n\r\nThese methods don't wait for the send to be complete. It means these methods behave asynchronously.\r\n\r\nIf you do something when the send is complete, you use any of some `WebSocket.Send (data, completed)` methods.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you explicitly close the WebSocket connection, you use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nThe types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, and the type of `reason` is `string`.\r\n\r\nIn addition, the `WebSocket.Close ()` and `WebSocket.Close (code)` methods exist, too.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketService\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketService` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nIf you override the `WebSocketService.OnMessage` method, it's bound to the server side `WebSocket.OnMessage` event.\r\n\r\nAnd if you override the `WebSocketService.OnOpen`, `WebSocketService.OnError` and `WebSocketService.OnClose` methods, each of them is bound to each server side event of `WebSocket.OnOpen`, `WebSocket.OnError` and `WebSocket.OnClose`.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client of the current session to the WebSocket service.\r\n\r\nThe `WebSocketService.Sessions` (its type is `WebSocketSharp.Server.WebSocketSessionManager`) property provides some functions for the sessions to the WebSocket service.\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method sends a data to all clients of the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service with the specified path to the service to your `WebSocketServer` by using the `WebSocketServer.AddWebSocketService` or `WebSocketServer.AddWebSocketService` method.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2**.\r\n\r\nIf you create an instance of the `WebSocketServer` class without the port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the server.\r\n\r\n```cs\r\nwssv.Stop ();\r\n```\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext` and some other classes of [Mono] to create the HTTP server that can upgrade the connection to the WebSocket connection when it receives a WebSocket connection request.\r\n\r\nYou can add any WebSocket service with the specified path to the service to your `HttpServer` by using the `HttpServer.AddWebSocketService` or `HttpServer.AddWebSocketService` method.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\n**websocket-sharp** supports **[Per-message Compression][compression]** extension. (But it doesn't support with [extension parameters].)\r\n\r\nIf you enable this extension as a WebSocket client, you should do like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your WebSocket client sends the following header in the opening handshake to a WebSocket server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it responds the same header. And when your client receives the header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nAs a **WebSocket Client**, creating an instance of the `WebSocket` class with the specified **wss** scheme URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nIf you set the custom validation for the server certificate, you use the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate and returns valid.\r\n\r\nAs a **WebSocket Server**, creating an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes own logging functions.\r\n\r\nThe `WebSocket.Log` property provides the logging functions.\r\n\r\nIf you change the current logging level (the default is `LogLevel.ERROR`), you use the `WebSocket.Log.Level` property.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThe above means that the logging outputs with a less than `LogLevel.DEBUG` are not outputted.\r\n\r\nAnd if you output a log, you use any of some output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging functions.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n[Example] connects to the [Echo server] using the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n[Example1] connects to the [Audio Data delivery server] using the WebSocket ([Example1] is only implemented the chat feature, still unfinished).\r\n\r\nAnd [Example1] uses [Json.NET].\r\n\r\n### Example2 ###\r\n\r\n[Example2] starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n[Example3] starts an HTTP server that can upgrade the connection to the WebSocket connection.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after [Example3] running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\n**websocket-sharp** supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\n**websocket-sharp** is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[master]: https://github.com/sta/websocket-sharp/tree/master\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n[websocket-sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 4d5002cd4a90932f5a8319fd9f1e9b207838ae01 Mon Sep 17 00:00:00 2001 From: sta Date: Mon, 24 Feb 2014 20:42:18 +0900 Subject: [PATCH 13/27] Create gh-pages branch via GitHub --- images/checker.png | Bin 0 -> 250 bytes index.html | 241 ++++++++++++++---------- javascripts/scale.fix.js | 20 ++ params.json | 2 +- stylesheets/pygment_trac.css | 125 ++++++------ stylesheets/styles.css | 356 +++++++++++++++++++++++++++++++++++ 6 files changed, 573 insertions(+), 171 deletions(-) create mode 100644 images/checker.png create mode 100644 javascripts/scale.fix.js create mode 100644 stylesheets/styles.css diff --git a/images/checker.png b/images/checker.png new file mode 100644 index 0000000000000000000000000000000000000000..ab1454032c6ec47a4c974f4e4d75bd226911b4fc GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^3P3E!!3HFKxnwkf6icy_X9x!n)NrJ90QsB+9+AZi z4BSE>%y{W;-5;Q!Oo?kmNpOBzNqJ&XDuZK6ep0G}TV_#ed45rLv4V53Y2nt#W z{&tJwQo64!`zEoY0VG=WX{H35gh8JhW7>iX;yrE$GemF_3=9!wFW${k`+fjuK7*&L KpUXO@geCwfrcS5; literal 0 HcmV?d00001 diff --git a/index.html b/index.html index adc7629c4..5cf41a7a3 100644 --- a/index.html +++ b/index.html @@ -1,37 +1,36 @@ - + - + - - - - - + websocket-sharp by sta + + + + + - - websocket-sharp by sta - -
-
+
+

websocket-sharp

-

A C# implementation of the WebSocket protocol client and server

- View project onGitHub -
-
- -
-
-
-

+

A C# implementation of the WebSocket protocol client and server

+

View the Project on GitHub sta/websocket-sharp

+ + +
+

Welcome to websocket-sharp!

-

websocket-sharp supports the followings.

+

websocket-sharp supports the followings:

Branches

@@ -55,7 +55,7 @@

Build

-

websocket-sharp is built as a single assembly, websocket-sharp.dll.

+

websocket-sharp is built as a single assembly, websocket-sharp.dll.

websocket-sharp is developed with MonoDevelop. So the simple way to build is to open websocket-sharp.sln and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.

@@ -67,12 +67,12 @@

You should add websocket-sharp.dll (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) built yourself to the library references of your project.

-

If you use that websocket-sharp.dll in your Unity project, you should add it to any folder of your project (e.g. Assets/Plugins) in the Unity Editor.

+

If you would like to use that websocket-sharp.dll in your Unity project, you should add that dll to any folder of your project (e.g. Assets/Plugins) in the Unity Editor.

NuGet Gallery

-

websocket-sharp is available on the NuGet Gallery, as still a prerelease version.

+

websocket-sharp is available on the NuGet Gallery, as still a prerelease version.

  • NuGet Gallery: websocket-sharp
  • @@ -84,10 +84,10 @@

    Unity Asset Store

    -

    websocket-sharp is available on the Unity Asset Store.

    +

    websocket-sharp is available on the Unity Asset Store.

    It's priced at US$15. I think your $15 makes this project more better and accelerated, Thank you!

    @@ -106,9 +106,8 @@

    public static void Main (string [] args) { using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) { - ws.OnMessage += (sender, e) => { + ws.OnMessage += (sender, e) => Console.WriteLine ("Laputa says: " + e.Data); - }; ws.Connect (); ws.Send ("BALUS"); @@ -132,14 +131,14 @@

    Step 2

    -

    Creating an instance of the WebSocket class with the specified WebSocket URL to connect.

    +

    Creating an instance of the WebSocket class with the WebSocket URL to connect.

    using (var ws = new WebSocket ("ws://example.com")) {
       ...
     }
     
    -

    The WebSocket class inherits the IDisposable interface, so you can use the using statement.

    +

    The WebSocket class inherits the System.IDisposable interface, so you can use the using statement.

    Step 3

    @@ -156,23 +155,25 @@
    };

-

e has passed as EventArgs.Empty, so you don't use e.

+

e has passed as the System.EventArgs.Empty, so you don't use e.

WebSocket.OnMessage Event
-

A WebSocket.OnMessage event occurs when the WebSocket receives a WebSocket data frame.

+

A WebSocket.OnMessage event occurs when the WebSocket receives a WebSocket message.

ws.OnMessage += (sender, e) => {
   ...
 };
 
-

e.Type (WebSocketSharp.MessageEventArgs.Type, its type is WebSocketSharp.Opcode) indicates the type of a received data. So by checking it, you determine which item you should use.

+

e has passed as a WebSocketSharp.MessageEventArgs.

-

If e.Type equals Opcode.TEXT, you use e.Data (WebSocketSharp.MessageEventArgs.Data, its type is string) that contains a received Text data.

+

e.Type property returns either WebSocketSharp.Opcode.TEXT or WebSocketSharp.Opcode.BINARY that represents the type of the received message. So by checking it, you determine which item you should use.

-

If e.Type equals Opcode.BINARY, you use e.RawData (WebSocketSharp.MessageEventArgs.RawData, its type is byte []) that contains a received Binary data.

+

If e.Type is Opcode.TEXT, you should use e.Data property (returns a string) that represents the received Text message.

+ +

Or if e.Type is Opcode.BINARY, you should use e.RawData property (returns a byte []) that represents the received Binary message.

if (e.Type == Opcode.TEXT) {
   // Do something with e.Data
@@ -195,7 +196,9 @@ 
};
-

e.Message (WebSocketSharp.ErrorEventArgs.Message, its type is string) contains an error message, so you use it.

+

e has passed as a WebSocketSharp.ErrorEventArgs.

+ +

e.Message property returns a string that represents the error message. So you should use it to get the error message.

WebSocket.OnClose Event
@@ -207,7 +210,9 @@
};
-

e.Code (WebSocketSharp.CloseEventArgs.Code, its type is ushort) contains a status code indicating the reason for closure and e.Reason (WebSocketSharp.CloseEventArgs.Reason, its type is string) contains the reason for closure, so you use them.

+

e has passed as a WebSocketSharp.CloseEventArgs.

+ +

e.Code property returns a ushort that represents the status code that indicates the reason for closure, and e.Reason property returns a string that represents the reason for closure. So you should use them to get the reason for closure.

Step 4

@@ -217,23 +222,26 @@

ws.Connect ();
 
+

If you would like to connect to the server asynchronously, you should use the WebSocket.ConnectAsync () method.

+

Step 5

-

Sending a data.

+

Sending a data to the WebSocket server.

ws.Send (data);
 

The WebSocket.Send method is overloaded.

-

The types of data are string, byte [] and System.IO.FileInfo.

+

You can use the WebSocket.Send (string), WebSocket.Send (byte []), and WebSocket.Send (System.IO.FileInfo) methods to send a data.

-

In addition, the WebSocket.Send (stream, length) method exists, too.

+

If you would like to send a data asynchronously, you should use the WebSocket.SendAsync method.

-

These methods don't wait for the send to be complete. It means these methods behave asynchronously.

+
ws.SendAsync (data, completed);
+
-

If you do something when the send is complete, you use any of some WebSocket.Send (data, completed) methods.

+

And if you would like to do something when the send is complete, you should set completed to any Action<bool>.

Step 6

@@ -243,13 +251,13 @@

ws.Close (code, reason);
 
-

If you explicitly close the WebSocket connection, you use the WebSocket.Close method.

+

If you would like to close the connection explicitly, you should use the WebSocket.Close method.

The WebSocket.Close method is overloaded.

-

The types of code are WebSocketSharp.CloseStatusCode and ushort, and the type of reason is string.

+

You can use the WebSocket.Close (), WebSocket.Close (ushort), WebSocket.Close (WebSocketSharp.CloseStatusCode), WebSocket.Close (ushort, string), or WebSocket.Close (WebSocketSharp.CloseStatusCode, string) method to close the connection.

-

In addition, the WebSocket.Close () and WebSocket.Close (code) methods exist, too.

+

If you would like to close the connection asynchronously, you should use the WebSocket.CloseAsync method.

WebSocket Server

@@ -294,14 +302,14 @@

using WebSocketSharp.Server;
 
-

The WebSocketService and WebSocketServer classes exist in the WebSocketSharp.Server namespace.

+

The WebSocketServer and WebSocketService classes exist in the WebSocketSharp.Server namespace.

Step 2

Creating the class that inherits the WebSocketService class.

-

For example, if you provide an echo service,

+

For example, if you would like to provide an echo service,

using System;
 using WebSocketSharp;
@@ -316,7 +324,7 @@ 

}

-

And if you provide a chat service,

+

And if you would like to provide a chat service,

using System;
 using WebSocketSharp;
@@ -343,15 +351,15 @@ 

}

-

If you override the WebSocketService.OnMessage method, it's bound to the server side WebSocket.OnMessage event.

+

If you override the WebSocketService.OnMessage (MessageEventArgs) method, that overridden method is called when the OnMessage event of the current session's WebSocket occurs.

-

And if you override the WebSocketService.OnOpen, WebSocketService.OnError and WebSocketService.OnClose methods, each of them is bound to each server side event of WebSocket.OnOpen, WebSocket.OnError and WebSocket.OnClose.

+

And if you override the WebSocketService.OnOpen (), WebSocketService.OnError (ErrorEventArgs), and WebSocketService.OnClose (CloseEventArgs) methods, each of them is called when each event of the current session's WebSocket (the OnOpen, OnError, and OnClose events) occurs.

-

The WebSocketService.Send method sends a data to the client of the current session to the WebSocket service.

+

The WebSocketService.Send method sends a data to the client on the current session in the WebSocket service.

-

The WebSocketService.Sessions (its type is WebSocketSharp.Server.WebSocketSessionManager) property provides some functions for the sessions to the WebSocket service.

+

If you would like to access the sessions in the WebSocket service, you should use the WebSocketService.Sessions property (returns a WebSocketSharp.Server.WebSocketSessionManager).

-

The WebSocketService.Sessions.Broadcast method sends a data to all clients of the WebSocket service.

+

The WebSocketService.Sessions.Broadcast method broadcasts a data to all clients of the WebSocket service.

Step 3

@@ -364,15 +372,15 @@

wssv.AddWebSocketService<Chat> ("/ChatWithNiceBoat", () => new Chat (" Nice boat.")); -

You can add any WebSocket service with the specified path to the service to your WebSocketServer by using the WebSocketServer.AddWebSocketService<TWithNew> or WebSocketServer.AddWebSocketService<T> method.

+

You can add any WebSocket service to your WebSocketServer with the specified path to the service, using the WebSocketServer.AddWebSocketService<TWithNew> (string) and WebSocketServer.AddWebSocketService<T> (string, Func<T>) methods.

The type of TWithNew must inherit the WebSocketService class and must have a public parameterless constructor.

-

The type of T must inherit WebSocketService class.

+

The type of T must inherit the WebSocketService class.

-

So you can use the classes created in Step 2.

+

So you can use the classes created in Step 2 to add the WebSocket service.

-

If you create an instance of the WebSocketServer class without the port number, the WebSocketServer set the port number to 80 automatically. So it's necessary to run with root permission.

+

If you create an instance of the WebSocketServer class without a port number, the WebSocketServer set the port number to 80 automatically. So it's necessary to run with root permission.

$ sudo mono example2.exe
 
@@ -380,7 +388,7 @@

Step 4

-

Starting the server.

+

Starting the WebSocket server.

wssv.Start ();
 
@@ -388,17 +396,23 @@

Step 5

-

Stopping the server.

+

Stopping the WebSocket server.

-
wssv.Stop ();
+
wssv.Stop (code, reason);
 
+

The WebSocketServer.Stop method is overloaded.

+ +

You can use the WebSocketServer.Stop (), WebSocketServer.Stop (ushort, string), or WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string) method to stop the server.

+

HTTP Server with the WebSocket

-

I modified the System.Net.HttpListener, System.Net.HttpListenerContext and some other classes of Mono to create the HTTP server that can upgrade the connection to the WebSocket connection when it receives a WebSocket connection request.

+

I modified the System.Net.HttpListener, System.Net.HttpListenerContext, and some other classes of Mono to create the HTTP server that allows to accept the WebSocket connection requests.

+ +

So websocket-sharp provides the WebSocketSharp.Server.HttpServer class.

-

You can add any WebSocket service with the specified path to the service to your HttpServer by using the HttpServer.AddWebSocketService<TWithNew> or HttpServer.AddWebSocketService<T> method.

+

You can add any WebSocket service to your HttpServer with the specified path to the service, using the HttpServer.AddWebSocketService<TWithNew> (string) and HttpServer.AddWebSocketService<T> (string, Func<T>) methods.

var httpsv = new HttpServer (4649);
 httpsv.AddWebSocketService<Echo> ("/Echo");
@@ -414,31 +428,33 @@ 

Per-message Compression

-

websocket-sharp supports Per-message Compression extension. (But it doesn't support with extension parameters.)

+

websocket-sharp supports the Per-message Compression extension. (But it doesn't support with the extension parameters.)

-

If you enable this extension as a WebSocket client, you should do like the following.

+

If you would like to enable this extension as a WebSocket client, you should set like the following.

ws.Compression = CompressionMethod.DEFLATE;
 
-

And then your WebSocket client sends the following header in the opening handshake to a WebSocket server.

+

And then your client sends the following header with the connection request to the server.

Sec-WebSocket-Extensions: permessage-deflate
 
-

If the server supports this extension, it responds the same header. And when your client receives the header, it enables this extension.

+

If the server supports this extension, it returns the same header. And when your client receives that header, it enables this extension.

Secure Connection

-

As a WebSocket Client, creating an instance of the WebSocket class with the specified wss scheme URL to connect.

+

websocket-sharp supports the Secure Connection (SSL).

+ +

As a WebSocket Client, you should create an instance of the WebSocket class with the wss scheme WebSocket URL to connect.

using (var ws = new WebSocket ("wss://example.com")) {
   ...
 }
 
-

If you set the custom validation for the server certificate, you use the WebSocket.ServerCertificateValidationCallback property.

+

And if you would like to set the custom validation for the server certificate, you should set the WebSocket.ServerCertificateValidationCallback property.

ws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {
   // Do something to validate the server certificate.
@@ -448,32 +464,63 @@ 

If you set this property to nothing, the validation does nothing with the server certificate and returns valid.

-

As a WebSocket Server, creating an instance of the WebSocketServer or HttpServer class with some settings for the secure connection.

+

As a WebSocket Server, you should create an instance of the WebSocketServer or HttpServer class with some settings for the secure connection. It's like the following.

var wssv = new WebSocketServer (4649, true);
 wssv.Certificate = new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");
 
+

+HTTP Authentication

+ +

websocket-sharp supports the HTTP Authentication (Basic/Digest).

+ +

As a WebSocket Client, you should set a pair of user name and password for the HTTP authentication, using the WebSocket.SetCredentials (string, string, bool) method before connecting.

+ +
ws.SetCredentials (username, password, preAuth);
+
+ +

If preAuth is true, the WebSocket sends the Basic authentication credentials with the first connection request to the server.

+ +

Or if preAuth is false, the WebSocket sends either the Basic or Digest authentication (determined by the unauthorized response to the first connection request) credentials with the second connection request to the server.

+ +

As a WebSocket Server, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting. It's like the following.

+ +
wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
+wssv.Realm = "WebSocket Test";
+wssv.UserCredentialsFinder = identity => {
+  var expected = "nobita";
+  return identity.Name == expected
+         ? new NetworkCredential (expected, "password", "gunfighter") // User name, password, and roles
+         : null; // If the user credentials not found.
+};
+
+ +

If you would like to provide the Digest authentication, you should set like the following.

+ +
wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;
+
+

Logging

-

The WebSocket class includes own logging functions.

+

The WebSocket class includes the own logging function.

-

The WebSocket.Log property provides the logging functions.

+

You can access it with the WebSocket.Log property (returns a WebSocketSharp.Logger).

-

If you change the current logging level (the default is LogLevel.ERROR), you use the WebSocket.Log.Level property.

+

So if you would like to change the current logging level (WebSocketSharp.LogLevel.ERROR as the default), you should set the WebSocket.Log.Level property to any of the LogLevel enum values.

ws.Log.Level = LogLevel.DEBUG;
 
-

The above means that the logging outputs with a less than LogLevel.DEBUG are not outputted.

+

This means a log with less than LogLevel.DEBUG isn't outputted.

-

And if you output a log, you use any of some output methods. The following outputs a log with LogLevel.DEBUG.

+

And if you would like to output a log, you should use any of the output methods. The following outputs a log with LogLevel.DEBUG.

ws.Log.Debug ("This is a debug message.");
 
-

The WebSocketServer and HttpServer classes include the same logging functions.

+

The WebSocketServer and HttpServer classes include the same logging function.

Examples

@@ -483,31 +530,31 @@

Example

-

Example connects to the Echo server using the WebSocket.

+

Example connects to the Echo server with the WebSocket.

Example1

-

Example1 connects to the Audio Data delivery server using the WebSocket (Example1 is only implemented the chat feature, still unfinished).

+

Example1 connects to the Audio Data delivery server with the WebSocket. (But it's only implemented the chat feature, still unfinished.)

-

And Example1 uses Json.NET.

+

And Example1 uses Json.NET.

Example2

-

Example2 starts a WebSocket server.

+

Example2 starts a WebSocket server.

Example3

-

Example3 starts an HTTP server that can upgrade the connection to the WebSocket connection.

+

Example3 starts an HTTP server that allows to accept the WebSocket connection requests.

-

Could you access to http://localhost:4649 to do WebSocket Echo Test with your web browser after Example3 running?

+

Could you access to http://localhost:4649 to do WebSocket Echo Test with your web browser after Example3 running?

Supported WebSocket Specifications

-

websocket-sharp supports RFC 6455 and is based on the following WebSocket references.

+

websocket-sharp supports RFC 6455 and is based on the following WebSocket references.

License

-

websocket-sharp is provided under The MIT License.

- - - -
+

websocket-sharp is provided under The MIT License.

+
- - diff --git a/javascripts/scale.fix.js b/javascripts/scale.fix.js new file mode 100644 index 000000000..08716c006 --- /dev/null +++ b/javascripts/scale.fix.js @@ -0,0 +1,20 @@ +fixScale = function(doc) { + + var addEvent = 'addEventListener', + type = 'gesturestart', + qsa = 'querySelectorAll', + scales = [1, 1], + meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; + + function fix() { + meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; + doc.removeEventListener(type, fix, true); + } + + if ((meta = meta[meta.length - 1]) && addEvent in doc) { + fix(); + scales = [.25, 1.6]; + doc[addEvent](type, fix, true); + } + +}; \ No newline at end of file diff --git a/params.json b/params.json index 9b9fcf5b4..898bdd906 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"# Welcome to websocket-sharp! #\r\n\r\n**websocket-sharp** supports the followings.\r\n\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Branches ##\r\n\r\n- **[master]** for production releases.\r\n- **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.\r\n- **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.\r\n\r\n## Build ##\r\n\r\n**websocket-sharp** is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) built yourself to the library references of your project.\r\n\r\nIf you use that websocket-sharp.dll in your **[Unity]** project, you should add it to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\n**websocket-sharp** is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\n**websocket-sharp** is available on the **Unity Asset Store**.\r\n\r\n- **[websocket-sharp for Unity]**\r\n\r\nIt's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) => {\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n };\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the specified WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as `EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket data frame.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e.Type` (`WebSocketSharp.MessageEventArgs.Type`, its type is `WebSocketSharp.Opcode`) indicates the type of a received data. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` equals `Opcode.TEXT`, you use `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, its type is `string`) that contains a received **Text** data.\r\n\r\nIf `e.Type` equals `Opcode.BINARY`, you use `e.RawData` (`WebSocketSharp.MessageEventArgs.RawData`, its type is `byte []`) that contains a received **Binary** data.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT) {\r\n // Do something with e.Data\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY) {\r\n // Do something with e.RawData\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, its type is `string`) contains an error message, so you use it.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e.Code` (`WebSocketSharp.CloseEventArgs.Code`, its type is `ushort`) contains a status code indicating the reason for closure and `e.Reason` (`WebSocketSharp.CloseEventArgs.Reason`, its type is `string`) contains the reason for closure, so you use them.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nSending a data.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nThe types of `data` are `string`, `byte []` and `System.IO.FileInfo`.\r\n\r\nIn addition, the `WebSocket.Send (stream, length)` method exists, too.\r\n\r\nThese methods don't wait for the send to be complete. It means these methods behave asynchronously.\r\n\r\nIf you do something when the send is complete, you use any of some `WebSocket.Send (data, completed)` methods.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you explicitly close the WebSocket connection, you use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nThe types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, and the type of `reason` is `string`.\r\n\r\nIn addition, the `WebSocket.Close ()` and `WebSocket.Close (code)` methods exist, too.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketService\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketService` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nIf you override the `WebSocketService.OnMessage` method, it's bound to the server side `WebSocket.OnMessage` event.\r\n\r\nAnd if you override the `WebSocketService.OnOpen`, `WebSocketService.OnError` and `WebSocketService.OnClose` methods, each of them is bound to each server side event of `WebSocket.OnOpen`, `WebSocket.OnError` and `WebSocket.OnClose`.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client of the current session to the WebSocket service.\r\n\r\nThe `WebSocketService.Sessions` (its type is `WebSocketSharp.Server.WebSocketSessionManager`) property provides some functions for the sessions to the WebSocket service.\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method sends a data to all clients of the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service with the specified path to the service to your `WebSocketServer` by using the `WebSocketServer.AddWebSocketService` or `WebSocketServer.AddWebSocketService` method.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2**.\r\n\r\nIf you create an instance of the `WebSocketServer` class without the port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the server.\r\n\r\n```cs\r\nwssv.Stop ();\r\n```\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext` and some other classes of [Mono] to create the HTTP server that can upgrade the connection to the WebSocket connection when it receives a WebSocket connection request.\r\n\r\nYou can add any WebSocket service with the specified path to the service to your `HttpServer` by using the `HttpServer.AddWebSocketService` or `HttpServer.AddWebSocketService` method.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\n**websocket-sharp** supports **[Per-message Compression][compression]** extension. (But it doesn't support with [extension parameters].)\r\n\r\nIf you enable this extension as a WebSocket client, you should do like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your WebSocket client sends the following header in the opening handshake to a WebSocket server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it responds the same header. And when your client receives the header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nAs a **WebSocket Client**, creating an instance of the `WebSocket` class with the specified **wss** scheme URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nIf you set the custom validation for the server certificate, you use the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate and returns valid.\r\n\r\nAs a **WebSocket Server**, creating an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes own logging functions.\r\n\r\nThe `WebSocket.Log` property provides the logging functions.\r\n\r\nIf you change the current logging level (the default is `LogLevel.ERROR`), you use the `WebSocket.Log.Level` property.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThe above means that the logging outputs with a less than `LogLevel.DEBUG` are not outputted.\r\n\r\nAnd if you output a log, you use any of some output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging functions.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n[Example] connects to the [Echo server] using the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n[Example1] connects to the [Audio Data delivery server] using the WebSocket ([Example1] is only implemented the chat feature, still unfinished).\r\n\r\nAnd [Example1] uses [Json.NET].\r\n\r\n### Example2 ###\r\n\r\n[Example2] starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n[Example3] starts an HTTP server that can upgrade the connection to the WebSocket connection.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after [Example3] running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\n**websocket-sharp** supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\n**websocket-sharp** is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[master]: https://github.com/sta/websocket-sharp/tree/master\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n[websocket-sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"# Welcome to websocket-sharp! #\r\n\r\n**websocket-sharp** supports the followings:\r\n\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Branches ##\r\n\r\n- **[master]** for production releases.\r\n- **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.\r\n- **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) built yourself to the library references of your project.\r\n\r\nIf you would like to use that websocket-sharp.dll in your **[Unity]** project, you should add that dll to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket message.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.TEXT` or `WebSocketSharp.Opcode.BINARY` that represents the type of the received message. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` is `Opcode.TEXT`, you should use `e.Data` property (returns a `string`) that represents the received **Text** message.\r\n\r\nOr if `e.Type` is `Opcode.BINARY`, you should use `e.RawData` property (returns a `byte []`) that represents the received **Binary** message.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT) {\r\n // Do something with e.Data\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY) {\r\n // Do something with e.RawData\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message. So you should use it to get the error message.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code that indicates the reason for closure, and `e.Reason` property returns a `string` that represents the reason for closure. So you should use them to get the reason for closure.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending a data to the WebSocket server.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte [])`, and `WebSocket.Send (System.IO.FileInfo)` methods to send a data.\r\n\r\nIf you would like to send a data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```cs\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd if you would like to do something when the send is complete, you should set `completed` to any `Action`.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketService\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketServer` and `WebSocketService` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nIf you override the `WebSocketService.OnMessage (MessageEventArgs)` method, that overridden method is called when the `OnMessage` event of the current session's `WebSocket` occurs.\r\n\r\nAnd if you override the `WebSocketService.OnOpen ()`, `WebSocketService.OnError (ErrorEventArgs)`, and `WebSocketService.OnClose (CloseEventArgs)` methods, each of them is called when each event of the current session's `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client on the current session in the WebSocket service.\r\n\r\nIf you would like to access the sessions in the WebSocket service, you should use the `WebSocketService.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method broadcasts a data to all clients of the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified path to the service, using the `WebSocketServer.AddWebSocketService (string)` and `WebSocketServer.AddWebSocketService (string, Func)` methods.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit the `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the WebSocket service.\r\n\r\nIf you create an instance of the `WebSocketServer` class without a port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```cs\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified path to the service, using the `HttpServer.AddWebSocketService (string)` and `HttpServer.AddWebSocketService (string, Func)` methods.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension. (But it doesn't support with the [extension parameters].)\r\n\r\nIf you would like to enable this extension as a WebSocket client, you should set like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your client sends the following header with the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it returns the same header. And when your client receives that header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection (SSL)**.\r\n\r\nAs a **WebSocket Client**, you should create an instance of the `WebSocket` class with the **wss** scheme WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to set the custom validation for the server certificate, you should set the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate and returns valid.\r\n\r\nAs a **WebSocket Server**, you should create an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection. It's like the following.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```cs\r\nws.SetCredentials (username, password, preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest authentication (determined by the unauthorized response to the first connection request) credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting. It's like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = identity => {\r\n var expected = \"nobita\";\r\n return identity.Name == expected\r\n ? new NetworkCredential (expected, \"password\", \"gunfighter\") // User name, password, and roles\r\n : null; // If the user credentials not found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can access it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.ERROR` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThis means a log with less than `LogLevel.DEBUG` isn't outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[master]: https://github.com/sta/websocket-sharp/tree/master\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css index c6a6452d2..1926cfdf3 100644 --- a/stylesheets/pygment_trac.css +++ b/stylesheets/pygment_trac.css @@ -1,69 +1,60 @@ -.highlight { background: #ffffff; } -.highlight .c { color: #999988; font-style: italic } /* Comment */ -.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ -.highlight .k { font-weight: bold } /* Keyword */ -.highlight .o { font-weight: bold } /* Operator */ -.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ -.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ -.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .hll { background-color: #49483e } +.highlight { background: #3A3C42; color: #f8f8f2 } +.highlight .c { color: #75715e } /* Comment */ +.highlight .err { color: #960050; background-color: #1e0010 } /* Error */ +.highlight .k { color: #66d9ef } /* Keyword */ +.highlight .l { color: #ae81ff } /* Literal */ +.highlight .n { color: #f8f8f2 } /* Name */ +.highlight .o { color: #f92672 } /* Operator */ +.highlight .p { color: #f8f8f2 } /* Punctuation */ +.highlight .cm { color: #75715e } /* Comment.Multiline */ +.highlight .cp { color: #75715e } /* Comment.Preproc */ +.highlight .c1 { color: #75715e } /* Comment.Single */ +.highlight .cs { color: #75715e } /* Comment.Special */ .highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #aa0000 } /* Generic.Error */ -.highlight .gh { color: #999999 } /* Generic.Heading */ -.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ -.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ -.highlight .go { color: #888888 } /* Generic.Output */ -.highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ -.highlight .gt { color: #aa0000 } /* Generic.Traceback */ -.highlight .kc { font-weight: bold } /* Keyword.Constant */ -.highlight .kd { font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ -.highlight .m { color: #009999 } /* Literal.Number */ -.highlight .s { color: #d14 } /* Literal.String */ -.highlight .na { color: #008080 } /* Name.Attribute */ -.highlight .nb { color: #0086B3 } /* Name.Builtin */ -.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ -.highlight .no { color: #008080 } /* Name.Constant */ -.highlight .ni { color: #800080 } /* Name.Entity */ -.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ -.highlight .nn { color: #555555 } /* Name.Namespace */ -.highlight .nt { color: #000080 } /* Name.Tag */ -.highlight .nv { color: #008080 } /* Name.Variable */ -.highlight .ow { font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mf { color: #009999 } /* Literal.Number.Float */ -.highlight .mh { color: #009999 } /* Literal.Number.Hex */ -.highlight .mi { color: #009999 } /* Literal.Number.Integer */ -.highlight .mo { color: #009999 } /* Literal.Number.Oct */ -.highlight .sb { color: #d14 } /* Literal.String.Backtick */ -.highlight .sc { color: #d14 } /* Literal.String.Char */ -.highlight .sd { color: #d14 } /* Literal.String.Doc */ -.highlight .s2 { color: #d14 } /* Literal.String.Double */ -.highlight .se { color: #d14 } /* Literal.String.Escape */ -.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ -.highlight .si { color: #d14 } /* Literal.String.Interpol */ -.highlight .sx { color: #d14 } /* Literal.String.Other */ -.highlight .sr { color: #009926 } /* Literal.String.Regex */ -.highlight .s1 { color: #d14 } /* Literal.String.Single */ -.highlight .ss { color: #990073 } /* Literal.String.Symbol */ -.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #008080 } /* Name.Variable.Class */ -.highlight .vg { color: #008080 } /* Name.Variable.Global */ -.highlight .vi { color: #008080 } /* Name.Variable.Instance */ -.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ - -.type-csharp .highlight .k { color: #0000FF } -.type-csharp .highlight .kt { color: #0000FF } -.type-csharp .highlight .nf { color: #000000; font-weight: normal } -.type-csharp .highlight .nc { color: #2B91AF } -.type-csharp .highlight .nn { color: #000000 } -.type-csharp .highlight .s { color: #A31515 } -.type-csharp .highlight .sc { color: #A31515 } +.highlight .kc { color: #66d9ef } /* Keyword.Constant */ +.highlight .kd { color: #66d9ef } /* Keyword.Declaration */ +.highlight .kn { color: #f92672 } /* Keyword.Namespace */ +.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ +.highlight .kr { color: #66d9ef } /* Keyword.Reserved */ +.highlight .kt { color: #66d9ef } /* Keyword.Type */ +.highlight .ld { color: #e6db74 } /* Literal.Date */ +.highlight .m { color: #ae81ff } /* Literal.Number */ +.highlight .s { color: #e6db74 } /* Literal.String */ +.highlight .na { color: #a6e22e } /* Name.Attribute */ +.highlight .nb { color: #f8f8f2 } /* Name.Builtin */ +.highlight .nc { color: #a6e22e } /* Name.Class */ +.highlight .no { color: #66d9ef } /* Name.Constant */ +.highlight .nd { color: #a6e22e } /* Name.Decorator */ +.highlight .ni { color: #f8f8f2 } /* Name.Entity */ +.highlight .ne { color: #a6e22e } /* Name.Exception */ +.highlight .nf { color: #a6e22e } /* Name.Function */ +.highlight .nl { color: #f8f8f2 } /* Name.Label */ +.highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +.highlight .nx { color: #a6e22e } /* Name.Other */ +.highlight .py { color: #f8f8f2 } /* Name.Property */ +.highlight .nt { color: #f92672 } /* Name.Tag */ +.highlight .nv { color: #f8f8f2 } /* Name.Variable */ +.highlight .ow { color: #f92672 } /* Operator.Word */ +.highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +.highlight .mf { color: #ae81ff } /* Literal.Number.Float */ +.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ +.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ +.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ +.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ +.highlight .sc { color: #e6db74 } /* Literal.String.Char */ +.highlight .sd { color: #e6db74 } /* Literal.String.Doc */ +.highlight .s2 { color: #e6db74 } /* Literal.String.Double */ +.highlight .se { color: #ae81ff } /* Literal.String.Escape */ +.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ +.highlight .si { color: #e6db74 } /* Literal.String.Interpol */ +.highlight .sx { color: #e6db74 } /* Literal.String.Other */ +.highlight .sr { color: #e6db74 } /* Literal.String.Regex */ +.highlight .s1 { color: #e6db74 } /* Literal.String.Single */ +.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ +.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ +.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ +.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ +.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/stylesheets/styles.css b/stylesheets/styles.css new file mode 100644 index 000000000..466b9d68b --- /dev/null +++ b/stylesheets/styles.css @@ -0,0 +1,356 @@ +@import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700); +html { + background: #6C7989; + background: #6c7989 -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #6c7989), color-stop(100%, #434b55)) fixed; + background: #6c7989 -webkit-linear-gradient(#6c7989, #434b55) fixed; + background: #6c7989 -moz-linear-gradient(#6c7989, #434b55) fixed; + background: #6c7989 -o-linear-gradient(#6c7989, #434b55) fixed; + background: #6c7989 -ms-linear-gradient(#6c7989, #434b55) fixed; + background: #6c7989 linear-gradient(#6c7989, #434b55) fixed; +} + +body { + padding: 50px 0; + margin: 0; + font: 14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #555; + font-weight: 300; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAeCAYAAABNChwpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAAUdEVYdENyZWF0aW9uIFRpbWUAMy82LzEygrTcTAAAAFRJREFUSIljfPDggZRf5RIGGNjUHsNATz6jXmSL1Kb2GLiAX+USBnrymRgGGDCORgFmoNAXjEbBaBSMRsFoFIxGwWgUjEbBaBSMRsFoFIxGwWgUAABYNujumib3wAAAAABJRU5ErkJggg==') fixed; +} + +.wrapper { + width: 640px; + margin: 0 auto; + background: #DEDEDE; + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + -ms-border-radius: 8px; + -o-border-radius: 8px; + border-radius: 8px; + -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; + -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; + box-shadow: rgba(0, 0, 0, 0.2) 0 0 0 1px, rgba(0, 0, 0, 0.45) 0 3px 10px; +} + +header, section, footer { + display: block; +} + +a { + color: #069; + text-decoration: none; +} + +p { + margin: 0 0 20px; + padding: 0; +} + +strong { + color: #222; + font-weight: 700; +} + +header { + -webkit-border-radius: 8px 8px 0 0; + -moz-border-radius: 8px 8px 0 0; + -ms-border-radius: 8px 8px 0 0; + -o-border-radius: 8px 8px 0 0; + border-radius: 8px 8px 0 0; + background: #C6EAFA; + background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ddfbfc), color-stop(100%, #c6eafa)); + background: -webkit-linear-gradient(#ddfbfc, #c6eafa); + background: -moz-linear-gradient(#ddfbfc, #c6eafa); + background: -o-linear-gradient(#ddfbfc, #c6eafa); + background: -ms-linear-gradient(#ddfbfc, #c6eafa); + background: linear-gradient(#ddfbfc, #c6eafa); + position: relative; + padding: 15px 20px; + border-bottom: 1px solid #B2D2E1; +} +header h1 { + margin: 0; + padding: 0; + font-size: 24px; + line-height: 1.2; + color: #069; + text-shadow: rgba(255, 255, 255, 0.9) 0 1px 0; +} +header.without-description h1 { + margin: 10px 0; +} +header p { + margin: 0; + color: #61778B; + width: 300px; + font-size: 13px; +} +header p.view { + display: none; + font-weight: 700; + text-shadow: rgba(255, 255, 255, 0.9) 0 1px 0; + -webkit-font-smoothing: antialiased; +} +header p.view a { + color: #06c; +} +header p.view small { + font-weight: 400; +} +header ul { + margin: 0; + padding: 0; + list-style: none; + position: absolute; + z-index: 1; + right: 20px; + top: 20px; + height: 38px; + padding: 1px 0; + background: #5198DF; + background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #77b9fb), color-stop(100%, #3782cd)); + background: -webkit-linear-gradient(#77b9fb, #3782cd); + background: -moz-linear-gradient(#77b9fb, #3782cd); + background: -o-linear-gradient(#77b9fb, #3782cd); + background: -ms-linear-gradient(#77b9fb, #3782cd); + background: linear-gradient(#77b9fb, #3782cd); + border-radius: 5px; + -webkit-box-shadow: inset rgba(255, 255, 255, 0.45) 0 1px 0, inset rgba(0, 0, 0, 0.2) 0 -1px 0; + -moz-box-shadow: inset rgba(255, 255, 255, 0.45) 0 1px 0, inset rgba(0, 0, 0, 0.2) 0 -1px 0; + box-shadow: inset rgba(255, 255, 255, 0.45) 0 1px 0, inset rgba(0, 0, 0, 0.2) 0 -1px 0; + width: auto; +} +header ul:before { + content: ''; + position: absolute; + z-index: -1; + left: -5px; + top: -4px; + right: -5px; + bottom: -6px; + background: rgba(0, 0, 0, 0.1); + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + -ms-border-radius: 8px; + -o-border-radius: 8px; + border-radius: 8px; + -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0, inset rgba(255, 255, 255, 0.7) 0 -1px 0; + -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0, inset rgba(255, 255, 255, 0.7) 0 -1px 0; + box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0, inset rgba(255, 255, 255, 0.7) 0 -1px 0; +} +header ul li { + width: 79px; + float: left; + border-right: 1px solid #3A7CBE; + height: 38px; +} +header ul li.single { + border: none; +} +header ul li + li { + width: 78px; + border-left: 1px solid #8BBEF3; +} +header ul li + li + li { + border-right: none; + width: 79px; +} +header ul a { + line-height: 1; + font-size: 11px; + color: #fff; + color: rgba(255, 255, 255, 0.8); + display: block; + text-align: center; + font-weight: 400; + padding-top: 6px; + height: 40px; + text-shadow: rgba(0, 0, 0, 0.4) 0 -1px 0; +} +header ul a strong { + font-size: 14px; + display: block; + color: #fff; + -webkit-font-smoothing: antialiased; +} + +section { + padding: 15px 20px; + font-size: 15px; + border-top: 1px solid #fff; + background: -webkit-gradient(linear, 50% 0%, 50% 700, color-stop(0%, #fafafa), color-stop(100%, #dedede)); + background: -webkit-linear-gradient(#fafafa, #dedede 700px); + background: -moz-linear-gradient(#fafafa, #dedede 700px); + background: -o-linear-gradient(#fafafa, #dedede 700px); + background: -ms-linear-gradient(#fafafa, #dedede 700px); + background: linear-gradient(#fafafa, #dedede 700px); + -webkit-border-radius: 0 0 8px 8px; + -moz-border-radius: 0 0 8px 8px; + -ms-border-radius: 0 0 8px 8px; + -o-border-radius: 0 0 8px 8px; + border-radius: 0 0 8px 8px; + position: relative; +} + +h1, h2, h3, h4, h5, h6 { + color: #222; + padding: 0; + margin: 0 0 20px; + line-height: 1.2; +} + +p, ul, ol, table, pre, dl { + margin: 0 0 20px; +} + +h1, h2, h3 { + line-height: 1.1; +} + +h1 { + font-size: 28px; +} + +h2 { + color: #393939; +} + +h3, h4, h5, h6 { + color: #494949; +} + +blockquote { + margin: 0 -20px 20px; + padding: 15px 20px 1px 40px; + font-style: italic; + background: #ccc; + background: rgba(0, 0, 0, 0.06); + color: #222; +} + +img { + max-width: 100%; +} + +code, pre { + font-family: Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + color: #333; + font-size: 12px; + overflow-x: auto; +} + +pre { + padding: 20px; + background: #3A3C42; + color: #f8f8f2; + margin: 0 -20px 20px; +} +pre code { + color: #f8f8f2; +} +li pre { + margin-left: -60px; + padding-left: 60px; +} + +table { + width: 100%; + border-collapse: collapse; +} + +th, td { + text-align: left; + padding: 5px 10px; + border-bottom: 1px solid #aaa; +} + +dt { + color: #222; + font-weight: 700; +} + +th { + color: #222; +} + +small { + font-size: 11px; +} + +hr { + border: 0; + background: #aaa; + height: 1px; + margin: 0 0 20px; +} + +footer { + width: 640px; + margin: 0 auto; + padding: 20px 0 0; + color: #ccc; + overflow: hidden; +} +footer a { + color: #fff; + font-weight: bold; +} +footer p { + float: left; +} +footer p + p { + float: right; +} + +@media print, screen and (max-width: 740px) { + body { + padding: 0; + } + + .wrapper { + -webkit-border-radius: 0; + -moz-border-radius: 0; + -ms-border-radius: 0; + -o-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + width: 100%; + } + + footer { + -webkit-border-radius: 0; + -moz-border-radius: 0; + -ms-border-radius: 0; + -o-border-radius: 0; + border-radius: 0; + padding: 20px; + width: auto; + } + footer p { + float: none; + margin: 0; + } + footer p + p { + float: none; + } +} +@media print, screen and (max-width:580px) { + header ul { + display: none; + } + + header p.view { + display: block; + } + + header p { + width: 100%; + } +} +@media print { + header p.view a small:before { + content: 'at http://github.com/'; + } +} From c141aaa62829207d1d9f87e0c2fa7e219896488d Mon Sep 17 00:00:00 2001 From: sta Date: Tue, 25 Feb 2014 17:19:56 +0900 Subject: [PATCH 14/27] Create gh-pages branch via GitHub --- index.html | 6 +++--- params.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 5cf41a7a3..fade78e89 100644 --- a/index.html +++ b/index.html @@ -27,8 +27,8 @@

websocket-sharp

-

-Welcome to websocket-sharp!

+

+Welcome to websocket-sharp!

websocket-sharp supports the followings:

@@ -513,7 +513,7 @@

ws.Log.Level = LogLevel.DEBUG;
 
-

This means a log with less than LogLevel.DEBUG isn't outputted.

+

This means a log with less than LogLevel.DEBUG cannot be outputted.

And if you would like to output a log, you should use any of the output methods. The following outputs a log with LogLevel.DEBUG.

diff --git a/params.json b/params.json index 898bdd906..2ca3f7f94 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"# Welcome to websocket-sharp! #\r\n\r\n**websocket-sharp** supports the followings:\r\n\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Branches ##\r\n\r\n- **[master]** for production releases.\r\n- **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.\r\n- **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) built yourself to the library references of your project.\r\n\r\nIf you would like to use that websocket-sharp.dll in your **[Unity]** project, you should add that dll to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket message.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.TEXT` or `WebSocketSharp.Opcode.BINARY` that represents the type of the received message. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` is `Opcode.TEXT`, you should use `e.Data` property (returns a `string`) that represents the received **Text** message.\r\n\r\nOr if `e.Type` is `Opcode.BINARY`, you should use `e.RawData` property (returns a `byte []`) that represents the received **Binary** message.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT) {\r\n // Do something with e.Data\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY) {\r\n // Do something with e.RawData\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message. So you should use it to get the error message.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code that indicates the reason for closure, and `e.Reason` property returns a `string` that represents the reason for closure. So you should use them to get the reason for closure.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending a data to the WebSocket server.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte [])`, and `WebSocket.Send (System.IO.FileInfo)` methods to send a data.\r\n\r\nIf you would like to send a data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```cs\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd if you would like to do something when the send is complete, you should set `completed` to any `Action`.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketService\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketServer` and `WebSocketService` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nIf you override the `WebSocketService.OnMessage (MessageEventArgs)` method, that overridden method is called when the `OnMessage` event of the current session's `WebSocket` occurs.\r\n\r\nAnd if you override the `WebSocketService.OnOpen ()`, `WebSocketService.OnError (ErrorEventArgs)`, and `WebSocketService.OnClose (CloseEventArgs)` methods, each of them is called when each event of the current session's `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client on the current session in the WebSocket service.\r\n\r\nIf you would like to access the sessions in the WebSocket service, you should use the `WebSocketService.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method broadcasts a data to all clients of the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified path to the service, using the `WebSocketServer.AddWebSocketService (string)` and `WebSocketServer.AddWebSocketService (string, Func)` methods.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit the `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the WebSocket service.\r\n\r\nIf you create an instance of the `WebSocketServer` class without a port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```cs\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified path to the service, using the `HttpServer.AddWebSocketService (string)` and `HttpServer.AddWebSocketService (string, Func)` methods.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension. (But it doesn't support with the [extension parameters].)\r\n\r\nIf you would like to enable this extension as a WebSocket client, you should set like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your client sends the following header with the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it returns the same header. And when your client receives that header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection (SSL)**.\r\n\r\nAs a **WebSocket Client**, you should create an instance of the `WebSocket` class with the **wss** scheme WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to set the custom validation for the server certificate, you should set the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate and returns valid.\r\n\r\nAs a **WebSocket Server**, you should create an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection. It's like the following.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```cs\r\nws.SetCredentials (username, password, preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest authentication (determined by the unauthorized response to the first connection request) credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting. It's like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = identity => {\r\n var expected = \"nobita\";\r\n return identity.Name == expected\r\n ? new NetworkCredential (expected, \"password\", \"gunfighter\") // User name, password, and roles\r\n : null; // If the user credentials not found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can access it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.ERROR` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThis means a log with less than `LogLevel.DEBUG` isn't outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[master]: https://github.com/sta/websocket-sharp/tree/master\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports the followings:\r\n\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Branches ##\r\n\r\n- **[master]** for production releases.\r\n- **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.\r\n- **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) built yourself to the library references of your project.\r\n\r\nIf you would like to use that websocket-sharp.dll in your **[Unity]** project, you should add that dll to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket message.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.TEXT` or `WebSocketSharp.Opcode.BINARY` that represents the type of the received message. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` is `Opcode.TEXT`, you should use `e.Data` property (returns a `string`) that represents the received **Text** message.\r\n\r\nOr if `e.Type` is `Opcode.BINARY`, you should use `e.RawData` property (returns a `byte []`) that represents the received **Binary** message.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT) {\r\n // Do something with e.Data\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY) {\r\n // Do something with e.RawData\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message. So you should use it to get the error message.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code that indicates the reason for closure, and `e.Reason` property returns a `string` that represents the reason for closure. So you should use them to get the reason for closure.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending a data to the WebSocket server.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte [])`, and `WebSocket.Send (System.IO.FileInfo)` methods to send a data.\r\n\r\nIf you would like to send a data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```cs\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd if you would like to do something when the send is complete, you should set `completed` to any `Action`.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketService\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketServer` and `WebSocketService` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nIf you override the `WebSocketService.OnMessage (MessageEventArgs)` method, that overridden method is called when the `OnMessage` event of the current session's `WebSocket` occurs.\r\n\r\nAnd if you override the `WebSocketService.OnOpen ()`, `WebSocketService.OnError (ErrorEventArgs)`, and `WebSocketService.OnClose (CloseEventArgs)` methods, each of them is called when each event of the current session's `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client on the current session in the WebSocket service.\r\n\r\nIf you would like to access the sessions in the WebSocket service, you should use the `WebSocketService.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method broadcasts a data to all clients of the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified path to the service, using the `WebSocketServer.AddWebSocketService (string)` and `WebSocketServer.AddWebSocketService (string, Func)` methods.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit the `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the WebSocket service.\r\n\r\nIf you create an instance of the `WebSocketServer` class without a port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```cs\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified path to the service, using the `HttpServer.AddWebSocketService (string)` and `HttpServer.AddWebSocketService (string, Func)` methods.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension. (But it doesn't support with the [extension parameters].)\r\n\r\nIf you would like to enable this extension as a WebSocket client, you should set like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your client sends the following header with the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it returns the same header. And when your client receives that header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection (SSL)**.\r\n\r\nAs a **WebSocket Client**, you should create an instance of the `WebSocket` class with the **wss** scheme WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to set the custom validation for the server certificate, you should set the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate and returns valid.\r\n\r\nAs a **WebSocket Server**, you should create an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection. It's like the following.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```cs\r\nws.SetCredentials (username, password, preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest authentication (determined by the unauthorized response to the first connection request) credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting. It's like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = identity => {\r\n var expected = \"nobita\";\r\n return identity.Name == expected\r\n ? new NetworkCredential (expected, \"password\", \"gunfighter\") // User name, password, and roles\r\n : null; // If the user credentials not found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can access it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.ERROR` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThis means a log with less than `LogLevel.DEBUG` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[master]: https://github.com/sta/websocket-sharp/tree/master\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From 8ad7c7eb990154aa54f844f081987a3ad0c83946 Mon Sep 17 00:00:00 2001 From: sta Date: Wed, 26 Feb 2014 17:10:51 +0900 Subject: [PATCH 15/27] Create gh-pages branch via GitHub --- index.html | 26 ++++++++------------------ params.json | 2 +- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/index.html b/index.html index fade78e89..3ca8542e1 100644 --- a/index.html +++ b/index.html @@ -30,7 +30,7 @@

websocket-sharp

Welcome to websocket-sharp!

-

websocket-sharp supports the followings:

+

websocket-sharp supports:

-Branches

- -

Build

websocket-sharp is built as a single assembly, websocket-sharp.dll.

@@ -160,7 +150,7 @@
WebSocket.OnMessage Event
-

A WebSocket.OnMessage event occurs when the WebSocket receives a WebSocket message.

+

A WebSocket.OnMessage event occurs when the WebSocket receives a message.

ws.OnMessage += (sender, e) => {
   ...
@@ -212,7 +202,7 @@ 

e has passed as a WebSocketSharp.CloseEventArgs.

-

e.Code property returns a ushort that represents the status code that indicates the reason for closure, and e.Reason property returns a string that represents the reason for closure. So you should use them to get the reason for closure.

+

e.Code property returns a ushort that represents the status code indicating the reason for closure, and e.Reason property returns a string that represents the reason for closure. So you should use them to get the reason for closure.

Step 4

@@ -351,15 +341,15 @@

}

-

If you override the WebSocketService.OnMessage (MessageEventArgs) method, that overridden method is called when the OnMessage event of the current session's WebSocket occurs.

+

If you override the WebSocketService.OnMessage (MessageEventArgs) method, it's called when the OnMessage event of the WebSocket used by the current session in the WebSocket service occurs.

-

And if you override the WebSocketService.OnOpen (), WebSocketService.OnError (ErrorEventArgs), and WebSocketService.OnClose (CloseEventArgs) methods, each of them is called when each event of the current session's WebSocket (the OnOpen, OnError, and OnClose events) occurs.

+

And if you override the WebSocketService.OnOpen (), WebSocketService.OnError (ErrorEventArgs), and WebSocketService.OnClose (CloseEventArgs) methods, each of them is called when each event of the WebSocket (the OnOpen, OnError, and OnClose) occurs.

The WebSocketService.Send method sends a data to the client on the current session in the WebSocket service.

If you would like to access the sessions in the WebSocket service, you should use the WebSocketService.Sessions property (returns a WebSocketSharp.Server.WebSocketSessionManager).

-

The WebSocketService.Sessions.Broadcast method broadcasts a data to all clients of the WebSocket service.

+

The WebSocketService.Sessions.Broadcast method broadcasts a data to every client in the WebSocket service.

Step 3

@@ -372,7 +362,7 @@

wssv.AddWebSocketService<Chat> ("/ChatWithNiceBoat", () => new Chat (" Nice boat."));

-

You can add any WebSocket service to your WebSocketServer with the specified path to the service, using the WebSocketServer.AddWebSocketService<TWithNew> (string) and WebSocketServer.AddWebSocketService<T> (string, Func<T>) methods.

+

You can add any WebSocket service to your WebSocketServer with the specified path to the service, using the WebSocketServer.AddWebSocketService<TWithNew> (string) or WebSocketServer.AddWebSocketService<T> (string, Func<T>) method.

The type of TWithNew must inherit the WebSocketService class and must have a public parameterless constructor.

@@ -412,7 +402,7 @@

So websocket-sharp provides the WebSocketSharp.Server.HttpServer class.

-

You can add any WebSocket service to your HttpServer with the specified path to the service, using the HttpServer.AddWebSocketService<TWithNew> (string) and HttpServer.AddWebSocketService<T> (string, Func<T>) methods.

+

You can add any WebSocket service to your HttpServer with the specified path to the service, using the HttpServer.AddWebSocketService<TWithNew> (string) or HttpServer.AddWebSocketService<T> (string, Func<T>) method.

var httpsv = new HttpServer (4649);
 httpsv.AddWebSocketService<Echo> ("/Echo");
diff --git a/params.json b/params.json
index 2ca3f7f94..42055a557 100644
--- a/params.json
+++ b/params.json
@@ -1 +1 @@
-{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports the followings:\r\n\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Branches ##\r\n\r\n- **[master]** for production releases.\r\n- **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.\r\n- **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) built yourself to the library references of your project.\r\n\r\nIf you would like to use that websocket-sharp.dll in your **[Unity]** project, you should add that dll to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n    PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n  public class Program\r\n  {\r\n    public static void Main (string [] args)\r\n    {\r\n      using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n        ws.OnMessage += (sender, e) =>\r\n          Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n        ws.Connect ();\r\n        ws.Send (\"BALUS\");\r\n        Console.ReadKey (true);\r\n      }\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n  ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) => {\r\n  ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket message.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) => {\r\n  ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.TEXT` or `WebSocketSharp.Opcode.BINARY` that represents the type of the received message. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` is `Opcode.TEXT`, you should use `e.Data` property (returns a `string`) that represents the received **Text** message.\r\n\r\nOr if `e.Type` is `Opcode.BINARY`, you should use `e.RawData` property (returns a `byte []`) that represents the received **Binary** message.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT) {\r\n  // Do something with e.Data\r\n  return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY) {\r\n  // Do something with e.RawData\r\n  return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) => {\r\n  ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message. So you should use it to get the error message.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) => {\r\n  ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code that indicates the reason for closure, and `e.Reason` property returns a `string` that represents the reason for closure. So you should use them to get the reason for closure.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending a data to the WebSocket server.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte [])`, and `WebSocket.Send (System.IO.FileInfo)` methods to send a data.\r\n\r\nIf you would like to send a data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```cs\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd if you would like to do something when the send is complete, you should set `completed` to any `Action`.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n  public class Laputa : WebSocketService\r\n  {\r\n    protected override void OnMessage (MessageEventArgs e)\r\n    {\r\n      var msg = e.Data == \"BALUS\"\r\n              ? \"I've been balused already...\"\r\n              : \"I'm not available now.\";\r\n\r\n      Send (msg);\r\n    }\r\n  }\r\n\r\n  public class Program\r\n  {\r\n    public static void Main (string [] args)\r\n    {\r\n      var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n      wssv.AddWebSocketService (\"/Laputa\");\r\n      wssv.Start ();\r\n      Console.ReadKey (true);\r\n      wssv.Stop ();\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketServer` and `WebSocketService` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n  protected override void OnMessage (MessageEventArgs e)\r\n  {\r\n    Send (e.Data);\r\n  }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n  private string _suffix;\r\n\r\n  public Chat ()\r\n    : this (null)\r\n  {\r\n  }\r\n\r\n  public Chat (string suffix)\r\n  {\r\n    _suffix = suffix ?? String.Empty;\r\n  }\r\n\r\n  protected override void OnMessage (MessageEventArgs e)\r\n  {\r\n    Sessions.Broadcast (e.Data + _suffix);\r\n  }\r\n}\r\n```\r\n\r\nIf you override the `WebSocketService.OnMessage (MessageEventArgs)` method, that overridden method is called when the `OnMessage` event of the current session's `WebSocket` occurs.\r\n\r\nAnd if you override the `WebSocketService.OnOpen ()`, `WebSocketService.OnError (ErrorEventArgs)`, and `WebSocketService.OnClose (CloseEventArgs)` methods, each of them is called when each event of the current session's `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client on the current session in the WebSocket service.\r\n\r\nIf you would like to access the sessions in the WebSocket service, you should use the `WebSocketService.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method broadcasts a data to all clients of the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified path to the service, using the `WebSocketServer.AddWebSocketService (string)` and `WebSocketServer.AddWebSocketService (string, Func)` methods.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit the `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the WebSocket service.\r\n\r\nIf you create an instance of the `WebSocketServer` class without a port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n    $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```cs\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified path to the service, using the `HttpServer.AddWebSocketService (string)` and `HttpServer.AddWebSocketService (string, Func)` methods.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension. (But it doesn't support with the [extension parameters].)\r\n\r\nIf you would like to enable this extension as a WebSocket client, you should set like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your client sends the following header with the connection request to the server.\r\n\r\n    Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it returns the same header. And when your client receives that header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection (SSL)**.\r\n\r\nAs a **WebSocket Client**, you should create an instance of the `WebSocket` class with the **wss** scheme WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n  ...\r\n}\r\n```\r\n\r\nAnd if you would like to set the custom validation for the server certificate, you should set the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {\r\n  // Do something to validate the server certificate.\r\n  return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate and returns valid.\r\n\r\nAs a **WebSocket Server**, you should create an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection. It's like the following.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```cs\r\nws.SetCredentials (username, password, preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest authentication (determined by the unauthorized response to the first connection request) credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting. It's like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = identity => {\r\n  var expected = \"nobita\";\r\n  return identity.Name == expected\r\n         ? new NetworkCredential (expected, \"password\", \"gunfighter\") // User name, password, and roles\r\n         : null; // If the user credentials not found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can access it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.ERROR` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThis means a log with less than `LogLevel.DEBUG` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[master]: https://github.com/sta/websocket-sharp/tree/master\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."}
\ No newline at end of file
+{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) built yourself to the library references of your project.\r\n\r\nIf you would like to use that websocket-sharp.dll in your **[Unity]** project, you should add that dll to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n    PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n  public class Program\r\n  {\r\n    public static void Main (string [] args)\r\n    {\r\n      using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n        ws.OnMessage += (sender, e) =>\r\n          Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n        ws.Connect ();\r\n        ws.Send (\"BALUS\");\r\n        Console.ReadKey (true);\r\n      }\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n  ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) => {\r\n  ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) => {\r\n  ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.TEXT` or `WebSocketSharp.Opcode.BINARY` that represents the type of the received message. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` is `Opcode.TEXT`, you should use `e.Data` property (returns a `string`) that represents the received **Text** message.\r\n\r\nOr if `e.Type` is `Opcode.BINARY`, you should use `e.RawData` property (returns a `byte []`) that represents the received **Binary** message.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT) {\r\n  // Do something with e.Data\r\n  return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY) {\r\n  // Do something with e.RawData\r\n  return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) => {\r\n  ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message. So you should use it to get the error message.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) => {\r\n  ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code indicating the reason for closure, and `e.Reason` property returns a `string` that represents the reason for closure. So you should use them to get the reason for closure.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending a data to the WebSocket server.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte [])`, and `WebSocket.Send (System.IO.FileInfo)` methods to send a data.\r\n\r\nIf you would like to send a data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```cs\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd if you would like to do something when the send is complete, you should set `completed` to any `Action`.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n  public class Laputa : WebSocketService\r\n  {\r\n    protected override void OnMessage (MessageEventArgs e)\r\n    {\r\n      var msg = e.Data == \"BALUS\"\r\n              ? \"I've been balused already...\"\r\n              : \"I'm not available now.\";\r\n\r\n      Send (msg);\r\n    }\r\n  }\r\n\r\n  public class Program\r\n  {\r\n    public static void Main (string [] args)\r\n    {\r\n      var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n      wssv.AddWebSocketService (\"/Laputa\");\r\n      wssv.Start ();\r\n      Console.ReadKey (true);\r\n      wssv.Stop ();\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketServer` and `WebSocketService` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n  protected override void OnMessage (MessageEventArgs e)\r\n  {\r\n    Send (e.Data);\r\n  }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n  private string _suffix;\r\n\r\n  public Chat ()\r\n    : this (null)\r\n  {\r\n  }\r\n\r\n  public Chat (string suffix)\r\n  {\r\n    _suffix = suffix ?? String.Empty;\r\n  }\r\n\r\n  protected override void OnMessage (MessageEventArgs e)\r\n  {\r\n    Sessions.Broadcast (e.Data + _suffix);\r\n  }\r\n}\r\n```\r\n\r\nIf you override the `WebSocketService.OnMessage (MessageEventArgs)` method, it's called when the `OnMessage` event of the `WebSocket` used by the current session in the WebSocket service occurs.\r\n\r\nAnd if you override the `WebSocketService.OnOpen ()`, `WebSocketService.OnError (ErrorEventArgs)`, and `WebSocketService.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose`) occurs.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client on the current session in the WebSocket service.\r\n\r\nIf you would like to access the sessions in the WebSocket service, you should use the `WebSocketService.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method broadcasts a data to every client in the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified path to the service, using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit the `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the WebSocket service.\r\n\r\nIf you create an instance of the `WebSocketServer` class without a port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n    $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```cs\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified path to the service, using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension. (But it doesn't support with the [extension parameters].)\r\n\r\nIf you would like to enable this extension as a WebSocket client, you should set like the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your client sends the following header with the connection request to the server.\r\n\r\n    Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it returns the same header. And when your client receives that header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection (SSL)**.\r\n\r\nAs a **WebSocket Client**, you should create an instance of the `WebSocket` class with the **wss** scheme WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n  ...\r\n}\r\n```\r\n\r\nAnd if you would like to set the custom validation for the server certificate, you should set the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {\r\n  // Do something to validate the server certificate.\r\n  return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate and returns valid.\r\n\r\nAs a **WebSocket Server**, you should create an instance of the `WebSocketServer` or `HttpServer` class with some settings for the secure connection. It's like the following.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.Certificate = new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```cs\r\nws.SetCredentials (username, password, preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest authentication (determined by the unauthorized response to the first connection request) credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting. It's like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = identity => {\r\n  var expected = \"nobita\";\r\n  return identity.Name == expected\r\n         ? new NetworkCredential (expected, \"password\", \"gunfighter\") // User name, password, and roles\r\n         : null; // If the user credentials not found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set like the following.\r\n\r\n```cs\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can access it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.ERROR` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThis means a log with less than `LogLevel.DEBUG` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."}
\ No newline at end of file

From 012873a44f65b4ea674086ece0ebf106e4576d58 Mon Sep 17 00:00:00 2001
From: sta 
Date: Sat, 14 Jun 2014 16:13:10 +0900
Subject: [PATCH 16/27] Create gh-pages branch via GitHub

---
 fonts/OpenSans-Bold-webfont.eot            | Bin 0 -> 21190 bytes
 fonts/OpenSans-Bold-webfont.svg            | 146 +++
 fonts/OpenSans-Bold-webfont.ttf            | Bin 0 -> 21012 bytes
 fonts/OpenSans-Bold-webfont.woff           | Bin 0 -> 14036 bytes
 fonts/OpenSans-BoldItalic-webfont.eot      | Bin 0 -> 23510 bytes
 fonts/OpenSans-BoldItalic-webfont.svg      | 146 +++
 fonts/OpenSans-BoldItalic-webfont.ttf      | Bin 0 -> 23304 bytes
 fonts/OpenSans-BoldItalic-webfont.woff     | Bin 0 -> 15572 bytes
 fonts/OpenSans-Italic-webfont.eot          | Bin 0 -> 23866 bytes
 fonts/OpenSans-Italic-webfont.svg          | 146 +++
 fonts/OpenSans-Italic-webfont.ttf          | Bin 0 -> 23680 bytes
 fonts/OpenSans-Italic-webfont.woff         | Bin 0 -> 15836 bytes
 fonts/OpenSans-Light-webfont.eot           | Bin 0 -> 20886 bytes
 fonts/OpenSans-Light-webfont.svg           | 146 +++
 fonts/OpenSans-Light-webfont.ttf           | Bin 0 -> 20704 bytes
 fonts/OpenSans-Light-webfont.woff          | Bin 0 -> 13972 bytes
 fonts/OpenSans-LightItalic-webfont.eot     | Bin 0 -> 24074 bytes
 fonts/OpenSans-LightItalic-webfont.svg     | 146 +++
 fonts/OpenSans-LightItalic-webfont.ttf     | Bin 0 -> 23864 bytes
 fonts/OpenSans-LightItalic-webfont.woff    | Bin 0 -> 15944 bytes
 fonts/OpenSans-Regular-webfont.eot         | Bin 0 -> 20878 bytes
 fonts/OpenSans-Regular-webfont.svg         | 146 +++
 fonts/OpenSans-Regular-webfont.ttf         | Bin 0 -> 20688 bytes
 fonts/OpenSans-Regular-webfont.woff        | Bin 0 -> 13988 bytes
 fonts/OpenSans-Semibold-webfont.eot        | Bin 0 -> 21046 bytes
 fonts/OpenSans-Semibold-webfont.svg        | 146 +++
 fonts/OpenSans-Semibold-webfont.ttf        | Bin 0 -> 20852 bytes
 fonts/OpenSans-Semibold-webfont.woff       | Bin 0 -> 14052 bytes
 fonts/OpenSans-SemiboldItalic-webfont.eot  | Bin 0 -> 23882 bytes
 fonts/OpenSans-SemiboldItalic-webfont.svg  | 146 +++
 fonts/OpenSans-SemiboldItalic-webfont.ttf  | Bin 0 -> 23660 bytes
 fonts/OpenSans-SemiboldItalic-webfont.woff | Bin 0 -> 15748 bytes
 images/bullet.png                          | Bin 0 -> 1045 bytes
 images/hr.gif                              | Bin 0 -> 1121 bytes
 images/nav-bg.gif                          | Bin 0 -> 1238 bytes
 index.html                                 | 164 +++-
 javascripts/respond.js                     | 779 ++++++++++++++++
 params.json                                |   2 +-
 stylesheets/ie.css                         |   3 +
 stylesheets/normalize.css                  | 459 ++++++++++
 stylesheets/pygment_trac.css               | 130 +--
 stylesheets/styles.css                     | 999 +++++++++++++++------
 42 files changed, 3355 insertions(+), 349 deletions(-)
 create mode 100644 fonts/OpenSans-Bold-webfont.eot
 create mode 100644 fonts/OpenSans-Bold-webfont.svg
 create mode 100644 fonts/OpenSans-Bold-webfont.ttf
 create mode 100644 fonts/OpenSans-Bold-webfont.woff
 create mode 100644 fonts/OpenSans-BoldItalic-webfont.eot
 create mode 100644 fonts/OpenSans-BoldItalic-webfont.svg
 create mode 100644 fonts/OpenSans-BoldItalic-webfont.ttf
 create mode 100644 fonts/OpenSans-BoldItalic-webfont.woff
 create mode 100644 fonts/OpenSans-Italic-webfont.eot
 create mode 100644 fonts/OpenSans-Italic-webfont.svg
 create mode 100644 fonts/OpenSans-Italic-webfont.ttf
 create mode 100644 fonts/OpenSans-Italic-webfont.woff
 create mode 100644 fonts/OpenSans-Light-webfont.eot
 create mode 100644 fonts/OpenSans-Light-webfont.svg
 create mode 100644 fonts/OpenSans-Light-webfont.ttf
 create mode 100644 fonts/OpenSans-Light-webfont.woff
 create mode 100644 fonts/OpenSans-LightItalic-webfont.eot
 create mode 100644 fonts/OpenSans-LightItalic-webfont.svg
 create mode 100644 fonts/OpenSans-LightItalic-webfont.ttf
 create mode 100644 fonts/OpenSans-LightItalic-webfont.woff
 create mode 100644 fonts/OpenSans-Regular-webfont.eot
 create mode 100644 fonts/OpenSans-Regular-webfont.svg
 create mode 100644 fonts/OpenSans-Regular-webfont.ttf
 create mode 100644 fonts/OpenSans-Regular-webfont.woff
 create mode 100644 fonts/OpenSans-Semibold-webfont.eot
 create mode 100644 fonts/OpenSans-Semibold-webfont.svg
 create mode 100644 fonts/OpenSans-Semibold-webfont.ttf
 create mode 100644 fonts/OpenSans-Semibold-webfont.woff
 create mode 100644 fonts/OpenSans-SemiboldItalic-webfont.eot
 create mode 100644 fonts/OpenSans-SemiboldItalic-webfont.svg
 create mode 100644 fonts/OpenSans-SemiboldItalic-webfont.ttf
 create mode 100644 fonts/OpenSans-SemiboldItalic-webfont.woff
 create mode 100644 images/bullet.png
 create mode 100644 images/hr.gif
 create mode 100644 images/nav-bg.gif
 create mode 100644 javascripts/respond.js
 create mode 100644 stylesheets/ie.css
 create mode 100644 stylesheets/normalize.css

diff --git a/fonts/OpenSans-Bold-webfont.eot b/fonts/OpenSans-Bold-webfont.eot
new file mode 100644
index 0000000000000000000000000000000000000000..e1c7674430d0dc4eb95a461948412adcd3194385
GIT binary patch
literal 21190
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
+
+
+
+This is a custom SVG webfont generated by Font Squirrel.
+Copyright   : Digitized data copyright  20102011 Google Corporation
+Foundry     : Ascender Corporation
+Foundry URL : httpwwwascendercorpcom
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
\ No newline at end of file
diff --git a/fonts/OpenSans-Bold-webfont.ttf b/fonts/OpenSans-Bold-webfont.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..2d94f0629db751b8412a814df98fbe82f6fdd1df
GIT binary patch
literal 21012
zcmbt+3w#vS+4ng!v$NN1_L|M+x|>Z1F$p2Ngft)!5CH>3h!_J#J=fGeE;XnZlwL%?|pyYOPHO@&dhnv
zbDr~D{?BukamJVj9|~h5Mobuc^&?OJoiXmh)q;`3FCM{?OvZU{oJTIbtR}v3?rj(1
zd=$>7OrJY-{+TPQ=zJ@-7pLE_IAS+k!x@to6*~~M48v6jwZHx_{GHb@vj?Ni7Z)2=!7QXL43m39emOtZs1I|ll&0TzB
zMRUb!oIi{A1+JSned-IJyz>QPWB!WvU2~`2IG=Cizh-Rghqym-{nWWLN^2WIUo(2g
z_s*ZUXmP^b=Qv}R?!)=Z^B2yT|7l;})r^h57x&+Vjkv*HxO-kL?O#&2wx;)!#5Zo7
z<+Z(=5!|;?-1l4D$0D9c
zZlvH}@9X}c`l=#-=FM<*T~f3)Pi!|zRv5EuT3|2PId
zb2BHd(RThnd?_my)oQaloUSZ)w#V!92ZA}F+;CogL19sGBw7+HE$da@yW)b%s_H&9
zeQV>1es%rpf6y>s;Dv(*4{01a>>^0*$WfOxjUF?$`ODQZ|L0?jvKU!#;P31k
zX7F14^=E%!U$IVJ#e4BAwnk%B8uO3VE*RIQHQg{#W3eH*np)X5Xrj2bVq)Yk8u$0f
zt=4!|gxVEU)II&t&s_4;ZEP7MhyZNt7%*TCg
zUHP9+%#TGiOJ$oj;)aRhi-{BQK1)?r`=n}3t

QU1&XWS9^QD#_$?zm0l_?HTGPx zRr$P;hMH>4UKLqEjXaC@M>M(Yl2}AjdNpZmT-(|iYo|u&;0O89=*0ZB;;h9yqXr!& zb)I}r6pc8mB7YX$aaBcXG;3vhTO=|vHe%|WNL!?1n)wR4FN<16(~-52k!wdxjjfHW zjfv)B8f$6O8gVE3N6l)DGw1}*xJ65Y4(CRr`H{nG!3I2Z323`KO&jRLZP`_^$l-M3 zu}ItK%krZdpV+n*9l9j8HWpcX$=cXdqJ+9bpG1#`hQWtn@KOip!1pg50HLuFv8i*W zoZl0A)L(^8tX)HFYwC!twQ7-ZZ5QV6!#9Ddove{J4jaZt@Ak0iOnlPKmxJ=i+LpH1 zG*BNKmX95e4Fl&JTiTK=!Y-OVEXgArJ1sI@3(qJJl;VxSDh*e`7kpHch;qiE4YDy4 z_d_Zj&^I!(vJ0X2Ijc-57UohalU&BJRUC88R->`QDaFQ|N~NZFbPKOc$>L16^GepY zHsOtW%c9=se)*EFVrf~|8q2P;O|z7b(8iMPWBd)Y;Y5p9vZM>|)$BDXSz&&ql4~A% zwdRVaR0k`<+p{u9JKZX?Ri?6SEEkuvYf^4;qE(~gu_cpQFT1k6WkS2cCndgGH=(ty<59kWT!RGX9ZrQ!D#IQ<2UG^d zSu&VIcL)9U%AK}g4j5}S@3PjUY~~$S8{J`5?3G&3qdW1aOMIb6d8O7rZ_nU8Uyf$M zO2?kTN51@u4zxVaPASjouiPn%PnABkuxF<|Y{Nm0XQv~_iG!eLXI9XK+dSgaD?S7C zN%w@rJ$NctJcW1WXWmngc~2qTv$H63XE9xu8$FUtyzqF5X=Ez;{L4SBF^|ThE?OU} zi~19Cg0^7P8VzE2{4s20iTYSI57u<@=-4A;pKE@r`LuDohD*j>3w9 zT6>jyizLhtYcN(v$2{aM@59RiIiWh0_pj^MtGw-lm+n6H@G47-yyCS*hSus>oCsHN-5Z z*O#TGFfPK0zA14;4hv5WV^h7h- zr9P08h}ZRtm8gE6u=9WS#SlL6*H0w3Z%%bq$EQq*SC5k`Pj|k_pZ%B1io{>|{GE?J z{`_yZuIN0w{M<@Xn|u#lJofSD?~04$0k(9XP#O4F2pOwoD_Am@c$ZJSiz>&Hc4Au% zF(^(9(u*9&wIYvJ9y#pQRmhZDqnBe>u$|6*`@==SNGkNoZW& zq$eB`+=%AlhH!&c1EEq~If5&uIQ8Lm8EtFj{p+KuWaZIvXx>r?QzBl^-P|7t4aQx) zz@?UD4~`yw{J@^~);`J$M)u=_OK%y+tBo~_p8m&I#^3qSl{0RcVWb9J)OvMm`>2MC z#`1ga-an!BXIHJ?^VWWnmA@3hVw#G9(7NGsar^u20u-JnLY zXVB&RF`>&#OikXSx0M>LM{kqaO6zB#n@KB^d~()e?3I?``7CJVqzrCy%`HR?O0o

@%hI6 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 GmH!73$*E-k literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-Bold-webfont.woff b/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..cd86852d0a0c1930dab144b687318df762aa7ad3 GIT binary patch literal 14036 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 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-BoldItalic-webfont.svg b/fonts/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 000000000..8392240a1 --- /dev/null +++ b/fonts/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-BoldItalic-webfont.ttf b/fonts/OpenSans-BoldItalic-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f74e0e3ca7fc8276e5ad7adf934032d4f6f8f7b6 GIT binary patch literal 23304 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 Jqg8+5{{i(PmP-Ht literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-BoldItalic-webfont.woff b/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..f3248c1142bc295baf37546c887f63cb021bdf00 GIT binary patch literal 15572 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

3m6 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 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-Italic-webfont.svg b/fonts/OpenSans-Italic-webfont.svg new file mode 100644 index 000000000..29c7497fe --- /dev/null +++ b/fonts/OpenSans-Italic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-Italic-webfont.ttf b/fonts/OpenSans-Italic-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..63f187e984b225756e2030556c4465eeaf8724e5 GIT binary patch literal 23680 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


@ftTG)1Ne;2W3;2T_!O!c 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 + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-Light-webfont.ttf b/fonts/OpenSans-Light-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b50ef9dcb5bc8984f50d4c770c6149661edc0f1d GIT binary patch literal 20704 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 NWyB80sJ;Tm{tu1K%R~SG literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-LightItalic-webfont.svg b/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 000000000..60765da83 --- /dev/null +++ b/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-LightItalic-webfont.ttf b/fonts/OpenSans-LightItalic-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5898c8c7818efebdfec1733d531b1417764fe59f GIT binary patch literal 23864 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 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-LightItalic-webfont.woff b/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..9c978dc30cebf694a34c54e2cd2ca53539acff7a GIT binary patch literal 15944 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
8{k>V($m&YfrUylNrC=o<~)tYxTU& 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 w=uX)Q(ZAw?^=XdvhzN+X2?81c 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 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-Regular-webfont.svg b/fonts/OpenSans-Regular-webfont.svg new file mode 100644 index 000000000..01038bb1c --- /dev/null +++ b/fonts/OpenSans-Regular-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-Regular-webfont.ttf b/fonts/OpenSans-Regular-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..05951e7b36b2352b1a69e2052d08fbffd77d5151 GIT binary patch literal 20688 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 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-Regular-webfont.woff b/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..274664b28e8ed522cf1753f933ca085d8c8cc330 GIT binary patch literal 13988 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 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-Semibold-webfont.eot b/fonts/OpenSans-Semibold-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..289aade3e229d405a8ba85c31018f08075e115dc GIT binary patch literal 21046 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 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-Semibold-webfont.svg b/fonts/OpenSans-Semibold-webfont.svg new file mode 100644 index 000000000..cc2ca4275 --- /dev/null +++ b/fonts/OpenSans-Semibold-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 2011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-Semibold-webfont.ttf b/fonts/OpenSans-Semibold-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6f15073125b8703bc52cbc0e06f30d16e7c2b512 GIT binary patch literal 20852 zcmbt+349b)w)eeN)qAJ+&c1Y~vxwP9nk0rDWC@E10hxfx4gxA5%K#z*1Bjr&0E&vs z%%EZfhpFnchzuf#3yKUPf)5>Bo&y?1WfR}|Gyd1JL-yfG(;1UzEp-ldhgIM#s=(0|IRzd&YQtE^UaJ6Jb>pz)5hL8vEY*)FQfex(KloItl3dl zX%l0E;%L7+W9GyekIY^>hq1wn@%%q<5I5M{E2o#!`Jj0Vz9-IS#3wE^Qt1wpM0**2 zgKubIh)RZ3&rFP&HkqP$QI2tzkFZJnJRWga%(7LHB;_+EeczphZpL@6!NJOV485L( zSm-lm&d~#GnRT^PA7cD>^qEp;+JO_A_>FlGN2X{o_BvX0KNB=G;9P*`6lP}kvfs0( z*|Y3{7Rn0ch6+Muq0yli!nvQZmKHo8!gHI&bAQBhEaVBLhBE*8xt1?l zUTfLcvbW`xmR&6`em3>9iJy)8Y|Ll3d^X~L|A>zV+_>YrpC7$KPH9D^T zhYw}NWVTpsc84>`<@R`e{y;D}B{eNQBQq;IClt<&UeoT{qT-U$vi9W_(GHbW z)z{T@?9{nS*KXZ=^t>KY+qbq~{{aJU7{!e9Nt)MvobLb#MRX zdi(_NkWHSnbV}<36I(B?J}(+4TJz@Lv+(W(;_^3FfBf&SG0Vox9%4(`BbbA&EY5bZ zy_nGh>;zZXH~9IUy}&+a$Jl%9E0q+Z5P*>kOG9p}}%EePsLu&WI^R*Grk>>5eciNqI$K@uSbXvMvTDwOvOpJj4V;j#ab@EAH9d}zvY$;mEkp(Vl7YH z>fUzCTI}6!cfw;QCb)SB(wP#dR6s@Q936qE%fWkGfU6PoxIE;}Sh}Ii4C0XM~Qg0vqt9exU891Z|)XkGYE@ zq2r0pBcb{MLo>oEA5p&w1L_x96$!2Cw<pvl~%A$q_*LTj?i%$Z@jjTKG-m@nku+ziFGx3`qz6q3v zR@K!<#)0}s&kUS+q$fDvy{OLOSghhM_<~<0B(9us zXa+Y{+Jg#_{ODR$nk7nXUaapu9 z8!uw*%cI_~H$UtR@00sA=ScILSD1EO>_1sKjXsvQe8IP)4+nbe$YM^sSGASJWjDQy zs~&o_>a2*HeJrRHB~EHmh33VZHK*+Lsjiy#<<%Xkq7})(fH{&|;1A1@<%4Sb4!ogH z-y5Ag7~Q_G{|$rt_8mIdwDhu>`jodw7ZT&@E^Hgfj#8gi48U9=MkF7POCFYt8PxyN!GtewlVOpOrk#XNi{*D+3QNn&K>j6*VSXE!LuV(6}E=ru#v^tw^%CMQT<0uC9CkF_{I6?7O;t{zHH+)O1gyly31CHOk_*nSQHjo<>`m6&J~# zMtiaY7eP;BQqYOVJmR-k{0`7>dL~6YgKwpZZ{eL8t?$WfeNPrW)0o}*WDebzyL%*= zINCbX z`WMyQr5_m_8+>8#_JKz()?DP98+c{|-=dGCqe1^$gFcFHrUUnBE@d{oWu;OGK@71% zR>B@;YEGG&8PybflX^`>EJsXGPBvKUD^mkyYJOC6JDMQ8F?WEt?oP5nqD#wE+i@-I zX;Q-;Et?m`6lWf0GoB?DOw1Ly1}!zqqg@L@OY<~oWput40_XEW;4~!%BF}16pLYj0 z1=GTLC3z_|nmd5IURns1**wKtSjsCqR8?0-VKprUh2E5GjBz7QdulWk{`w|t= z9?b)BH5o0FM@vI1&uHa&w03A^i@9Q0+NVM1qUK%P9|R&`PxNRC!`J&|0qpGR%{mp&NAyFK~*vwwK> zx&0k`E?d^K;{>_rwadr&Vcvbywk^MVv|)dzo=cbZ?4(Hi?Qj2j`pfVC`tW*Q$P3qB zx}6ju-^t%TbMo}*Z$EwbA>NMX|CVHJOv@Ql6L^>fkFJ8PXR#FGUk33noYWMv5$oF9 z!K5f@NG;pfq-J~6!q9QAW`=B;%d|qAvOQV}#K(zCr$_VQ((h~1I^bNG4R**iYKb>) z%LwPWF>2N6QzIl;nkN-(^ZT?Q_{6ku3LZ_ZQQLc8gwGz#yVl?kkxVv-r8uy-&QPy|dyeK5|IaxjvhCiGJkaNnbvATEBSV zfjKYzMqe^@@a@-kzU$^+)!uk3U%GVvnCXwzJ*sY7H*?pmdhGVY`rjJ$lk4h+espNu zg4_B0UUQ`1|Tk_->uP zTN;S(CP8XrGC0gtm*B1i%g}9n!{e)tnx$aCml7$E>Kya#xDqm#>smq}an;u_(aMgx~ zOgsLhm+L>_r(?sP`GFsPsTcW=V#gkJ?CWNT7Q z6)^Lpte72!hBLb4GU+X6nQA|-N)>UNVQ-X*n9WWf+sGu@ZFFg8wjwRbU{qz;3$q^# zdn4X4d`+CM)$fW+^JDx`eR52n$~S_BZqUe2u-tga^QjQg+4pX!AiZa;Tx7IUtEaUhQ=(A6VOO;0?940~hui zG^9`8p>@VwAw>47K)VyP+hOlw3h5tm z`?%^TQ3^x*T1Sv;B^=K%j)yvQ#(E` z-a8ULQ4Mrk1{-R4m0Ft86!VZuv(c1gmZ|3Bn%~nD^P5Sm{27oiv!5=_Bw<;QFfENi zEO?D-^Ty0hKk0doPfY?7qLsX>WGEaK^D4*S4KmvgQ+rXk|jviTnXn6zxBN_TN`%0wP*<+b@$w% zo2JZqo7+!b*t|hi_2c@t|LAn2wBp`nbEds|Zq%f*Ue7$V=eY-74q21`wC?CBj7`F< zGUZOwF3hiwO)%t7*yK2K*kF(06Kl)~TLM?pPhJaL8O;h)B3Hx^nqy#AGbY9+TumEI zOaS6wwZZaAZjZ3Aj>IHMUe!(VSqb@w1|yIWgaaL_BW6pX^u(z*-Z-Uqq zi}IV7YxnE>c(?t0`s)jOjsmIB6>~5T?I4Sp>>g&AK?N(tMf2cQn&LrQh70o`7EP9z zhg7H!xL4%VcH4ciT==rCQkR;v*Q9v^Ke<%jUZy4aN=tcTlFN&8X(?PuuBBQa&O|@Q*Bx zrnoB{Apgik_C8;z1dL9#SE#ANh19%QiUr_(cBTtMfXunqtC=W9(ZU#q#^61w zF0X2@Q7t~zM6&@`CM8IQS&k;w2}AfK3ENG=7s++;QPQ8M4IDV(n=^K2+16QaeWJH~ z^5jXe|&_8>sRl4V%@#J?Qs|8tv_U} z3*sL$yyln*BNNJ5!9Xl!q~4jvNk(KL9pNC4@c!~Yn)m5aPvz9%XD*&qNK~QK4PE&* zONKw$zKu)iwuCEGYQr1L1#42s{h;sX$xYI>h-8jx?P0pqB8P{v{p9eOcw4K{t&bPclM!s2Vbo3R?*ov6GCr?Fm~EfhJ1Mw9Al@ zWRj5r!3YEo2-LJ3ECOGJMm|g-#!Grrb0$F;a=dZ7+n+3pVJE|iKz*v2Ue#BlMtqvZ zuqYiE6sQl;V>q|45{|IXA0Y>?pjAjp(J&9^{F5iXx>tWj-@Lrzh>_oY?QnK_ZpLe$ zd^vx?+|9l38GQF|hsYeJIAY&~F zf8+)9Z)RTBg{khcxGm8u0y@j_xKm&djfxWiwI*Q&N@c=J@q?}8rNqoOH>o`=E#av+ z_!R;YPRo=;|835T@^LExlSTIrt2BHI3 z!o{ zm^1aJeq)A|bf30<(5T6^!$wvWTsr#5jkSG;4goKxw+uJ$G3{ZMtQ&iU#Y$;iMG>GX zWLXfY#{Jht71+X1RP&oDn2)D*p&MG78NBXJ(ikr?JmMmcmJCm`${2f}fgc!$te>E9_>7Vh{mrn4Ze;)bt?KjR2ILm)K^65WcI5P0%+T_VM-uj@fKX*)j zV+*h1xhK!Q|9{{(j*|www9n`4R=aqu)SsL9BmWiG8$Vk6?XqFDg9g3d_!rJIQuVUb z-@p6RHZDJ?>M#G7{)v8I=YQ|rO0p=>e^Yc>?}~8yYptZcF%~9)#Ay>LSLDr=>Eox@qLwu>5yBVMHa;bR|C_kWg$_a*{o!8Q*o&}X>Q;UL8ilo$wfpIg0BE1#;_y#SG>H0 zySIcF(4D`nNyopXwVQd*XNJPH$ZG@aDs&9qOLNTa)cs+t$DF>D#mJnK|vX z(KBzm1>@mtKJ3F`tkYCzE`c&?9{AKkitWU^G%NI; zMJn~b>Mi;|^fUQchkEekm{;J(rb*zj6^aP zWY-NhQg|uEGUkQA7Dhu}PdKuVzs_&v%k*jbeOtFm9z6)Q==bZ}^o{zGx204miRPD6 z-|}Vj?O=Tqb87=XD1Olt%&o}~D-#hR;yXbE#k3;iwZUUYtZM|fiD1u&W+|c#2lvUH zn&VPo^9jNW-qB|s&?^sK>GvY~wJ}1LG2$zIT1`Tftu!5WF&#Eo=qr69%uaL&Toy*; zN{9R88lyYvtomRxCHjmxH1ZQy8H z5Yd$Uana?-!38xMXi^aay&;EFN_A>p5l)mgAtM$14D8kRNd~N+(b^1pw z`VV?j7N38pIkzZ}uT0FHsi&B`ZV7E*F|>hd0!nWeT$E{4#>~;EqzW1s{7LXrvp|Rp z6avu(QV$f9hQ0f~mo}e0+dK+j&sJ&p#s1QU<~!TwjH~ERh9Z|7B7mnkXqli-=3DVyCs59q39QG|Y7!BbB%)-Z#YHPlvKtx!Xe3!T3w)_cyo)jx zg-;CY`uf>phsO2X5xihpd2!Ka-=?+lAq($z!Q&NlsrCdP%ux>agn&Pn7(79vh9|Ab zPKr~A%&KZ0WRvFBfdA*4F{-5J%Sf8S*#M-1j#{aM93;hD_9If^HR#8ws)B~<6QwZ%AjAfxT0+{ z$S1UNwt6%Ec1}WHA*IzfG917?`n)SCOaw26e|VT3PDXB zeAN-e5D{O{yN?gy8_g&Ms5|XYta`trdcD;P>gFg9VDgXN$w%d1>Y}`%pZ%`6rj1_H zQqb#Vb^pX~EBFl`5TiFD2^zI#hg(CgpSR7UwskD*rshp!aQ0a(VW9* zr6d!9xzZuCT@vYb)6sv%i7+c-r3XpY z{uL*J*tOwAGAvL6Ct_v;Ct_hksfO6qIMIAQkq_W~_yqlN{bl_{{Ym|!eFS%tru#(}9(;|D()Z|R3jZA+&+8BM*H`e`Ut*?V zJ1O_-WI=XwLK>}6!*mA0PDhepr-M+!WWi2yN0KTCD1-qO>`cMgOF*F==p3a%Y#2=v zvDZQx{wgMWOf-_K+59BWfV%h_e^NiIZ$7i-xs98je#*4tgX8-5vzzBjwaq(a*FAUN za|ig%*#!6=PS~M5HkrjD#BG>Z1J4uE3CJSpI9#G8!YgRygs^f5uSg}%Isiy`UsUX# zU}l849`eO}{wxs{C=q-P04C^dHS;w z*G(K+Go-fD^|RNH-~S1Qg>hv;o+o1tER>lxx7l*05CkTY#DFQ`vBXRQrZmBT$IPZS zn9|67Qxry;DN7lk*L|-v9XfO=MQIZ6k7HeT68ff^#oWX$IFjj9<=!% zOL+)gV{G_`yfn!dY@U007Sf}c?6QH?sotn~eIvKppvKV$Fgh$ij+C*)>s%`HsF{25gevXb)s>yip}Qv43KY+>S4#>0q^9lN_1azE-D}*p;l6#Z z7EJz0_3v#A1pWS^U0wVAy&pbxP{uknEyZ6H!*8mTh?o(K*2M7Cl@{x6mn?RFT4o@a zl6oc0%)2`!szv&j4-$x>n`4Q25xO#s0ck@*H(6LEf7DO8uWE6w!ikG81pzHW7UvH~ z%7cz#-*?~s5Gi!m04-XoU%udJZ?c!T&*_(60bgG@^yE$N_mGEQ-ZJ;wwI^i)(I?k@ zcy0H0D=t4F{S|YFsx#$0`0M~WZTJTX4FNxioFm}`X%g8W#V+imjfY$REBut+k=uD4 zek8q`pV7b7*XwJg^U~ht52bd^ots_K@Mc74hOF#HKUVTXEN!wPqZ6CJT1k7_v7XJq zPF0EcU|h5>_fmfx;*ZqANc<>z+F7_B6Q##5FKK>TLUjb*-xK4g$NO!_zld>Y7OVpi zy9hTA9u;}SfTZwxUZW`_{}ikM>W8}-GS5O{9SXVbYY8f{h@|SuO@tuO~}99 zg?C$kC?#BRU?oTpC9o2RVcg=Qyc2v#LMmEYaz!hQBC=TF;3obdG9*mjZN8{pybVbu zs$p!+?O<{vo=>FENy9VbEQ)@uqF=-T#!%2NFi&P+G{BRfL@297U7I}`hkE2le0W+3 zz_W%1NkPN`r#c+v3Xaw(KUVOkC2lx+i2XGbdgEc z!^SD$is~MW8{RPmH}H%Rw`;KR8Y*?P0LC4|YNPR{do_X`nU+G!!z&@55vD&)2Sc^1*IvCtcDn0p3aB#XVl> zs4w01=Rt?^Lp)#b7PKhCz*`@9J1b$$P|XZ)4lETUWzj_z@m987;Vo(*RKF25rd0@c zo_K2osd3rmNk%o607y(`3W=GPOs-Ut3$$k?BuXdPrT6I193yZa5V00PKU>|Y3hp9;opqNWso15ZQx$Q_vRlytY zoFOhdlfLRzraF&nHK3mX9E=xxSbJ#r8jqSoO;iz5HIun4o?~3qc(ksNI(Wy86{%g3 zSSY}x^~Rl=Vu%~1__eMm`FhEh;f}N`>)ZoEsijt6=s}2NRT-WsK&A%zkE(exPzgZ! zJgktX|303tJ+Bk2Q36c5&{9oIk^+3k|*Sq+mbs-Kcni2)}^5( zQ(Zz9@Y}z5zwEYjzUY7Sskb)Hs=S|s>am^a{G(U=89wE4I`X-XSZWr+f-B2UrcZD?|um-9i~tzXYi=x6jNmzV?1wqsiWO5``Mr0GfI1y5>ez0g8WyNO4 zf)(PHB7{x+#yTUc%8a^ct*b*l3}V{s@j}o;*hO1iQ>!WVC)7Ns zK{i57GT;hYAOfxcB48{K%}R(@Y{JX{HfLEmI zryp7_6#lH9*I25WEVpX)GqNA#%a4unWEd;sdUR z+c*}epi*#B+u$87DROJziE4gI`kF+o3%OwyWYyt@(Gch!xe2JY;D*d&!F!|0DOWpU z$-y*kxMGGVH0-gaIj8;g@R#2let)*hwRqj#%a$&BaETr;cg>m8ARI9a>5&Js^-fC4 zJ1-u1dDpAY#G#KSVNAm?rT`OT5`IDo`~)irws01*F(yabn1bXa2q{q0h2H}Vj&hPT zLS&C=WR4&?K^|X9HaS67s87SiG<*ilO4XwxT|}TiMpZ59zN%2sBTCQ06;)lh7}TUQ zhbKSV!OU!U`^V3=f9%}3p?MGb9S7fbE&2_Ur!J~-;A|y)TZ-O9G7wsV))2v$ zq#j5oP!7;e%PB-U;YHb+6i7oIKPqwHth=E1KvWtPYNHGpm^L$eQ|QxHPq@u*fh`so z7O7>bxv1=b>}Dw+cj}G(+Xpt@y=&~#EAQ!i=C3F3+uv}a{j_nfu8=#edGbcB|I`k( z-74#64c`36>kp1xdhK^LU5;a@`z#?}n z;fHCh`6=OqQJp8bWC2n7)#`_7HX0Dc{LY{GlO`h`^jCJ{sK$pE*5=*A-WF~iypDI$ z-?*vw@Zp6Edg?Lx_mhWzeLmK#-ZUgb^QQ1I(lF5d6#U;il{&~Z^ct;HgLpWKLJ(kS zT5||c_ym&C-V6sOf_z^afdnXJfnEbtrkQC~lH)7Zp`fNJ;jdG~QSj8alczuQz?qlB z&hi&$zx^g(Bpq!YzG#v5o>X{g`??$I4}c#0Q))qvgD^7((SyZ@C36+n!U$be(21A8 zpQu26A{RdI=(O6pe11_MsVjBO3pY=w-6Jg}yUsB-W}bz2X0ex9EQ{=C09Y9K*=wV}d&Pjn?4saJOLhFDChvu) zHahG{*ks|P-!WWY!M+d>vlk^ta;h`QK)(1(k{!*g)^-By0{BjeV?aDvV5ov<2n-ct zC8R6tNAz!uIxH8+5eZON;Oy%50kgfGyMaqjyGsK972>w)UrWy>N+sbWs1wUR!&&!*EyM z_v`8>rN=L2=+Aj~Ip3IU^xX?V$OGv6DjW=YN5LRr5}|kg101ZERMz|tIf!&fbe)_O zf2P?SH{M+WJgNzJR3;mbOgyECZCLs#7!GLw)Jv0D1}d9=TtxV<@u!oU?N6cI zLKU%e5rCyr0EWU!NC0XGG+#Ol9rqdr&*sxiuz`?>O5h7#C^UrgLHOB0I6P2lL2MZC zb|_h~^u&pox1BmQY1Wqq`H5F=zLi%$v0;a4Xr2DyTZPWNxAkLn!=#s_$F}jTU6>QN zfjQD@1WqzmNy5#e{bf{FW1JGs9)~Z>PsH^c%ik}!F_$#vgBWu*joD3Oc44sD0)rDn zr!iv>k9-`plv)PH?5l`n$Ta4RWJH{@sNR)nM~|yQ3(=SfV?kXg#+;1G4oa)I;PxS~ zMu3ItBn-K_5;y?1)>M*{2c;K8Qi2eelF?JAE;x1bv`_ahTDV}zTOY6H18(8w`OAXN z!nb(4x}l~Wk8RgKpD^szn)(Ni^oWvlyVvSu~?Leod{9V*NuLw3t=K80@*Xt z)J8b$2cC^ZtjSayLr|Q*5^->H3hald;K(f~B!6?v_(yvFx_;@14huU@S=VFXutm32 zERZ_AdPjPGb=Qu2rsqVeJBxL&1vc#O54=H&ewd(XN8jG-7LN&=4Li6}xdXhuF~MrR^m_Qq(bK3lKyBgD7Ho zBy$rxm_%kLF%q$hN!s%EU!Hn&X`l6z*FX5%RRdQ1YVHG196lhO(s_1h>t<7z-JSOA zdo7lof1s1;wF5bv_G@!i3mq~XHI!NGu7v-efm9B!5W5a(oyW}<=0veqAgY}5O3k8LjZ_j6C6xxI(5iq^)>08|sTt6ZUV=mcuQ&-_fiqp%m3KiE zTa;FX;f4rwf{KB#8DZS0-Mhbd>$MjLZoc~vU#-vTIavB(fA+E&J73^z_Xl-5`hNVw z3p;LJT!Nx>4xEcA3nACZY&MIzgdL*XjU0`8ye8x~9x z3MgI2sUS27@{U!Vsh7^v&KKbFdzBmR{dnd zHXeSyf#)}D(f_*b`2Xp%w)ziiHawLbd@A~P;u~c6|9hW{@-v+`)@VLPmP?0vWf^HYKu!wjafLi(`M`yb5<_lm6%7C-iTUddwr&(p#ObMyAi zk9~V|@5tW$2ll)1`u}lKn%BuI?q9jBt3C^Pfi3)-K0RttJ@QYv66|GCewHgSx8+I@ z(L(-Al)U9o3Dsd(NDH4@Ge5$;9S-+ZPNemDp-ZsKzRLgAT>o$6C9!Kv z>_Qhv8-)Ra&9camSD_eNvP9AXld86M&u@}H9Lm#Ywy+2nchdmDsiZ!|6~_h zTJM}M-IWVKPWXf5BlTfY~bc z>7@X}yMcBHpo%;ycJ7nHcV}Q9b?aXa5CC55-wOb@u~jYZ6E*6p&(KKOqD4p^hI#c? zzWl35x%#?o6M#k|oWmG#JN`=C7sX<}&`&lIG8) zoVj{E<`n;wA<7WwIfmNOurlP*pXd-e1@<6q)7t!J9vJQJ{3FY;(!=z3gwC{{Q8gN{ zY)59DqozULn3I~0MJ|9lc1K#O|>oGVc(HZ$NkEM)FH=(WoxY9n8kIgrI%JwO9ar8v{Fq>~i z4V!cqjtMOjOj)=;ob9uWWBbg#a13PgvCl=E#b=Y)1Z4%wGM!~{Y@D3W3h~)f3Zew_N)}Kivor|;BWje4!42*3Uf$v zk~mP%QwM3O;}5VjI^>eXA+e?A)oeL^hu(v6cQdE449Fk-t4RFZ!8Y^zrA%p$JW`$~ zZrU&t*6(bRZKl10eVYBa zBjgz6*yMQ6+1WYUx!$?gc`+%JG%x9OSE}n4*B*Dkz1Xd~zw=~z-t#Kn4&HIz-+G_& zzVH3Y$9&iNw)kECVg9{=yuiF**WiP}H*oRgkYk<&kCX3nEI zABECGwV`L|CtMI-6MjOhnB}m0;4}VF3@sr_!U=zS#rS7MCLMni>+Ur$`YX$X1+m@&t{6JCgW}ho_Gjz*q)W+rx@3L@yv9*;|_cqf4c|QGw~hzO>dck zt7)i}x)Jv#;wprF)MIg;h4V!0(wf4?;fXuY=UlYMVZ`+O>|c1EzWMWS3`ct=-emL< z0zIWT+P8hTwWpGQ`Q|Wia0O?tx8beR#G8qJgCpa>gAiJi(GIab2^xu_ zyVxAOX(oOqVid%UtG`WLD8^!H2ukR}xKFQZP*g!(886f1Ujz%y~eH*&$v z^Dr;w-46^l2q{UyoTgzfMFudBEMP`C=sAqJjbPsMVY>@a1=WsSi|T-4)cTj=FZe&c364k!9uv<|vKN{5%W096x#+I{<>;YKJRctlN=uF&$+$>Osi^U_d@W;e%sb{JZ z>aEH}z0{;o@0jwT1lR)&CmKn!5)B6$&YKbqI~tDaM8k%Ly(H1FqG5|98WuFHX^Dmz z4a?|6!-R&}ooKkwP$nlDZZuq}Mguwj1YO=x?_JEZsD(+u==%H`#QErsmuIxy8KDM> G*#8B1{{jR6 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-Semibold-webfont.woff b/fonts/OpenSans-Semibold-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..4e47cb1a69b2a7f0ca3336a5530008e6d5b423a9 GIT binary patch literal 14052 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 To$P%_2Tu721o2B~8}NSsFG&!4 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-SemiboldItalic-webfont.eot b/fonts/OpenSans-SemiboldItalic-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..50a8a6f7558e8dc27d16077ee37dd040bbec00e3 GIT binary patch literal 23882 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 Q9rxKDN}LW;y&?Ah00pQ#mH+?% literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-SemiboldItalic-webfont.svg b/fonts/OpenSans-SemiboldItalic-webfont.svg new file mode 100644 index 000000000..65b50e2a6 --- /dev/null +++ b/fonts/OpenSans-SemiboldItalic-webfont.svg @@ -0,0 +1,146 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Digitized data copyright 20102011 Google Corporation +Foundry : Ascender Corporation +Foundry URL : httpwwwascendercorpcom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-SemiboldItalic-webfont.ttf b/fonts/OpenSans-SemiboldItalic-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..55ba3120f765578c27764752b8ea0c25bdb24f99 GIT binary patch literal 23660 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 literal 0 HcmV?d00001 diff --git a/fonts/OpenSans-SemiboldItalic-webfont.woff b/fonts/OpenSans-SemiboldItalic-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..0adc6df1621cf92805c944d9c5b4908e29dfe938 GIT binary patch literal 15748 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 literal 0 HcmV?d00001 diff --git a/images/bullet.png b/images/bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..22ea54375ac8492b3c51cf6da0bfba787030e6d9 GIT binary patch literal 1045 zcmaJ=O-K}B7@ibMElse)x>0N3oSw5?98V->HIYF>5iUK zA`Lu5bm#{vC?X;w=x7lgyL9T*sXTTmFGV2OH|y@!L7T&T@AvXP&-=VT-;Kifxt{J| zH$f0R`J7b5r*C(49>o8{Pv7?AV*q8#Xu_I8HN}BMO0y~uVDSuTK#Y?R@n{4n4cmZ4dWW)fkR5n>5}VL{^~aW+Sr5{lATBNx7jWECM>py^tzM%5ye zkkmXh_8)PP86bocU)lJ`1N64~}H(jKdD$GkFi8&};*Mu=C6N$&UXgrpPv22!2 zrMWC0iDfx95#duQsfm>=b0v`+8^ydqi(wJ{`h8Vaq*?K`q0Gt?%>6K|7Cp}KZ=#S zlqz|jE8f;-HrN>f2WBg4$)%0t#jaI36bgN8`@Nj}IiRsO(?g)Qee+lH&GBcsu2Wkl zFCBT&_xy3&YHDb`?e40)*7fb$>q7tSN4El%;X-14`Lx|}Z~o~0K!1sNa^}RTSBEYK xuLp8pMev~G*qx4^U<$GJkL{hEhf4vXZ<2_8$_Xo1dk6i8n$M0)FVmCDe*jLcM%4fS literal 0 HcmV?d00001 diff --git a/images/hr.gif b/images/hr.gif new file mode 100644 index 0000000000000000000000000000000000000000..bdb4168de55a60c4d84ea1f5cb2dcbea7009c746 GIT binary patch literal 1121 zcmZ?wbhEHbWMyDxSj51fqO1Z0sw%3Aii)bLs?N^N3}B%6pF6@gK*1%kBoRp4*jE%J zCTFLXC?ut(XXe=|z2CiGNg*@ERw>-n*TA>HIW;5GqpB!1xXLdixhgx^GDXSWPQj+a zsv@@_H?<^Dp&~aYuh^=>Rw*$hKPlA;$OZ}PD=C1Llw{i~If5hKW)J z8<-g?n3?DqniyD`Sn4Pk85kPq8ye{wnCluESecqz85k-+ffCTRqLehNAQv~NT|l0# zQbtKhft9{~d3m{Bxv^e;QM$gNrKP35fswwEkuFe$ZgFK^Nn(X=Ua>OF1ees}+TSP$$Sz2y8{{ffi_eM3D1ke6TzeSPsO&CP|Y zE-nd5MYtEM!Nnn!1*!T$sm1xFMaii^<;ozd3ap%qQWHz^i$e1Ab6}wukda@KU!0L& zpx_*As%NO+o0y!L2ND76@b$Iw%quQQ%u7!7bg@+enxU7OnPO#O;%w<+?&@e}YU*le z=xXTbWaMgTZ0c%cXl`uj=;#8|>yn>bnwy$e0@Is<(CdU#FDNnO765H_NiE7OOHFYr z%Fk5*d)g`!w_7Z5ng`XJg4->YIQ8lS9itD5TBN9k2?5g&hzU=)Kn^_Vr{)3Edl4{U zGyebg_s{QNKYx7x_Vvr>Pai+LfA{vy>sK#dJb(7|$>T>4AKbrp_s;EGH*Z|OcJ<2T zOBXMkKX>-b=~E|996xsS$l*f=5A5H!chBx!J9li~wsp(qO&d3?U$=J6>QyUOEMK;C z$>K!|7tEhGch2ltGiOYnHg(G6NfRgZ_x1L4cXf8Ox3#u3H#IiY*VWckS5;P&mz9GzJE102GaYNdN!< literal 0 HcmV?d00001 diff --git a/images/nav-bg.gif b/images/nav-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..474396561daa9bebc874426b013e976333fe0153 GIT binary patch literal 1238 zcmZ?wbhEHbG+{7dXkcK_($X?DHC6o29pM|G;F4I92&8T7D+&^mvr|hHl2X$%^K6yg z@7}MZkeOnu6mIHk;9KCFnvv;IRg@ZBBb2320kUN}5%WiyPD~AkS7Qqokz3N?*Ucyj-u` zSTDaQUEk2s(o)~RNZ-gv7pOwFxH7LKu|hYmSQ%!5OKNd)QD#9&W`3Rm$i&2?{L&Iz zC7??oUdSzg8=F_G2lkF$a(=FUMPh-zp`HQAOE87LzW9~q=E7AMmjtCE+>6!V;*iRM zRQ;gT;{4L0QdGl)fawRsgeP1e2cGm(^ML8S2$--L|Nr~@=l8FlKfZta z`sMSdk00K@d;8|~tCugHKYRM*@uPti4*$!dV9LNIy>6iT3ec%8XM~CYHO;iDl5v%N=u513Jdb{a&xk?GBeWC zQd5$X5)DCA|t}XLPLUs0t5X0e0{vVJU!gqTwR=<93AZKY;CNqEG^8*hTC z__d<1|JvQk-S_wrYXxUpIrT POm websocket-sharp by sta - - - - + + + + + +

+
-
-

websocket-sharp

-

A C# implementation of the WebSocket protocol client and server

-

View the Project on GitHub sta/websocket-sharp

- -
+
+
+

websocket-sharp

+

A C# implementation of the WebSocket protocol client and server

+
+ Project maintained by sta + Hosted on GitHub Pages — Theme by mattgraham +
+

Welcome to websocket-sharp!

@@ -41,13 +52,24 @@

Per-message Compression extension
  • Secure Connection
  • HTTP Authentication
  • +
  • Query String, Origin header and Cookies
  • .NET 3.5 or later (includes compatible)
  • +Branches

    + +

    Build

    websocket-sharp is built as a single assembly, websocket-sharp.dll.

    -

    websocket-sharp is developed with MonoDevelop. So the simple way to build is to open websocket-sharp.sln and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.

    +

    websocket-sharp is developed with MonoDevelop. So the simple way to build is to open websocket-sharp.sln and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.

    Install

    @@ -78,7 +100,17 @@

    It's priced at US$15. I think your $15 makes this project more better and accelerated, Thank you!

    +

    It works with Unity Free, but there are some limitations:

    + +

    Using .NET API 2.0 compatibility level for iOS/Android requires to fix lack of some features for later than .NET 2.0, such as the System.Func<...> delegates (i've fixed it in the asset package).

    + +

    And it's priced at US$15. I think your $15 makes this project more better and accelerated, Thank you!

    Usage

    @@ -159,18 +191,18 @@

    e has passed as a WebSocketSharp.MessageEventArgs.

    -

    e.Type property returns either WebSocketSharp.Opcode.TEXT or WebSocketSharp.Opcode.BINARY that represents the type of the received message. So by checking it, you determine which item you should use.

    +

    e.Type property returns either WebSocketSharp.Opcode.Text or WebSocketSharp.Opcode.Binary that represents the type of the received message. So by checking it, you determine which item you should use.

    -

    If e.Type is Opcode.TEXT, you should use e.Data property (returns a string) that represents the received Text message.

    +

    If e.Type is Opcode.Text, you should use e.Data property (returns a string) that represents the received Text message.

    -

    Or if e.Type is Opcode.BINARY, you should use e.RawData property (returns a byte []) that represents the received Binary message.

    +

    Or if e.Type is Opcode.Binary, you should use e.RawData property (returns a byte []) that represents the received Binary message.

    -
    if (e.Type == Opcode.TEXT) {
    +
    if (e.Type == Opcode.Text) {
       // Do something with e.Data
       return;
     }
     
    -if (e.Type == Opcode.BINARY) {
    +if (e.Type == Opcode.Binary) {
       // Do something with e.RawData
       return;
     }
    @@ -224,7 +256,7 @@ 

    The WebSocket.Send method is overloaded.

    -

    You can use the WebSocket.Send (string), WebSocket.Send (byte []), and WebSocket.Send (System.IO.FileInfo) methods to send a data.

    +

    You can use the WebSocket.Send (string), WebSocket.Send (byte []), or WebSocket.Send (System.IO.FileInfo) method to send a data.

    If you would like to send a data asynchronously, you should use the WebSocket.SendAsync method.

    @@ -263,8 +295,8 @@

    protected override void OnMessage (MessageEventArgs e) { var msg = e.Data == "BALUS" - ? "I've been balused already..." - : "I'm not available now."; + ? "I've been balused already..." + : "I'm not available now."; Send (msg); } @@ -343,7 +375,7 @@

    If you override the WebSocketService.OnMessage (MessageEventArgs) method, it's called when the OnMessage event of the WebSocket used by the current session in the WebSocket service occurs.

    -

    And if you override the WebSocketService.OnOpen (), WebSocketService.OnError (ErrorEventArgs), and WebSocketService.OnClose (CloseEventArgs) methods, each of them is called when each event of the WebSocket (the OnOpen, OnError, and OnClose) occurs.

    +

    And if you override the WebSocketService.OnOpen (), WebSocketService.OnError (ErrorEventArgs), and WebSocketService.OnClose (CloseEventArgs) methods, each of them is called when each event of the WebSocket (the OnOpen, OnError, and OnClose events) occurs.

    The WebSocketService.Send method sends a data to the client on the current session in the WebSocket service.

    @@ -422,7 +454,7 @@

    If you would like to enable this extension as a WebSocket client, you should set like the following.

    -
    ws.Compression = CompressionMethod.DEFLATE;
    +
    ws.Compression = CompressionMethod.Deflate;
     

    And then your client sends the following header with the connection request to the server.

    @@ -491,6 +523,69 @@

    wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;
     
    +

    +Query String, Origin header and Cookies

    + +

    As a WebSocket Client, if you would like to send the Query String with the WebSocket connection request to the server, you should create an instance of the WebSocket class with the WebSocket URL that includes the Query string parameters.

    + +
    using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
    +  ...
    +}
    +
    + +

    And if you would like to send the Origin header with the WebSocket connection request to the server, you should set the WebSocket.Origin property to an allowable value as the Origin header before connecting, like the following.

    + +
    ws.Origin = "http://example.com";
    +
    + +

    And if you would like to send the Cookies with the WebSocket connection request to the server, you should set any cookie using the WebSocket.SetCookie (WebSocketSharp.Net.Cookie) method before connecting, like the following.

    + +
    ws.SetCookie (new Cookie ("name", "nobita"));
    +
    + +

    As a WebSocket Server, if you would like to get the Query String included in each WebSocket connection request, you should access the WebSocketService.Context.QueryString property, like the following.

    + +
    public class Chat : WebSocketService
    +{
    +  private string _name;
    +
    +  ...
    +
    +  protected override void OnOpen ()
    +  {
    +    _name = Context.QueryString ["name"];
    +  }
    +
    +  ...
    +}
    +
    + +

    And if you would like to check the Origin header and Cookies included in each WebSocket connection request, you should set each validation for the Origin header and Cookies in your WebSocketService, for example, using the AddWebSocketService<T> (string, Func<T>) method with initializing, like the following.

    + +
    wssv.AddWebSocketService<Chat> (
    +  "/Chat",
    +  () => new Chat () {
    +    OriginValidator = value => {
    +      // Check 'value' of the Origin header, and return true if valid
    +      Uri origin;
    +      return !value.IsNullOrEmpty () &&
    +             Uri.TryCreate (value, UriKind.Absolute, out origin) &&
    +             origin.Host == "example.com";
    +    },
    +    CookiesValidator = (req, res) => {
    +      // Check the Cookies in 'req', and set the Cookies to send to the client with 'res' if necessary
    +      foreach (Cookie cookie in req) {
    +        cookie.Expired = true;
    +        res.Add (cookie);
    +      }
    +
    +      return true; // If valid
    +    }
    +  });
    +
    + +

    Also, if you would like to get each value of the Origin header and cookies, you should access each of the WebSocketService.Context.Origin and WebSocketService.Context.CookieCollection properties.

    +

    Logging

    @@ -498,14 +593,14 @@

    You can access it with the WebSocket.Log property (returns a WebSocketSharp.Logger).

    -

    So if you would like to change the current logging level (WebSocketSharp.LogLevel.ERROR as the default), you should set the WebSocket.Log.Level property to any of the LogLevel enum values.

    +

    So if you would like to change the current logging level (WebSocketSharp.LogLevel.Error as the default), you should set the WebSocket.Log.Level property to any of the LogLevel enum values.

    -
    ws.Log.Level = LogLevel.DEBUG;
    +
    ws.Log.Level = LogLevel.Debug;
     
    -

    This means a log with less than LogLevel.DEBUG cannot be outputted.

    +

    This means a log with lower than LogLevel.Debug cannot be outputted.

    -

    And if you would like to output a log, you should use any of the output methods. The following outputs a log with LogLevel.DEBUG.

    +

    And if you would like to output a log, you should use any of the output methods. The following outputs a log with LogLevel.Debug.

    ws.Log.Debug ("This is a debug message.");
     
    @@ -544,7 +639,7 @@

    Supported WebSocket Specifications

    -

    websocket-sharp supports RFC 6455 and is based on the following WebSocket references.

    +

    websocket-sharp supports RFC 6455, and it's based on the following WebSocket references:

    +
    -
    -

    Project maintained by sta

    -

    Hosted on GitHub Pages — Theme by orderedlist

    -
    - - - - - + + + + + - - -
    - -
    -
    -

    websocket-sharp

    -

    A C# implementation of the WebSocket protocol client and server

    -
    - Project maintained by sta - Hosted on GitHub Pages — Theme by mattgraham -
    - -

    + + +
    +

    Welcome to websocket-sharp!

    websocket-sharp supports:

    @@ -101,9 +82,11 @@

    @@ -122,16 +105,16 @@

    namespace Example { - public class Program + public class Program { - public static void Main (string[] args) + public static void Main (string[] args) { - using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) { + using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) { ws.OnMessage += (sender, e) => - Console.WriteLine ("Laputa says: " + e.Data); + Console.WriteLine ("Laputa says: " + e.Data); ws.Connect (); - ws.Send ("BALUS"); + ws.Send ("BALUS"); Console.ReadKey (true); } } @@ -152,7 +135,7 @@

    Creating a new instance of the WebSocket class with the WebSocket URL to connect.

    -
    using (var ws = new WebSocket ("ws://example.com")) {
    +
    using (var ws = new WebSocket ("ws://example.com")) {
       ...
     }
    @@ -245,15 +228,15 @@

    Step 5

    -

    Sending a data to the WebSocket server.

    +

    Sending data to the WebSocket server.

    ws.Send (data);

    The WebSocket.Send method is overloaded.

    -

    You can use the WebSocket.Send (string), WebSocket.Send (byte[]), or WebSocket.Send (System.IO.FileInfo) method to send a data.

    +

    You can use the WebSocket.Send (string), WebSocket.Send (byte[]), or WebSocket.Send (System.IO.FileInfo) method to send the data.

    -

    If you would like to send a data asynchronously, you should use the WebSocket.SendAsync method.

    +

    If you would like to send the data asynchronously, you should use the WebSocket.SendAsync method.

    ws.SendAsync (data, completed);
    @@ -283,24 +266,24 @@

    namespace Example { - public class Laputa : WebSocketBehavior + public class Laputa : WebSocketBehavior { - protected override void OnMessage (MessageEventArgs e) + protected override void OnMessage (MessageEventArgs e) { - var msg = e.Data == "BALUS" - ? "I've been balused already..." - : "I'm not available now."; + var msg = e.Data == "BALUS" + ? "I've been balused already..." + : "I'm not available now."; Send (msg); } } - public class Program + public class Program { - public static void Main (string[] args) + public static void Main (string[] args) { - var wssv = new WebSocketServer ("ws://dragonsnest.far"); - wssv.AddWebSocketService<Laputa> ("/Laputa"); + var wssv = new WebSocketServer ("ws://dragonsnest.far"); + wssv.AddWebSocketService<Laputa> ("/Laputa"); wssv.Start (); Console.ReadKey (true); wssv.Stop (); @@ -328,9 +311,9 @@

    using WebSocketSharp; using WebSocketSharp.Server; -public class Echo : WebSocketBehavior +public class Echo : WebSocketBehavior { - protected override void OnMessage (MessageEventArgs e) + protected override void OnMessage (MessageEventArgs e) { Send (e.Data); } @@ -342,21 +325,21 @@

    using WebSocketSharp; using WebSocketSharp.Server; -public class Chat : WebSocketBehavior +public class Chat : WebSocketBehavior { - private string _suffix; + private string _suffix; - public Chat () + public Chat () : this (null) { } - public Chat (string suffix) + public Chat (string suffix) { _suffix = suffix ?? String.Empty; } - protected override void OnMessage (MessageEventArgs e) + protected override void OnMessage (MessageEventArgs e) { Sessions.Broadcast (e.Data + _suffix); } @@ -364,25 +347,25 @@

    You can define the behavior of any WebSocket service by creating the class that inherits the WebSocketBehavior class.

    -

    If you override the WebSocketBehavior.OnMessage (MessageEventArgs) method, it's called when the WebSocket used in the current session in the service receives a message.

    +

    If you override the WebSocketBehavior.OnMessage (MessageEventArgs) method, it's called when the WebSocket used in a session in the service receives a message.

    And if you override the WebSocketBehavior.OnOpen (), WebSocketBehavior.OnError (ErrorEventArgs), and WebSocketBehavior.OnClose (CloseEventArgs) methods, each of them is called when each event of the WebSocket (the OnOpen, OnError, and OnClose events) occurs.

    -

    The WebSocketBehavior.Send method sends a data to the client on the current session in the service.

    +

    The WebSocketBehavior.Send method sends data to the client on a session in the service.

    If you would like to access the sessions in the service, you should use the WebSocketBehavior.Sessions property (returns a WebSocketSharp.Server.WebSocketSessionManager).

    -

    The WebSocketBehavior.Sessions.Broadcast method broadcasts a data to every client in the service.

    +

    The WebSocketBehavior.Sessions.Broadcast method sends data to every client in the service.

    Step 3

    Creating a new instance of the WebSocketServer class.

    -
    var wssv = new WebSocketServer (4649);
    -wssv.AddWebSocketService<Echo> ("/Echo");
    -wssv.AddWebSocketService<Chat> ("/Chat");
    -wssv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));
    +
    var wssv = new WebSocketServer (4649);
    +wssv.AddWebSocketService<Echo> ("/Echo");
    +wssv.AddWebSocketService<Chat> ("/Chat");
    +wssv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));

    You can add any WebSocket service to your WebSocketServer with the specified behavior and path to the service, by using the WebSocketServer.AddWebSocketService<TBehaviorWithNew> (string) or WebSocketServer.AddWebSocketService<TBehavior> (string, Func<TBehavior>) method.

    @@ -424,10 +407,10 @@

    You can add any WebSocket service to your HttpServer with the specified behavior and path to the service, by using the HttpServer.AddWebSocketService<TBehaviorWithNew> (string) or HttpServer.AddWebSocketService<TBehavior> (string, Func<TBehavior>) method.

    -
    var httpsv = new HttpServer (4649);
    -httpsv.AddWebSocketService<Echo> ("/Echo");
    -httpsv.AddWebSocketService<Chat> ("/Chat");
    -httpsv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));
    +
    var httpsv = new HttpServer (4649);
    +httpsv.AddWebSocketService<Echo> ("/Echo");
    +httpsv.AddWebSocketService<Chat> ("/Chat");
    +httpsv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));

    For more information, would you see Example3?

    @@ -437,7 +420,7 @@

    Per-message Compression

    -

    websocket-sharp supports the Per-message Compression extension. (But it doesn't support with the extension parameters.)

    +

    websocket-sharp supports the Per-message Compression extension. (But this doesn't support it with the context take over.)

    If you would like to enable this extension as a WebSocket client, you should set such as the following.

    @@ -445,10 +428,10 @@

    And then your client will send the following header with the connection request to the server.

    -
    Sec-WebSocket-Extensions: permessage-deflate
    +
    Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover
     
    -

    If the server supports this extension, it will return the same header. And when your client receives it, this extension will be available.

    +

    If the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.

    Secure Connection

    @@ -457,7 +440,7 @@

    As a WebSocket Client, you should create a new instance of the WebSocket class with the wss scheme WebSocket URL.

    -
    using (var ws = new WebSocket ("wss://example.com")) {
    +
    using (var ws = new WebSocket ("wss://example.com")) {
       ...
     }
    @@ -475,9 +458,9 @@

    As a WebSocket Server, you should create a new instance of the WebSocketServer or HttpServer class with some settings for secure connection, such as the following.

    -
    var wssv = new WebSocketServer (4649, true);
    +
    var wssv = new WebSocketServer (5963, true);
     wssv.SslConfiguration.ServerCertificate =
    -  new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");
    + new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");

    HTTP Authentication

    @@ -486,7 +469,7 @@

    As a WebSocket Client, you should set a pair of user name and password for the HTTP authentication, by using the WebSocket.SetCredentials (string, string, bool) method before connecting.

    -
    ws.SetCredentials ("nobita", "password", preAuth);
    +
    ws.SetCredentials ("nobita", "password", preAuth);

    If preAuth is true, the WebSocket sends the Basic authentication credentials with the first connection request to the server.

    @@ -495,13 +478,13 @@

    As a WebSocket Server, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.

    wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
    -wssv.Realm = "WebSocket Test";
    +wssv.Realm = "WebSocket Test";
     wssv.UserCredentialsFinder = id => {
       var name = id.Name;
     
       // Return user name, password, and roles.
    -  return name == "nobita"
    -         ? new NetworkCredential (name, "password", "gunfighter")
    +  return name == "nobita"
    +         ? new NetworkCredential (name, "password", "gunfighter")
              : null; // If the user credentials aren't found.
     };
    @@ -514,28 +497,28 @@

    As a WebSocket Client, if you would like to send the Query String with the WebSocket connection request to the server, you should create a new instance of the WebSocket class with the WebSocket URL that includes the Query string parameters.

    -
    using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
    +
    using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
       ...
     }

    And if you would like to send the Origin header with the WebSocket connection request to the server, you should set the WebSocket.Origin property to an allowable value as the Origin header before connecting, such as the following.

    -
    ws.Origin = "http://example.com";
    +
    ws.Origin = "http://example.com";

    And also if you would like to send the Cookies with the WebSocket connection request to the server, you should set any cookie by using the WebSocket.SetCookie (WebSocketSharp.Net.Cookie) method before connecting, such as the following.

    -
    ws.SetCookie (new Cookie ("name", "nobita"));
    +
    ws.SetCookie (new Cookie ("name", "nobita"));

    As a WebSocket Server, if you would like to get the Query String included in each WebSocket connection request, you should access the WebSocketBehavior.Context.QueryString property, such as the following.

    -
    public class Chat : WebSocketBehavior
    +
    public class Chat : WebSocketBehavior
     {
    -  private string _name;
    +  private string _name;
       ...
     
    -  protected override void OnOpen ()
    +  protected override void OnOpen ()
       {
    -    _name = Context.QueryString["name"];
    +    _name = Context.QueryString["name"];
       }
     
       ...
    @@ -544,14 +527,14 @@ 

    And if you would like to validate the Origin header, Cookies, or both included in each WebSocket connection request, you should set each validation with your WebSocketBehavior, for example, by using the AddWebSocketService<TBehavior> (string, Func<TBehavior>) method with initializing, such as the following.

    wssv.AddWebSocketService<Chat> (
    -  "/Chat",
    -  () => new Chat () {
    +  "/Chat",
    +  () => new Chat () {
         OriginValidator = val => {
           // Check the value of the Origin header, and return true if valid.
           Uri origin;
           return !val.IsNullOrEmpty () &&
                  Uri.TryCreate (val, UriKind.Absolute, out origin) &&
    -             origin.Host == "example.com";
    +             origin.Host == "example.com";
         },
         CookiesValidator = (req, res) => {
           // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'
    @@ -574,8 +557,8 @@ 

    If you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the WebSocket.SetProxy (string, string, string) method before connecting.

    -
    var ws = new WebSocket ("ws://example.com");
    -ws.SetProxy ("http://localhost:3128", "nobita", "password");
    +
    var ws = new WebSocket ("ws://example.com");
    +ws.SetProxy ("http://localhost:3128", "nobita", "password");

    I tested this with the Squid. And it's necessary to disable the following configuration option in squid.conf (e.g. /etc/squid/squid.conf).

    @@ -598,7 +581,7 @@

    And if you would like to output a log, you should use any of the output methods. The following outputs a log with LogLevel.Debug.

    -
    ws.Log.Debug ("This is a debug message.");
    +
    ws.Log.Debug ("This is a debug message.");

    The WebSocketServer and HttpServer classes include the same logging function.

    @@ -639,7 +622,7 @@

    Thanks for translating to japanese.

    @@ -653,11 +636,16 @@

    License

    websocket-sharp is provided under The MIT License.

    -

    -

    - - @@ -669,4 +657,5 @@

    - \ No newline at end of file + + diff --git a/params.json b/params.json index 684453b26..ef4ea0a7c 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (server doesn't work in the webplayer)\r\n- **[.NET Socket Support for iOS/Android][Unity Licenses Comparison]** (requires iOS/Android Pro)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\nUsing **.NET API 2.0 compatibility level for iOS/Android** requires to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i've fixed it in the asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.Text` or `WebSocketSharp.Opcode.Binary` that represents the type of the message. So by checking it, you can determine which item you should use.\r\n\r\nIf it returns `Opcode.Text`, you should use `e.Data` property that returns a `string` (represents the **Text** message).\r\n\r\nOr if it returns `Opcode.Binary`, you should use `e.RawData` property that returns a `byte[]` (represents the **Binary** message).\r\n\r\n```csharp\r\nif (e.Type == Opcode.Text) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.Binary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code indicating the reason for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending a data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send a data.\r\n\r\nIf you would like to send a data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it's called when the `WebSocket` used in the current session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method sends a data to the client on the current session in the service.\r\n\r\nIf you would like to access the sessions in the service, you should use the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method broadcasts a data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension. (But it doesn't support with the [extension parameters].)\r\n\r\nIf you would like to enable this extension as a WebSocket client, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header with the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it will return the same header. And when your client receives it, this extension will be available.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the WebSocket connection request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin header** with the WebSocket connection request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin header] before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the WebSocket connection request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in each WebSocket connection request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin header**, **Cookies**, or both included in each WebSocket connection request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty () &&\r\n Uri.TryCreate (val, UriKind.Absolute, out origin) &&\r\n origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'\r\n // if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n });\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin header]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[Unity Licenses Comparison]: http://unity3d.com/unity/licenses\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (the server doesn't work in the webplayer)\r\n- **[.NET Socket Support for iOS/Android][Unity Licenses Comparison]** (requires iOS/Android Pro)\r\n- **Limited support for the System.IO.Compression** (the compression extension isn't available on Windows)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\nUsing **.NET API 2.0 compatibility level for iOS/Android** requires to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i've fixed it in the asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.Text` or `WebSocketSharp.Opcode.Binary` that represents the type of the message. So by checking it, you can determine which item you should use.\r\n\r\nIf it returns `Opcode.Text`, you should use `e.Data` property that returns a `string` (represents the **Text** message).\r\n\r\nOr if it returns `Opcode.Binary`, you should use `e.RawData` property that returns a `byte[]` (represents the **Binary** message).\r\n\r\n```csharp\r\nif (e.Type == Opcode.Text) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.Binary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code indicating the reason for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it's called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method sends data to the client on a session in the service.\r\n\r\nIf you would like to access the sessions in the service, you should use the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method sends data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension. (But this doesn't support it with the [context take over].)\r\n\r\nIf you would like to enable this extension as a WebSocket client, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header with the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the WebSocket connection request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin header** with the WebSocket connection request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin header] before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the WebSocket connection request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in each WebSocket connection request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin header**, **Cookies**, or both included in each WebSocket connection request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty () &&\r\n Uri.TryCreate (val, UriKind.Absolute, out origin) &&\r\n origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'\r\n // if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n });\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin header]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[Unity Licenses Comparison]: http://unity3d.com/unity/licenses\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/stylesheets/github-light.css b/stylesheets/github-light.css new file mode 100644 index 000000000..872a6f4b2 --- /dev/null +++ b/stylesheets/github-light.css @@ -0,0 +1,116 @@ +/* + Copyright 2014 GitHub Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +.pl-c /* comment */ { + color: #969896; +} + +.pl-c1 /* constant, markup.raw, meta.diff.header, meta.module-reference, meta.property-name, support, support.constant, support.variable, variable.other.constant */, +.pl-s .pl-v /* string variable */ { + color: #0086b3; +} + +.pl-e /* entity */, +.pl-en /* entity.name */ { + color: #795da3; +} + +.pl-s .pl-s1 /* string source */, +.pl-smi /* storage.modifier.import, storage.modifier.package, storage.type.java, variable.other, variable.parameter.function */ { + color: #333; +} + +.pl-ent /* entity.name.tag */ { + color: #63a35c; +} + +.pl-k /* keyword, storage, storage.type */ { + color: #a71d5d; +} + +.pl-pds /* punctuation.definition.string, string.regexp.character-class */, +.pl-s /* string */, +.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, +.pl-sr /* string.regexp */, +.pl-sr .pl-cce /* string.regexp constant.character.escape */, +.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */, +.pl-sr .pl-sre /* string.regexp source.ruby.embedded */ { + color: #183691; +} + +.pl-v /* variable */ { + color: #ed6a43; +} + +.pl-id /* invalid.deprecated */ { + color: #b52a1d; +} + +.pl-ii /* invalid.illegal */ { + background-color: #b52a1d; + color: #f8f8f8; +} + +.pl-sr .pl-cce /* string.regexp constant.character.escape */ { + color: #63a35c; + font-weight: bold; +} + +.pl-ml /* markup.list */ { + color: #693a17; +} + +.pl-mh /* markup.heading */, +.pl-mh .pl-en /* markup.heading entity.name */, +.pl-ms /* meta.separator */ { + color: #1d3e81; + font-weight: bold; +} + +.pl-mq /* markup.quote */ { + color: #008080; +} + +.pl-mi /* markup.italic */ { + color: #333; + font-style: italic; +} + +.pl-mb /* markup.bold */ { + color: #333; + font-weight: bold; +} + +.pl-md /* markup.deleted, meta.diff.header.from-file */ { + background-color: #ffecec; + color: #bd2c00; +} + +.pl-mi1 /* markup.inserted, meta.diff.header.to-file */ { + background-color: #eaffea; + color: #55a532; +} + +.pl-mdr /* meta.diff.range */ { + color: #795da3; + font-weight: bold; +} + +.pl-mo /* meta.output */ { + color: #1d3e81; +} + diff --git a/stylesheets/normalize.css b/stylesheets/normalize.css index bc2ba932d..30366a6e9 100644 --- a/stylesheets/normalize.css +++ b/stylesheets/normalize.css @@ -1,10 +1,35 @@ -/* normalize.css 2012-02-07T12:37 UTC - http://github.com/necolas/normalize.css */ -/* ============================================================================= - HTML5 display definitions +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions ========================================================================== */ -/* - * Corrects block display not defined in IE6/7/8/9 & FF3 + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. */ + article, aside, details, @@ -13,209 +38,126 @@ figure, footer, header, hgroup, +main, +menu, nav, section, summary { display: block; } -/* - * Corrects inline-block display not defined in IE6/7/8/9 & FF3 +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. */ + audio, canvas, +progress, video { - display: inline-block; - *display: inline; - *zoom: 1; + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ } -/* - * Prevents modern browsers from displaying 'audio' without controls +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. */ + audio:not([controls]) { display: none; + height: 0; } -/* - * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4 - * Known issue: no IE6 support +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. */ -[hidden] { + +[hidden], +template { display: none; } -/* ============================================================================= - Base +/* Links ========================================================================== */ -/* - * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units - * http://clagnut.com/blog/348/#c790 - * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom - * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ - */ -html { - font-size: 100%; - /* 1 */ - -webkit-text-size-adjust: 100%; - /* 2 */ - -ms-text-size-adjust: 100%; - /* 2 */ -} -/* - * Addresses font-family inconsistency between 'textarea' and other form elements. +/** + * Remove the gray background color from active links in IE 10. */ -html, -button, -input, -select, -textarea { - font-family: sans-serif; -} -/* - * Addresses margins handled incorrectly in IE6/7 - */ -body { - margin: 0; +a { + background-color: transparent; } -/* ============================================================================= - Links - ========================================================================== */ -/* - * Addresses outline displayed oddly in Chrome +/** + * Improve readability when focused and also mouse hovered in all browsers. */ -a:focus { - outline: thin dotted; -} -/* - * Improves readability when focused and also mouse hovered in all browsers - * people.opera.com/patrickl/experiments/keyboard/test - */ -a:hover, -a:active { +a:active, +a:hover { outline: 0; } -/* ============================================================================= - Typography +/* Text-level semantics ========================================================================== */ -/* - * Addresses font sizes and margins set differently in IE6/7 - * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5 - */ -h1 { - font-size: 2em; - margin: 0.67em 0; -} -h2 { - font-size: 1.5em; - margin: 0.83em 0; -} - -h3 { - font-size: 1.17em; - margin: 1em 0; -} - -h4 { - font-size: 1em; - margin: 1.33em 0; -} - -h5 { - font-size: 0.83em; - margin: 1.67em 0; -} - -h6 { - font-size: 0.75em; - margin: 2.33em 0; -} - -/* - * Addresses styling not present in IE7/8/9, S5, Chrome +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. */ + abbr[title] { border-bottom: 1px dotted; } -/* - * Addresses style set to 'bolder' in FF3+, S4/5, Chrome -*/ +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + b, strong { font-weight: bold; } -blockquote { - margin: 1em 40px; -} - -/* - * Addresses styling not present in S5, Chrome +/** + * Address styling not present in Safari and Chrome. */ + dfn { font-style: italic; } -/* - * Addresses styling not present in IE6/7/8/9 +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. */ -mark { - background: #ff0; - color: #000; -} -/* - * Addresses margins set differently in IE6/7 - */ -p, -pre { - margin: 1em 0; +h1 { + font-size: 2em; + margin: 0.67em 0; } -/* - * Corrects font family set oddly in IE6, S4/5, Chrome - * en.wikipedia.org/wiki/User:Davidgothberg/Test59 +/** + * Address styling not present in IE 8/9. */ -pre, -code, -kbd, -samp { - font-family: monospace, serif; - _font-family: 'courier new', monospace; - font-size: 1em; -} -/* - * 1. Addresses CSS quotes not supported in IE6/7 - * 2. Addresses quote property not supported in S4 - */ -/* 1 */ -q { - quotes: none; +mark { + background: #ff0; + color: #000; } -/* 2 */ -q:before, -q:after { - content: ''; - content: none; -} +/** + * Address inconsistent and variable font size in all browsers. + */ small { - font-size: 75%; + font-size: 80%; } -/* - * Prevents sub and sup affecting line-height in all browsers - * gist.github.com/413930 +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. */ + sub, sup { font-size: 75%; @@ -232,228 +174,251 @@ sub { bottom: -0.25em; } -/* ============================================================================= - Lists +/* Embedded content ========================================================================== */ -/* - * Addresses margins set differently in IE6/7 - */ -dl, -menu, -ol, -ul { - margin: 1em 0; -} -dd { - margin: 0 0 0 40px; -} - -/* - * Addresses paddings set differently in IE6/7 +/** + * Remove border when inside `a` element in IE 8/9/10. */ -menu, -ol, -ul { - padding: 0 0 0 40px; -} -/* - * Corrects list images handled incorrectly in IE7 - */ -nav ul, -nav ol { - list-style: none; - list-style-image: none; -} - -/* ============================================================================= - Embedded content - ========================================================================== */ -/* - * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3 - * 2. Improves image quality when scaled in IE7 - * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ - */ img { border: 0; - /* 1 */ - -ms-interpolation-mode: bicubic; - /* 2 */ } -/* - * Corrects overflow displayed oddly in IE9 +/** + * Correct overflow not hidden in IE 9/10/11. */ + svg:not(:root) { overflow: hidden; } -/* ============================================================================= - Figures +/* Grouping content ========================================================================== */ -/* - * Addresses margin not present in IE6/7/8/9, S5, O11 + +/** + * Address margin not present in IE 8/9 and Safari. */ + figure { - margin: 0; + margin: 1em 40px; } -/* ============================================================================= - Forms - ========================================================================== */ -/* - * Corrects margin displayed oddly in IE6/7 +/** + * Address differences between Firefox and other browsers. */ -form { - margin: 0; + +hr { + box-sizing: content-box; + height: 0; } -/* - * Define consistent border, margin, and padding +/** + * Contain overflow in all browsers. */ -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; + +pre { + overflow: auto; } -/* - * 1. Corrects color not being inherited in IE6/7/8/9 - * 2. Corrects text not wrapping in FF3 - * 3. Corrects alignment displayed oddly in IE6/7 +/** + * Address odd `em`-unit font size rendering in all browsers. */ -legend { - border: 0; - /* 1 */ - padding: 0; - white-space: normal; - /* 2 */ - *margin-left: -7px; - /* 3 */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; } -/* - * 1. Corrects font size not being inherited in all browsers - * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome - * 3. Improves appearance and consistency in all browsers +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + button, input, +optgroup, select, textarea { - font-size: 100%; - /* 1 */ - margin: 0; - /* 2 */ - vertical-align: baseline; - /* 3 */ - *vertical-align: middle; - /* 3 */ + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; } -/* - * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. */ + button, -input { - line-height: normal; - /* 1 */ +select { + text-transform: none; } -/* - * 1. Improves usability and consistency of cursor style between image-type 'input' and others - * 2. Corrects inability to style clickable 'input' types in iOS - * 3. Removes inner spacing in IE7 without affecting normal text inputs - * Known issue: inner spacing remains in IE6 +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. */ + button, -input[type="button"], +html input[type="button"], /* 1 */ input[type="reset"], input[type="submit"] { - cursor: pointer; - /* 1 */ - -webkit-appearance: button; - /* 2 */ - *overflow: visible; - /* 3 */ + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ } -/* - * Re-set default cursor for disabled elements +/** + * Re-set default cursor for disabled elements. */ + button[disabled], -input[disabled] { +html input[disabled] { cursor: default; } -/* - * 1. Addresses box sizing set to content-box in IE8/9 - * 2. Removes excess padding in IE8/9 - * 3. Removes excess padding in IE7 - Known issue: excess padding remains in IE6 +/** + * Remove inner padding and border in Firefox 4+. */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + input[type="checkbox"], input[type="radio"] { - box-sizing: border-box; - /* 1 */ - padding: 0; - /* 2 */ - *height: 13px; - /* 3 */ - *width: 13px; - /* 3 */ + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; } -/* - * 1. Addresses appearance set to searchfield in S5, Chrome - * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof) +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). */ + input[type="search"] { - -webkit-appearance: textfield; - /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - /* 2 */ + -webkit-appearance: textfield; /* 1 */ /* 2 */ box-sizing: content-box; } -/* - * Removes inner padding and search cancel button in S5, Chrome on OS X +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). */ -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button { + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } -/* - * Removes inner padding and border in FF3+ - * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ +/** + * Define consistent border, margin, and padding. */ -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ } -/* - * 1. Removes default vertical scrollbar in IE6/7/8/9 - * 2. Improves readability and alignment in all browsers +/** + * Remove default vertical scrollbar in IE 8/9/10/11. */ + textarea { overflow: auto; - /* 1 */ - vertical-align: top; - /* 2 */ } -/* ============================================================================= - Tables +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables ========================================================================== */ -/* - * Remove most spacing between table cells + +/** + * Remove most spacing between table cells. */ + table { border-collapse: collapse; border-spacing: 0; } + +td, +th { + padding: 0; +} diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css index b61750983..b5f20c235 100644 --- a/stylesheets/stylesheet.css +++ b/stylesheets/stylesheet.css @@ -1,479 +1,245 @@ -/* http://meyerweb.com/eric/tools/css/reset/ - v2.0 | 20110126 - License: none (public domain) -*/ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} +* { + box-sizing: border-box; } -/* LAYOUT STYLES */ body { - font-size: 15px; - line-height: 1.5; - background: #fafafa url(../images/body-bg.jpg) 0 0 repeat; - font-family: 'Helvetica Neue', Helvetica, Arial, serif; - font-weight: 400; - color: #666; -} + padding: 0; + margin: 0; + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 1.5; + color: #606c71; } a { - color: #2879d0; -} -a:hover { - color: #2268b2; -} - -header { - padding-top: 40px; - padding-bottom: 40px; - font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; - background: #2e7bcf url(../images/header-bg.jpg) 0 0 repeat-x; - border-bottom: solid 1px #275da1; -} - -header h1 { - letter-spacing: -1px; - font-size: 72px; - color: #fff; - line-height: 1; - margin-bottom: 0.2em; - width: 540px; -} + color: #1e6bb8; + text-decoration: none; } + a:hover { + text-decoration: underline; } + +.btn { + display: inline-block; + margin-bottom: 1rem; + color: rgba(255, 255, 255, 0.7); + background-color: rgba(255, 255, 255, 0.08); + border-color: rgba(255, 255, 255, 0.2); + border-style: solid; + border-width: 1px; + border-radius: 0.3rem; + transition: color 0.2s, background-color 0.2s, border-color 0.2s; } + .btn + .btn { + margin-left: 1rem; } + +.btn:hover { + color: rgba(255, 255, 255, 0.8); + text-decoration: none; + background-color: rgba(255, 255, 255, 0.2); + border-color: rgba(255, 255, 255, 0.3); } -header h2 { - font-size: 26px; - color: #9ddcff; - font-weight: normal; - line-height: 1.3; - width: 540px; - letter-spacing: 0; -} +@media screen and (min-width: 64em) { + .btn { + padding: 0.75rem 1rem; } } -.inner { - position: relative; - width: 940px; - margin: 0 auto; -} +@media screen and (min-width: 42em) and (max-width: 64em) { + .btn { + padding: 0.6rem 0.9rem; + font-size: 0.9rem; } } -#content-wrapper { - border-top: solid 1px #fff; - padding-top: 30px; -} +@media screen and (max-width: 42em) { + .btn { + display: block; + width: 100%; + padding: 0.75rem; + font-size: 0.9rem; } + .btn + .btn { + margin-top: 1rem; + margin-left: 0; } } -#main-content { - width: 690px; - float: left; -} +.page-header { + color: #fff; + text-align: center; + background-color: #159957; + background-image: linear-gradient(120deg, #155799, #159957); } -#main-content img { - max-width: 100%; -} +@media screen and (min-width: 64em) { + .page-header { + padding: 5rem 6rem; } } -aside#sidebar { - width: 200px; - padding-left: 20px; - min-height: 504px; - float: right; - background: transparent url(../images/sidebar-bg.jpg) 0 0 no-repeat; - font-size: 12px; - line-height: 1.3; -} +@media screen and (min-width: 42em) and (max-width: 64em) { + .page-header { + padding: 3rem 4rem; } } -aside#sidebar p.repo-owner, -aside#sidebar p.repo-owner a { - font-weight: bold; -} +@media screen and (max-width: 42em) { + .page-header { + padding: 2rem 1rem; } } -#downloads { - margin-bottom: 40px; -} +.project-name { + margin-top: 0; + margin-bottom: 0.1rem; } -a.button { - width: 134px; - height: 58px; - line-height: 1.2; - font-size: 23px; - color: #fff; - padding-left: 68px; - padding-top: 22px; - font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; -} -a.button small { - display: block; - font-size: 11px; -} -header a.button { - position: absolute; - right: 0; - top: 0; - background: transparent url(../images/github-button.png) 0 0 no-repeat; -} -aside a.button { - width: 138px; - padding-left: 64px; - display: block; - background: transparent url(../images/download-button.png) 0 0 no-repeat; - margin-bottom: 20px; - font-size: 21px; -} +@media screen and (min-width: 64em) { + .project-name { + font-size: 3.25rem; } } -code, pre { - font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; - color: #222; - margin-bottom: 30px; - font-size: 13px; -} +@media screen and (min-width: 42em) and (max-width: 64em) { + .project-name { + font-size: 2.25rem; } } -code { - background-color: #f2f8fc; - border: solid 1px #dbe7f3; - padding: 0 3px; -} +@media screen and (max-width: 42em) { + .project-name { + font-size: 1.75rem; } } -pre { - padding: 20px; - background: #fff; - text-shadow: none; +.project-tagline { + margin-bottom: 2rem; + font-weight: normal; + opacity: 0.7; } + +@media screen and (min-width: 64em) { + .project-tagline { + font-size: 1.25rem; } } + +@media screen and (min-width: 42em) and (max-width: 64em) { + .project-tagline { + font-size: 1.15rem; } } + +@media screen and (max-width: 42em) { + .project-tagline { + font-size: 1rem; } } + +.main-content :first-child { + margin-top: 0; } +.main-content img { + max-width: 100%; } +.main-content h1, .main-content h2, .main-content h3, .main-content h4, .main-content h5, .main-content h6 { + margin-top: 2rem; + margin-bottom: 1rem; + font-weight: normal; + color: #159957; } +.main-content p { + margin-bottom: 1em; } +.main-content code { + padding: 2px 4px; + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 0.9rem; + color: #383e41; + background-color: #f3f6fa; + border-radius: 0.3rem; } +.main-content pre { + padding: 0.8rem; + margin-top: 0; + margin-bottom: 1rem; + font: 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace; + color: #567482; + word-wrap: normal; + background-color: #f3f6fa; + border: solid 1px #dce6f0; + border-radius: 0.3rem; } + .main-content pre > code { + padding: 0; + margin: 0; + font-size: 0.9rem; + color: #567482; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; } +.main-content .highlight { + margin-bottom: 1rem; } + .main-content .highlight pre { + margin-bottom: 0; + word-break: normal; } +.main-content .highlight pre, .main-content pre { + padding: 0.8rem; overflow: auto; - border: solid 1px #f2f2f2; -} -pre code { - color: #2879d0; - background-color: #fff; - border: none; + font-size: 0.9rem; + line-height: 1.45; + border-radius: 0.3rem; } +.main-content pre code, .main-content pre tt { + display: inline; + max-width: initial; padding: 0; -} - -ul, ol, dl { - margin-bottom: 20px; -} - - -/* COMMON STYLES */ - -hr { - height: 1px; - line-height: 1px; - margin-top: 1em; - padding-bottom: 1em; - border: none; - background: transparent url('../images/hr.png') 0 0 no-repeat; -} - -table { + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; } + .main-content pre code:before, .main-content pre code:after, .main-content pre tt:before, .main-content pre tt:after { + content: normal; } +.main-content ul, .main-content ol { + margin-top: 0; } +.main-content blockquote { + padding: 0 1rem; + margin-left: 0; + color: #819198; + border-left: 0.3rem solid #dce6f0; } + .main-content blockquote > :first-child { + margin-top: 0; } + .main-content blockquote > :last-child { + margin-bottom: 0; } +.main-content table { + display: block; width: 100%; - border: 1px solid #ebebeb; -} - -th { - font-weight: 500; -} - -td { - border: 1px solid #ebebeb; - text-align: center; - font-weight: 300; -} - -form { - background: #f2f2f2; - padding: 20px; - -} - - -/* GENERAL ELEMENT TYPE STYLES */ - -#main-content h1 { - font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; - font-size: 2.8em; - letter-spacing: -1px; - color: #474747; -} - -#main-content h1:before { - content: "/"; - color: #9ddcff; - padding-right: 0.3em; - margin-left: -0.9em; -} - -#main-content h2 { - font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; - font-size: 22px; - font-weight: bold; - margin-bottom: 8px; - color: #474747; -} -#main-content h2:before { - content: "//"; - color: #9ddcff; - padding-right: 0.3em; - margin-left: -1.5em; -} - -#main-content h3 { - font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; - font-size: 18px; - font-weight: bold; - margin-top: 24px; - margin-bottom: 8px; - color: #474747; -} - -#main-content h3:before { - content: "///"; - color: #9ddcff; - padding-right: 0.3em; - margin-left: -2em; -} - -#main-content h4 { - font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; - font-size: 15px; - font-weight: bold; - color: #474747; -} - -h4:before { - content: "////"; - color: #9ddcff; - padding-right: 0.3em; - margin-left: -2.8em; -} - -#main-content h5 { - font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; - font-size: 14px; - color: #474747; -} -h5:before { - content: "/////"; - color: #9ddcff; - padding-right: 0.3em; - margin-left: -3.2em; -} - -#main-content h6 { - font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; - font-size: .8em; - color: #474747; -} -h6:before { - content: "//////"; - color: #9ddcff; - padding-right: 0.3em; - margin-left: -3.7em; -} - -p { - margin-bottom: 20px; -} - -a { - text-decoration: none; -} - -p a { - font-weight: 400; -} - -blockquote { - font-size: 1.6em; - border-left: 10px solid #e9e9e9; - margin-bottom: 20px; - padding: 0 0 0 30px; -} - -ul { - list-style: disc inside; - padding-left: 20px; -} - -ol { - list-style: decimal inside; - padding-left: 3px; -} - -dl dd { - font-style: italic; - font-weight: 100; -} - -footer { - background: transparent url('../images/hr.png') 0 0 no-repeat; - margin-top: 40px; - padding-top: 20px; - padding-bottom: 30px; - font-size: 13px; - color: #aaa; -} - -footer a { - color: #666; -} -footer a:hover { - color: #444; -} - -/* MISC */ -.clearfix:after { - clear: both; - content: '.'; + overflow: auto; + word-break: normal; + word-break: keep-all; } + .main-content table th { + font-weight: bold; } + .main-content table th, .main-content table td { + padding: 0.5rem 1rem; + border: 1px solid #e9ebec; } +.main-content dl { + padding: 0; } + .main-content dl dt { + padding: 0; + margin-top: 1rem; + font-size: 1rem; + font-weight: bold; } + .main-content dl dd { + padding: 0; + margin-bottom: 1rem; } +.main-content hr { + height: 2px; + padding: 0; + margin: 1rem 0; + background-color: #eff0f1; + border: 0; } + +@media screen and (min-width: 64em) { + .main-content { + max-width: 64rem; + padding: 2rem 6rem; + margin: 0 auto; + font-size: 1.1rem; } } + +@media screen and (min-width: 42em) and (max-width: 64em) { + .main-content { + padding: 2rem 4rem; + font-size: 1.1rem; } } + +@media screen and (max-width: 42em) { + .main-content { + padding: 2rem 1rem; + font-size: 1rem; } } + +.site-footer { + padding-top: 2rem; + margin-top: 2rem; + border-top: solid 1px #eff0f1; } + +.site-footer-owner { display: block; - visibility: hidden; - height: 0; -} - -.clearfix {display: inline-block;} -* html .clearfix {height: 1%;} -.clearfix {display: block;} + font-weight: bold; } -/* #Media Queries -================================================== */ +.site-footer-credits { + color: #819198; } -/* Smaller than standard 960 (devices and browsers) */ -@media only screen and (max-width: 959px) {} - -/* Tablet Portrait size to standard 960 (devices and browsers) */ -@media only screen and (min-width: 768px) and (max-width: 959px) { - .inner { - width: 740px; - } - header h1, header h2 { - width: 340px; - } - header h1 { - font-size: 60px; - } - header h2 { - font-size: 30px; - } - #main-content { - width: 490px; - } - #main-content h1:before, - #main-content h2:before, - #main-content h3:before, - #main-content h4:before, - #main-content h5:before, - #main-content h6:before { - content: none; - padding-right: 0; - margin-left: 0; - } -} - -/* All Mobile Sizes (devices and browser) */ -@media only screen and (max-width: 767px) { - .inner { - width: 93%; - } - header { - padding: 20px 0; - } - header .inner { - position: relative; - } - header h1, header h2 { - width: 100%; - } - header h1 { - font-size: 48px; - } - header h2 { - font-size: 24px; - } - header a.button { - background-image: none; - width: auto; - height: auto; - display: inline-block; - margin-top: 15px; - padding: 5px 10px; - position: relative; - text-align: center; - font-size: 13px; - line-height: 1; - background-color: #9ddcff; - color: #2879d0; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border-radius: 5px; - } - header a.button small { - font-size: 13px; - display: inline; - } - #main-content, - aside#sidebar { - float: none; - width: 100% ! important; - } - aside#sidebar { - background-image: none; - margin-top: 20px; - border-top: solid 1px #ddd; - padding: 20px 0; - min-height: 0; - } - aside#sidebar a.button { - display: none; - } - #main-content h1:before, - #main-content h2:before, - #main-content h3:before, - #main-content h4:before, - #main-content h5:before, - #main-content h6:before { - content: none; - padding-right: 0; - margin-left: 0; - } -} +@media screen and (min-width: 64em) { + .site-footer { + font-size: 1rem; } } -/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ -@media only screen and (min-width: 480px) and (max-width: 767px) {} +@media screen and (min-width: 42em) and (max-width: 64em) { + .site-footer { + font-size: 1rem; } } -/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ -@media only screen and (max-width: 479px) {} +@media screen and (max-width: 42em) { + .site-footer { + font-size: 0.9rem; } } From 162952e82dd7f20e97b3e6ab8ea77bf07ae40a2e Mon Sep 17 00:00:00 2001 From: sta Date: Mon, 3 Aug 2015 15:24:40 +0900 Subject: [PATCH 22/27] Create gh-pages branch via GitHub --- index.html | 46 +++++++++++++++++++++++++++++++++++++++------- params.json | 2 +- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index f0202e30e..46382646d 100644 --- a/index.html +++ b/index.html @@ -82,15 +82,17 @@

    • -Security Sandbox of the Webplayer (the server doesn't work in the webplayer)
    • +Security Sandbox of the Webplayer (The server isn't available in Web Player)
    • -.NET Socket Support for iOS/Android (requires iOS/Android Pro)
    • +WebGL Networking (Not available in WebGL)
    • -Limited support for the System.IO.Compression (the compression extension isn't available on Windows)
    • +Weak Support for the System.IO.Compression (The compression extension isn't available on Windows) +
    • +.NET Socket Support for iOS/Android (It requires iOS/Android Pro if your Unity is earlier than Unity 5)
    • .NET API 2.0 compatibility level for iOS/Android
    -

    Using .NET API 2.0 compatibility level for iOS/Android requires to fix lack of some features for later than .NET 2.0, such as the System.Func<...> delegates (so i've fixed it in the asset package).

    +

    .NET API 2.0 compatibility level for iOS/Android may require to fix lack of some features for later than .NET 2.0, such as the System.Func<...> delegates (so i've fixed it in the asset package).

    And it's priced at US$15. I think your $15 makes this project more better and accelerated, Thank you!

    @@ -188,6 +190,20 @@

    return; }

    +

    And if you would like to notify that a Ping has been received, via this event, you should set the WebSocket.EmitOnPing property to true, such as the following.

    + +
    ws.EmitOnPing = true;
    +ws.OnMessage += (sender, e) => {
    +  if (e.Type == Opcode.Ping) {
    +    // Do something to notify that a Ping has been received.
    +    ...
    +
    +    return;
    +  }
    +
    +  ...
    +};
    +
    WebSocket.OnError Event
    @@ -420,19 +436,35 @@

    Per-message Compression

    -

    websocket-sharp supports the Per-message Compression extension. (But this doesn't support it with the context take over.)

    +

    websocket-sharp supports the Per-message Compression extension (but doesn't support this extension with the context take over).

    -

    If you would like to enable this extension as a WebSocket client, you should set such as the following.

    +

    As a WebSocket client, if you would like to enable this extension, you should set such as the following.

    ws.Compression = CompressionMethod.Deflate;
    -

    And then your client will send the following header with the connection request to the server.

    +

    And then your client will send the following header in the connection request to the server.

    Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover
     

    If the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.

    +

    +Ignoring the extensions

    + +

    As a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the WebSocketBehavior.IgnoreExtensions property to true in your WebSocketBehavior constructor or initializing it, such as the following.

    + +
    wssv.AddWebSocketService<Chat> (
    +  "/Chat",
    +  () => new Chat () {
    +    // To ignore the extensions requested from a client.
    +    IgnoreExtensions = true
    +  });
    + +

    If it's set to true, the server doesn't return the Sec-WebSocket-Extensions header in the connection response.

    + +

    I think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.

    +

    Secure Connection

    diff --git a/params.json b/params.json index ef4ea0a7c..5d42becfa 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (the server doesn't work in the webplayer)\r\n- **[.NET Socket Support for iOS/Android][Unity Licenses Comparison]** (requires iOS/Android Pro)\r\n- **Limited support for the System.IO.Compression** (the compression extension isn't available on Windows)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\nUsing **.NET API 2.0 compatibility level for iOS/Android** requires to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i've fixed it in the asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.Text` or `WebSocketSharp.Opcode.Binary` that represents the type of the message. So by checking it, you can determine which item you should use.\r\n\r\nIf it returns `Opcode.Text`, you should use `e.Data` property that returns a `string` (represents the **Text** message).\r\n\r\nOr if it returns `Opcode.Binary`, you should use `e.RawData` property that returns a `byte[]` (represents the **Binary** message).\r\n\r\n```csharp\r\nif (e.Type == Opcode.Text) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.Binary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code indicating the reason for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it's called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method sends data to the client on a session in the service.\r\n\r\nIf you would like to access the sessions in the service, you should use the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method sends data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension. (But this doesn't support it with the [context take over].)\r\n\r\nIf you would like to enable this extension as a WebSocket client, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header with the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the WebSocket connection request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin header** with the WebSocket connection request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin header] before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the WebSocket connection request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in each WebSocket connection request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin header**, **Cookies**, or both included in each WebSocket connection request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty () &&\r\n Uri.TryCreate (val, UriKind.Absolute, out origin) &&\r\n origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'\r\n // if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n });\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin header]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[Unity Licenses Comparison]: http://unity3d.com/unity/licenses\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)\r\n- **[WebGL Networking]** (Not available in WebGL)\r\n- **Weak Support for the System.IO.Compression** (The compression extension isn't available on Windows)\r\n- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\n**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i've fixed it in the asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.Text` or `WebSocketSharp.Opcode.Binary` that represents the type of the message. So by checking it, you can determine which item you should use.\r\n\r\nIf it returns `Opcode.Text`, you should use `e.Data` property that returns a `string` (represents the **Text** message).\r\n\r\nOr if it returns `Opcode.Binary`, you should use `e.RawData` property that returns a `byte[]` (represents the **Binary** message).\r\n\r\n```csharp\r\nif (e.Type == Opcode.Text) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.Binary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\nAnd if you would like to notify that a **Ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.\r\n\r\n```csharp\r\nws.EmitOnPing = true;\r\nws.OnMessage += (sender, e) => {\r\n if (e.Type == Opcode.Ping) {\r\n // Do something to notify that a Ping has been received.\r\n ...\r\n\r\n return;\r\n }\r\n\r\n ...\r\n};\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code indicating the reason for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it's called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method sends data to the client on a session in the service.\r\n\r\nIf you would like to access the sessions in the service, you should use the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method sends data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).\r\n\r\nAs a WebSocket client, if you would like to enable this extension, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header in the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n#### Ignoring the extensions ####\r\n\r\nAs a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n // To ignore the extensions requested from a client.\r\n IgnoreExtensions = true\r\n });\r\n```\r\n\r\nIf it's set to `true`, the server doesn't return the **Sec-WebSocket-Extensions header** in the connection response.\r\n\r\nI think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the WebSocket connection request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin header** with the WebSocket connection request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin header] before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the WebSocket connection request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in each WebSocket connection request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin header**, **Cookies**, or both included in each WebSocket connection request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty () &&\r\n Uri.TryCreate (val, UriKind.Absolute, out origin) &&\r\n origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'\r\n // if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n });\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin header]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From bbddcffda78853337310caeb3b00fab8ef82d140 Mon Sep 17 00:00:00 2001 From: sta Date: Wed, 2 Dec 2015 15:21:08 +0900 Subject: [PATCH 23/27] Create gh-pages branch via GitHub --- index.html | 117 ++++++++++++++++++++++++++-------------------------- params.json | 2 +- 2 files changed, 59 insertions(+), 60 deletions(-) diff --git a/index.html b/index.html index 46382646d..34ced796d 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ websocket-sharp by sta - + @@ -102,8 +102,8 @@

    WebSocket Client

    -
    using System;
    -using WebSocketSharp;
    +
    using System;
    +using WebSocketSharp;
     
     namespace Example
     {
    @@ -128,7 +128,7 @@ 

    Required namespace.

    -
    using WebSocketSharp;
    +
    using WebSocketSharp;

    The WebSocket class exists in the WebSocketSharp namespace.

    @@ -137,7 +137,7 @@

    Creating a new instance of the WebSocket class with the WebSocket URL to connect.

    -
    using (var ws = new WebSocket ("ws://example.com")) {
    +
    using (var ws = new WebSocket ("ws://example.com")) {
       ...
     }
    @@ -153,7 +153,7 @@

    A WebSocket.OnOpen event occurs when the WebSocket connection has been established.

    -
    ws.OnOpen += (sender, e) => {
    +
    ws.OnOpen += (sender, e) => {
       ...
     };
    @@ -164,44 +164,44 @@

    A WebSocket.OnMessage event occurs when the WebSocket receives a message.

    -
    ws.OnMessage += (sender, e) => {
    +
    ws.OnMessage += (sender, e) => {
       ...
     };

    e has passed as a WebSocketSharp.MessageEventArgs.

    -

    e.Type property returns either WebSocketSharp.Opcode.Text or WebSocketSharp.Opcode.Binary that represents the type of the message. So by checking it, you can determine which item you should use.

    +

    If you would like to get the message data, you should access e.Data or e.RawData property.

    -

    If it returns Opcode.Text, you should use e.Data property that returns a string (represents the Text message).

    +

    And you can determine which property you should access by checking e.IsText or e.IsBinary property.

    -

    Or if it returns Opcode.Binary, you should use e.RawData property that returns a byte[] (represents the Binary message).

    +

    If e.IsText is true, you should access e.Data that returns a string (represents a text message).

    -
    if (e.Type == Opcode.Text) {
    +

    Or if e.IsBinary is true, you should access e.RawData that returns a byte[] (represents a binary message).

    + +
    if (e.IsText) {
       // Do something with e.Data.
       ...
     
       return;
     }
     
    -if (e.Type == Opcode.Binary) {
    +if (e.IsBinary) {
       // Do something with e.RawData.
       ...
     
       return;
     }
    -

    And if you would like to notify that a Ping has been received, via this event, you should set the WebSocket.EmitOnPing property to true, such as the following.

    +

    And if you would like to notify that a ping has been received, via this event, you should set the WebSocket.EmitOnPing property to true, such as the following.

    -
    ws.EmitOnPing = true;
    +
    ws.EmitOnPing = true;
     ws.OnMessage += (sender, e) => {
    -  if (e.Type == Opcode.Ping) {
    -    // Do something to notify that a Ping has been received.
    +  if (e.IsPing) {
    +    // Do something to notify that a ping has been received.
         ...
     
         return;
       }
    -
    -  ...
     };
    @@ -209,7 +209,7 @@

    A WebSocket.OnError event occurs when the WebSocket gets an error.

    -
    ws.OnError += (sender, e) => {
    +
    ws.OnError += (sender, e) => {
       ...
     };
    @@ -224,7 +224,7 @@

    A WebSocket.OnClose event occurs when the WebSocket connection has been closed.

    -
    ws.OnClose += (sender, e) => {
    +
    ws.OnClose += (sender, e) => {
       ...
     };
    @@ -237,7 +237,7 @@

    Connecting to the WebSocket server.

    -
    ws.Connect ();
    +
    ws.Connect ();

    If you would like to connect to the server asynchronously, you should use the WebSocket.ConnectAsync () method.

    @@ -246,7 +246,7 @@

    Sending data to the WebSocket server.

    -
    ws.Send (data);
    +
    ws.Send (data);

    The WebSocket.Send method is overloaded.

    @@ -254,7 +254,7 @@

    If you would like to send the data asynchronously, you should use the WebSocket.SendAsync method.

    -
    ws.SendAsync (data, completed);
    +
    ws.SendAsync (data, completed);

    And also if you would like to do something when the send is complete, you should set completed to any Action<bool> delegate.

    @@ -263,7 +263,7 @@

    Closing the WebSocket connection.

    -
    ws.Close (code, reason);
    +
    ws.Close (code, reason);

    If you would like to close the connection explicitly, you should use the WebSocket.Close method.

    @@ -276,9 +276,9 @@

    WebSocket Server

    -
    using System;
    -using WebSocketSharp;
    -using WebSocketSharp.Server;
    +
    using System;
    +using WebSocketSharp;
    +using WebSocketSharp.Server;
     
     namespace Example
     {
    @@ -312,7 +312,7 @@ 

    Required namespace.

    -
    using WebSocketSharp.Server;
    +
    using WebSocketSharp.Server;

    The WebSocketBehavior and WebSocketServer classes exist in the WebSocketSharp.Server namespace.

    @@ -323,9 +323,9 @@

    For example, if you would like to provide an echo service,

    -
    using System;
    -using WebSocketSharp;
    -using WebSocketSharp.Server;
    +
    using System;
    +using WebSocketSharp;
    +using WebSocketSharp.Server;
     
     public class Echo : WebSocketBehavior
     {
    @@ -337,9 +337,9 @@ 

    And if you would like to provide a chat service,

    -
    using System;
    -using WebSocketSharp;
    -using WebSocketSharp.Server;
    +
    using System;
    +using WebSocketSharp;
    +using WebSocketSharp.Server;
     
     public class Chat : WebSocketBehavior
     {
    @@ -369,7 +369,7 @@ 

    The WebSocketBehavior.Send method sends data to the client on a session in the service.

    -

    If you would like to access the sessions in the service, you should use the WebSocketBehavior.Sessions property (returns a WebSocketSharp.Server.WebSocketSessionManager).

    +

    If you would like to get the sessions in the service, you should access the WebSocketBehavior.Sessions property (returns a WebSocketSharp.Server.WebSocketSessionManager).

    The WebSocketBehavior.Sessions.Broadcast method sends data to every client in the service.

    @@ -378,7 +378,7 @@

    Creating a new instance of the WebSocketServer class.

    -
    var wssv = new WebSocketServer (4649);
    +
    var wssv = new WebSocketServer (4649);
     wssv.AddWebSocketService<Echo> ("/Echo");
     wssv.AddWebSocketService<Chat> ("/Chat");
     wssv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));
    @@ -401,14 +401,14 @@

    Starting the WebSocket server.

    -
    wssv.Start ();
    +
    wssv.Start ();

    Step 5

    Stopping the WebSocket server.

    -
    wssv.Stop (code, reason);
    +
    wssv.Stop (code, reason);

    The WebSocketServer.Stop method is overloaded.

    @@ -423,7 +423,7 @@

    You can add any WebSocket service to your HttpServer with the specified behavior and path to the service, by using the HttpServer.AddWebSocketService<TBehaviorWithNew> (string) or HttpServer.AddWebSocketService<TBehavior> (string, Func<TBehavior>) method.

    -
    var httpsv = new HttpServer (4649);
    +
    var httpsv = new HttpServer (4649);
     httpsv.AddWebSocketService<Echo> ("/Echo");
     httpsv.AddWebSocketService<Chat> ("/Chat");
     httpsv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));
    @@ -440,7 +440,7 @@

    As a WebSocket client, if you would like to enable this extension, you should set such as the following.

    -
    ws.Compression = CompressionMethod.Deflate;
    +
    ws.Compression = CompressionMethod.Deflate;

    And then your client will send the following header in the connection request to the server.

    @@ -454,7 +454,7 @@

    As a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the WebSocketBehavior.IgnoreExtensions property to true in your WebSocketBehavior constructor or initializing it, such as the following.

    -
    wssv.AddWebSocketService<Chat> (
    +
    wssv.AddWebSocketService<Chat> (
       "/Chat",
       () => new Chat () {
         // To ignore the extensions requested from a client.
    @@ -472,13 +472,13 @@ 

    As a WebSocket Client, you should create a new instance of the WebSocket class with the wss scheme WebSocket URL.

    -
    using (var ws = new WebSocket ("wss://example.com")) {
    +
    using (var ws = new WebSocket ("wss://example.com")) {
       ...
     }

    And if you would like to use the custom validation for the server certificate, you should set the WebSocket.SslConfiguration.ServerCertificateValidationCallback property.

    -
    ws.SslConfiguration.ServerCertificateValidationCallback =
    +
    ws.SslConfiguration.ServerCertificateValidationCallback =
       (sender, certificate, chain, sslPolicyErrors) => {
         // Do something to validate the server certificate.
         ...
    @@ -490,7 +490,7 @@ 

    As a WebSocket Server, you should create a new instance of the WebSocketServer or HttpServer class with some settings for secure connection, such as the following.

    -
    var wssv = new WebSocketServer (5963, true);
    +
    var wssv = new WebSocketServer (5963, true);
     wssv.SslConfiguration.ServerCertificate =
       new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");
    @@ -501,7 +501,7 @@

    As a WebSocket Client, you should set a pair of user name and password for the HTTP authentication, by using the WebSocket.SetCredentials (string, string, bool) method before connecting.

    -
    ws.SetCredentials ("nobita", "password", preAuth);
    +
    ws.SetCredentials ("nobita", "password", preAuth);

    If preAuth is true, the WebSocket sends the Basic authentication credentials with the first connection request to the server.

    @@ -509,7 +509,7 @@

    As a WebSocket Server, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.

    -
    wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
    +
    wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
     wssv.Realm = "WebSocket Test";
     wssv.UserCredentialsFinder = id => {
       var name = id.Name;
    @@ -522,28 +522,28 @@ 

    If you would like to provide the Digest authentication, you should set such as the following.

    -
    wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;
    +
    wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;

    Query String, Origin header and Cookies

    As a WebSocket Client, if you would like to send the Query String with the WebSocket connection request to the server, you should create a new instance of the WebSocket class with the WebSocket URL that includes the Query string parameters.

    -
    using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
    +
    using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
       ...
     }

    And if you would like to send the Origin header with the WebSocket connection request to the server, you should set the WebSocket.Origin property to an allowable value as the Origin header before connecting, such as the following.

    -
    ws.Origin = "http://example.com";
    +
    ws.Origin = "http://example.com";

    And also if you would like to send the Cookies with the WebSocket connection request to the server, you should set any cookie by using the WebSocket.SetCookie (WebSocketSharp.Net.Cookie) method before connecting, such as the following.

    -
    ws.SetCookie (new Cookie ("name", "nobita"));
    +
    ws.SetCookie (new Cookie ("name", "nobita"));
    -

    As a WebSocket Server, if you would like to get the Query String included in each WebSocket connection request, you should access the WebSocketBehavior.Context.QueryString property, such as the following.

    +

    As a WebSocket Server, if you would like to get the Query String included in a WebSocket connection request, you should access the WebSocketBehavior.Context.QueryString property, such as the following.

    -
    public class Chat : WebSocketBehavior
    +
    public class Chat : WebSocketBehavior
     {
       private string _name;
       ...
    @@ -556,9 +556,9 @@ 

    ... }

    -

    And if you would like to validate the Origin header, Cookies, or both included in each WebSocket connection request, you should set each validation with your WebSocketBehavior, for example, by using the AddWebSocketService<TBehavior> (string, Func<TBehavior>) method with initializing, such as the following.

    +

    And if you would like to validate the Origin header, Cookies, or both included in a WebSocket connection request, you should set each validation with your WebSocketBehavior, for example, by using the AddWebSocketService<TBehavior> (string, Func<TBehavior>) method with initializing, such as the following.

    -
    wssv.AddWebSocketService<Chat> (
    +
    wssv.AddWebSocketService<Chat> (
       "/Chat",
       () => new Chat () {
         OriginValidator = val => {
    @@ -589,7 +589,7 @@ 

    If you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the WebSocket.SetProxy (string, string, string) method before connecting.

    -
    var ws = new WebSocket ("ws://example.com");
    +
    var ws = new WebSocket ("ws://example.com");
     ws.SetProxy ("http://localhost:3128", "nobita", "password");

    I tested this with the Squid. And it's necessary to disable the following configuration option in squid.conf (e.g. /etc/squid/squid.conf).

    @@ -607,13 +607,13 @@

    So if you would like to change the current logging level (WebSocketSharp.LogLevel.Error as the default), you should set the WebSocket.Log.Level property to any of the LogLevel enum values.

    -
    ws.Log.Level = LogLevel.Debug;
    +
    ws.Log.Level = LogLevel.Debug;

    The above means a log with lower than LogLevel.Debug cannot be outputted.

    And if you would like to output a log, you should use any of the output methods. The following outputs a log with LogLevel.Debug.

    -
    ws.Log.Debug ("This is a debug message.");
    +
    ws.Log.Debug ("This is a debug message.");

    The WebSocketServer and HttpServer classes include the same logging function.

    @@ -644,7 +644,7 @@

    Example3 starts an HTTP server that allows to accept the WebSocket connection requests.

    -

    Would you access to http://localhost:4649 to do WebSocket Echo Test with your web browser after Example3 running?

    +

    Would you access to http://localhost:4649 to do WebSocket Echo Test with your web browser while Example3 is running?

    Supported WebSocket Specifications

    @@ -690,4 +690,3 @@

    - diff --git a/params.json b/params.json index 5d42becfa..17345d6e9 100644 --- a/params.json +++ b/params.json @@ -1 +1 @@ -{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)\r\n- **[WebGL Networking]** (Not available in WebGL)\r\n- **Weak Support for the System.IO.Compression** (The compression extension isn't available on Windows)\r\n- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\n**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i've fixed it in the asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\n`e.Type` property returns either `WebSocketSharp.Opcode.Text` or `WebSocketSharp.Opcode.Binary` that represents the type of the message. So by checking it, you can determine which item you should use.\r\n\r\nIf it returns `Opcode.Text`, you should use `e.Data` property that returns a `string` (represents the **Text** message).\r\n\r\nOr if it returns `Opcode.Binary`, you should use `e.RawData` property that returns a `byte[]` (represents the **Binary** message).\r\n\r\n```csharp\r\nif (e.Type == Opcode.Text) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.Binary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\nAnd if you would like to notify that a **Ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.\r\n\r\n```csharp\r\nws.EmitOnPing = true;\r\nws.OnMessage += (sender, e) => {\r\n if (e.Type == Opcode.Ping) {\r\n // Do something to notify that a Ping has been received.\r\n ...\r\n\r\n return;\r\n }\r\n\r\n ...\r\n};\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code indicating the reason for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it's called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method sends data to the client on a session in the service.\r\n\r\nIf you would like to access the sessions in the service, you should use the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method sends data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).\r\n\r\nAs a WebSocket client, if you would like to enable this extension, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header in the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n#### Ignoring the extensions ####\r\n\r\nAs a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n // To ignore the extensions requested from a client.\r\n IgnoreExtensions = true\r\n });\r\n```\r\n\r\nIf it's set to `true`, the server doesn't return the **Sec-WebSocket-Extensions header** in the connection response.\r\n\r\nI think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the WebSocket connection request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin header** with the WebSocket connection request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin header] before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the WebSocket connection request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in each WebSocket connection request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin header**, **Cookies**, or both included in each WebSocket connection request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty () &&\r\n Uri.TryCreate (val, UriKind.Absolute, out origin) &&\r\n origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'\r\n // if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n });\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin header]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)\r\n- **[WebGL Networking]** (Not available in WebGL)\r\n- **Weak Support for the System.IO.Compression** (The compression extension isn't available on Windows)\r\n- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\n**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i've fixed it in the asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\nIf you would like to get the message data, you should access `e.Data` or `e.RawData` property.\r\n\r\nAnd you can determine which property you should access by checking `e.IsText` or `e.IsBinary` property.\r\n\r\nIf `e.IsText` is `true`, you should access `e.Data` that returns a `string` (represents a **text** message).\r\n\r\nOr if `e.IsBinary` is `true`, you should access `e.RawData` that returns a `byte[]` (represents a **binary** message).\r\n\r\n```csharp\r\nif (e.IsText) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.IsBinary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\nAnd if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.\r\n\r\n```csharp\r\nws.EmitOnPing = true;\r\nws.OnMessage += (sender, e) => {\r\n if (e.IsPing) {\r\n // Do something to notify that a ping has been received.\r\n ...\r\n\r\n return;\r\n }\r\n};\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code indicating the reason for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it's called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method sends data to the client on a session in the service.\r\n\r\nIf you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method sends data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).\r\n\r\nAs a WebSocket client, if you would like to enable this extension, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header in the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n#### Ignoring the extensions ####\r\n\r\nAs a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n // To ignore the extensions requested from a client.\r\n IgnoreExtensions = true\r\n });\r\n```\r\n\r\nIf it's set to `true`, the server doesn't return the **Sec-WebSocket-Extensions header** in the connection response.\r\n\r\nI think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the WebSocket connection request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin header** with the WebSocket connection request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin header] before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the WebSocket connection request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in a WebSocket connection request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin header**, **Cookies**, or both included in a WebSocket connection request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty () &&\r\n Uri.TryCreate (val, UriKind.Absolute, out origin) &&\r\n origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'\r\n // if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n });\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin header]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file From a1385b45a63761f83dc7fb4c1956755e1c981dc8 Mon Sep 17 00:00:00 2001 From: sta Date: Sat, 16 Jul 2016 15:14:41 +0900 Subject: [PATCH 24/27] Create gh-pages branch via GitHub --- index.html | 221 +++++++++++++++++------------------ params.json | 8 +- stylesheets/github-light.css | 68 ++++++----- 3 files changed, 155 insertions(+), 142 deletions(-) diff --git a/index.html b/index.html index 34ced796d..c45f8ea92 100644 --- a/index.html +++ b/index.html @@ -20,7 +20,7 @@

    A C# implementation of the WebSocket protocol client

    -Welcome to websocket-sharp!

    +Welcome to websocket-sharp!

    websocket-sharp supports:

    @@ -35,28 +35,28 @@

  • HTTP Authentication
  • Query String, Origin header and Cookies
  • Connecting through the HTTP Proxy server
  • -
  • .NET 3.5 or later (includes compatible)
  • +
  • .NET Framework 3.5 or later (includes compatible environment such as Mono)
  • -Build

    +Build

    websocket-sharp is built as a single assembly, websocket-sharp.dll.

    websocket-sharp is developed with MonoDevelop. So the simple way to build is to open websocket-sharp.sln and run build for websocket-sharp project with any of the build configurations (e.g. Debug) in MonoDevelop.

    -Install

    +Install

    -Self Build

    +Self Build

    You should add your websocket-sharp.dll (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) to the library references of your project.

    If you would like to use that dll in your Unity project, you should add it to any folder of your project (e.g. Assets/Plugins) in Unity Editor.

    -NuGet Gallery

    +NuGet Gallery

    websocket-sharp is available on the NuGet Gallery, as still a prerelease version.

    @@ -70,7 +70,7 @@

    -Unity Asset Store

    +Unity Asset Store

    websocket-sharp is available on the Unity Asset Store.

    @@ -86,21 +86,23 @@

  • WebGL Networking (Not available in WebGL)
  • -Weak Support for the System.IO.Compression (The compression extension isn't available on Windows)
  • +Incompatible platform (Not available for such UWP) +
  • +Limited support for the System.IO.Compression (The compression extension isn't available on Windows)
  • .NET Socket Support for iOS/Android (It requires iOS/Android Pro if your Unity is earlier than Unity 5)
  • .NET API 2.0 compatibility level for iOS/Android
  • -

    .NET API 2.0 compatibility level for iOS/Android may require to fix lack of some features for later than .NET 2.0, such as the System.Func<...> delegates (so i've fixed it in the asset package).

    +

    .NET API 2.0 compatibility level for iOS/Android may require to fix lack of some features for later than .NET 2.0, such as the System.Func<...> delegates (so i have added them in that asset package).

    And it's priced at US$15. I think your $15 makes this project more better and accelerated, Thank you!

    -Usage

    +Usage

    -WebSocket Client

    +WebSocket Client

    using System;
     using WebSocketSharp;
    @@ -113,7 +115,7 @@ 

    { using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) { ws.OnMessage += (sender, e) => - Console.WriteLine ("Laputa says: " + e.Data); + Console.WriteLine ("Laputa says: " + e.Data); ws.Connect (); ws.Send ("BALUS"); @@ -124,7 +126,7 @@

    }

    -Step 1

    +Step 1

    Required namespace.

    @@ -133,7 +135,7 @@

    The WebSocket class exists in the WebSocketSharp namespace.

    -Step 2

    +Step 2

    Creating a new instance of the WebSocket class with the WebSocket URL to connect.

    @@ -144,29 +146,29 @@

    The WebSocket class inherits the System.IDisposable interface, so you can use the using statement. And the WebSocket connection will be closed with close status 1001 (going away) when the control leaves the using block.

    -Step 3

    +Step 3

    Setting the WebSocket events.

    -WebSocket.OnOpen Event
    +WebSocket.OnOpen Event

    A WebSocket.OnOpen event occurs when the WebSocket connection has been established.

    ws.OnOpen += (sender, e) => {
    -  ...
    -};
    + ... + };

    e has passed as the System.EventArgs.Empty, so you don't need to use it.

    -WebSocket.OnMessage Event
    +WebSocket.OnMessage Event

    A WebSocket.OnMessage event occurs when the WebSocket receives a message.

    ws.OnMessage += (sender, e) => {
    -  ...
    -};
    + ... + };

    e has passed as a WebSocketSharp.MessageEventArgs.

    @@ -196,22 +198,22 @@
    ws.EmitOnPing = true;
     ws.OnMessage += (sender, e) => {
    -  if (e.IsPing) {
    -    // Do something to notify that a ping has been received.
    -    ...
    +    if (e.IsPing) {
    +      // Do something to notify that a ping has been received.
    +      ...
     
    -    return;
    -  }
    -};
    + return; + } + };
    -WebSocket.OnError Event
    +WebSocket.OnError Event

    A WebSocket.OnError event occurs when the WebSocket gets an error.

    ws.OnError += (sender, e) => {
    -  ...
    -};
    + ... + };

    e has passed as a WebSocketSharp.ErrorEventArgs.

    @@ -220,20 +222,20 @@

    If the error is due to an exception, e.Exception property returns a System.Exception instance that caused the error.

    -WebSocket.OnClose Event
    +WebSocket.OnClose Event

    A WebSocket.OnClose event occurs when the WebSocket connection has been closed.

    ws.OnClose += (sender, e) => {
    -  ...
    -};
    + ... + };

    e has passed as a WebSocketSharp.CloseEventArgs.

    -

    e.Code property returns a ushort that represents the status code indicating the reason for the close, and e.Reason property returns a string that represents the reason for the close.

    +

    e.Code property returns a ushort that represents the status code for the close, and e.Reason property returns a string that represents the reason for the close.

    -Step 4

    +Step 4

    Connecting to the WebSocket server.

    @@ -242,7 +244,7 @@

    If you would like to connect to the server asynchronously, you should use the WebSocket.ConnectAsync () method.

    -Step 5

    +Step 5

    Sending data to the WebSocket server.

    @@ -259,7 +261,7 @@

    And also if you would like to do something when the send is complete, you should set completed to any Action<bool> delegate.

    -Step 6

    +Step 6

    Closing the WebSocket connection.

    @@ -274,7 +276,7 @@

    If you would like to close the connection asynchronously, you should use the WebSocket.CloseAsync method.

    -WebSocket Server

    +WebSocket Server
    using System;
     using WebSocketSharp;
    @@ -308,7 +310,7 @@ 

    }

    -Step 1

    +Step 1

    Required namespace.

    @@ -317,7 +319,7 @@

    The WebSocketBehavior and WebSocketServer classes exist in the WebSocketSharp.Server namespace.

    -Step 2

    +Step 2

    Creating the class that inherits the WebSocketBehavior class.

    @@ -363,18 +365,18 @@

    You can define the behavior of any WebSocket service by creating the class that inherits the WebSocketBehavior class.

    -

    If you override the WebSocketBehavior.OnMessage (MessageEventArgs) method, it's called when the WebSocket used in a session in the service receives a message.

    +

    If you override the WebSocketBehavior.OnMessage (MessageEventArgs) method, it will be called when the WebSocket used in a session in the service receives a message.

    -

    And if you override the WebSocketBehavior.OnOpen (), WebSocketBehavior.OnError (ErrorEventArgs), and WebSocketBehavior.OnClose (CloseEventArgs) methods, each of them is called when each event of the WebSocket (the OnOpen, OnError, and OnClose events) occurs.

    +

    And if you override the WebSocketBehavior.OnOpen (), WebSocketBehavior.OnError (ErrorEventArgs), and WebSocketBehavior.OnClose (CloseEventArgs) methods, each of them will be called when each of the WebSocket events (OnOpen, OnError, and OnClose) occurs.

    -

    The WebSocketBehavior.Send method sends data to the client on a session in the service.

    +

    The WebSocketBehavior.Send method can send data to the client on a session in the service.

    If you would like to get the sessions in the service, you should access the WebSocketBehavior.Sessions property (returns a WebSocketSharp.Server.WebSocketSessionManager).

    -

    The WebSocketBehavior.Sessions.Broadcast method sends data to every client in the service.

    +

    The WebSocketBehavior.Sessions.Broadcast method can send data to every client in the service.

    -Step 3

    +Step 3

    Creating a new instance of the WebSocketServer class.

    @@ -397,14 +399,14 @@

    -Step 4

    +Step 4

    Starting the WebSocket server.

    wssv.Start ();

    -Step 5

    +Step 5

    Stopping the WebSocket server.

    @@ -415,9 +417,9 @@

    You can use the WebSocketServer.Stop (), WebSocketServer.Stop (ushort, string), or WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string) method to stop the server.

    -HTTP Server with the WebSocket

    +HTTP Server with the WebSocket -

    I modified the System.Net.HttpListener, System.Net.HttpListenerContext, and some other classes of Mono to create the HTTP server that allows to accept the WebSocket connection requests.

    +

    I have modified the System.Net.HttpListener, System.Net.HttpListenerContext, and some other classes from Mono to create an HTTP server that allows to accept the WebSocket handshake requests.

    So websocket-sharp provides the WebSocketSharp.Server.HttpServer class.

    @@ -431,10 +433,10 @@

    For more information, would you see Example3?

    -WebSocket Extensions

    +WebSocket Extensions

    -Per-message Compression

    +Per-message Compression

    websocket-sharp supports the Per-message Compression extension (but doesn't support this extension with the context take over).

    @@ -442,7 +444,7 @@

    ws.Compression = CompressionMethod.Deflate;
    -

    And then your client will send the following header in the connection request to the server.

    +

    And then your client will send the following header in the handshake request to the server.

    Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover
     
    @@ -450,23 +452,25 @@

    If the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.

    -Ignoring the extensions

    +Ignoring the extensions

    As a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the WebSocketBehavior.IgnoreExtensions property to true in your WebSocketBehavior constructor or initializing it, such as the following.

    wssv.AddWebSocketService<Chat> (
       "/Chat",
    -  () => new Chat () {
    -    // To ignore the extensions requested from a client.
    -    IgnoreExtensions = true
    -  });
    + () => + new Chat () { + // To ignore the extensions requested from a client. + IgnoreExtensions = true + } +); -

    If it's set to true, the server doesn't return the Sec-WebSocket-Extensions header in the connection response.

    +

    If it's set to true, the service will not return the Sec-WebSocket-Extensions header in its handshake response.

    I think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.

    -Secure Connection

    +Secure Connection

    websocket-sharp supports the Secure Connection with SSL/TLS.

    @@ -495,7 +499,7 @@

    new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");

    -HTTP Authentication

    +HTTP Authentication

    websocket-sharp supports the HTTP Authentication (Basic/Digest).

    @@ -503,45 +507,45 @@

    ws.SetCredentials ("nobita", "password", preAuth);
    -

    If preAuth is true, the WebSocket sends the Basic authentication credentials with the first connection request to the server.

    +

    If preAuth is true, the WebSocket sends the Basic authentication credentials with the first handshake request to the server.

    -

    Or if preAuth is false, the WebSocket sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.

    +

    Or if preAuth is false, the WebSocket sends either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication credentials with the second handshake request to the server.

    As a WebSocket Server, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.

    wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
     wssv.Realm = "WebSocket Test";
     wssv.UserCredentialsFinder = id => {
    -  var name = id.Name;
    +    var name = id.Name;
     
    -  // Return user name, password, and roles.
    -  return name == "nobita"
    -         ? new NetworkCredential (name, "password", "gunfighter")
    -         : null; // If the user credentials aren't found.
    -};
    + // Return user name, password, and roles. + return name == "nobita" + ? new NetworkCredential (name, "password", "gunfighter") + : null; // If the user credentials aren't found. + };

    If you would like to provide the Digest authentication, you should set such as the following.

    wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;

    -Query String, Origin header and Cookies

    +Query String, Origin header and Cookies -

    As a WebSocket Client, if you would like to send the Query String with the WebSocket connection request to the server, you should create a new instance of the WebSocket class with the WebSocket URL that includes the Query string parameters.

    +

    As a WebSocket Client, if you would like to send the Query String with the handshake request to the server, you should create a new instance of the WebSocket class with the WebSocket URL that includes the Query string parameters.

    using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
       ...
     }
    -

    And if you would like to send the Origin header with the WebSocket connection request to the server, you should set the WebSocket.Origin property to an allowable value as the Origin header before connecting, such as the following.

    +

    And if you would like to send the Origin header with the handshake request to the server, you should set the WebSocket.Origin property to an allowable value as the Origin header before connecting, such as the following.

    ws.Origin = "http://example.com";
    -

    And also if you would like to send the Cookies with the WebSocket connection request to the server, you should set any cookie by using the WebSocket.SetCookie (WebSocketSharp.Net.Cookie) method before connecting, such as the following.

    +

    And also if you would like to send the Cookies with the handshake request to the server, you should set any cookie by using the WebSocket.SetCookie (WebSocketSharp.Net.Cookie) method before connecting, such as the following.

    ws.SetCookie (new Cookie ("name", "nobita"));
    -

    As a WebSocket Server, if you would like to get the Query String included in a WebSocket connection request, you should access the WebSocketBehavior.Context.QueryString property, such as the following.

    +

    As a WebSocket Server, if you would like to get the Query String included in a handshake request, you should access the WebSocketBehavior.Context.QueryString property, such as the following.

    public class Chat : WebSocketBehavior
     {
    @@ -556,34 +560,36 @@ 

    ... }

    -

    And if you would like to validate the Origin header, Cookies, or both included in a WebSocket connection request, you should set each validation with your WebSocketBehavior, for example, by using the AddWebSocketService<TBehavior> (string, Func<TBehavior>) method with initializing, such as the following.

    +

    And if you would like to validate the Origin header, Cookies, or both included in a handshake request, you should set each validation with your WebSocketBehavior, for example, by using the AddWebSocketService<TBehavior> (string, Func<TBehavior>) method with initializing, such as the following.

    wssv.AddWebSocketService<Chat> (
       "/Chat",
    -  () => new Chat () {
    -    OriginValidator = val => {
    -      // Check the value of the Origin header, and return true if valid.
    -      Uri origin;
    -      return !val.IsNullOrEmpty () &&
    -             Uri.TryCreate (val, UriKind.Absolute, out origin) &&
    -             origin.Host == "example.com";
    -    },
    -    CookiesValidator = (req, res) => {
    -      // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'
    -      // if necessary.
    -      foreach (Cookie cookie in req) {
    -        cookie.Expired = true;
    -        res.Add (cookie);
    -      }
    -
    -      return true; // If valid.
    +  () =>
    +    new Chat () {
    +      OriginValidator = val => {
    +          // Check the value of the Origin header, and return true if valid.
    +          Uri origin;
    +          return !val.IsNullOrEmpty ()
    +                 && Uri.TryCreate (val, UriKind.Absolute, out origin)
    +                 && origin.Host == "example.com";
    +        },
    +      CookiesValidator = (req, res) => {
    +          // Check the cookies in 'req', and set the cookies to send to
    +          // the client with 'res' if necessary.
    +          foreach (Cookie cookie in req) {
    +            cookie.Expired = true;
    +            res.Add (cookie);
    +          }
    +
    +          return true; // If valid.
    +        }
         }
    -  });
    +);

    And also if you would like to get each value of the Origin header and cookies, you should access each of the WebSocketBehavior.Context.Origin and WebSocketBehavior.Context.CookieCollection properties.

    -Connecting through the HTTP Proxy server

    +Connecting through the HTTP Proxy server

    websocket-sharp supports to connect through the HTTP Proxy server.

    @@ -592,16 +598,16 @@

    var ws = new WebSocket ("ws://example.com");
     ws.SetProxy ("http://localhost:3128", "nobita", "password");
    -

    I tested this with the Squid. And it's necessary to disable the following configuration option in squid.conf (e.g. /etc/squid/squid.conf).

    +

    I have tested this with the Squid. And it's necessary to disable the following configuration option in squid.conf (e.g. /etc/squid/squid.conf).

    # Deny CONNECT to other than SSL ports
     #http_access deny CONNECT !SSL_ports
     

    -Logging

    +Logging -

    The WebSocket class includes the own logging function.

    +

    The WebSocket class has the own logging function.

    You can use it with the WebSocket.Log property (returns a WebSocketSharp.Logger).

    @@ -615,39 +621,32 @@

    ws.Log.Debug ("This is a debug message.");
    -

    The WebSocketServer and HttpServer classes include the same logging function.

    +

    The WebSocketServer and HttpServer classes have the same logging function.

    -Examples

    +Examples

    Examples using websocket-sharp.

    -Example

    +Example

    Example connects to the Echo server with the WebSocket.

    -Example1

    - -

    Example1 connects to the Audio Data delivery server with the WebSocket. (But it's only implemented the chat feature, still unfinished.)

    - -

    And Example1 uses Json.NET.

    - -

    -Example2

    +Example2

    Example2 starts a WebSocket server.

    -Example3

    +Example3 -

    Example3 starts an HTTP server that allows to accept the WebSocket connection requests.

    +

    Example3 starts an HTTP server that allows to accept the WebSocket handshake requests.

    Would you access to http://localhost:4649 to do WebSocket Echo Test with your web browser while Example3 is running?

    -Supported WebSocket Specifications

    +Supported WebSocket Specifications

    websocket-sharp supports RFC 6455, and it's based on the following WebSocket references:

    @@ -665,7 +664,7 @@

    -License

    +License

    websocket-sharp is provided under The MIT License.

    diff --git a/params.json b/params.json index 17345d6e9..bec69800c 100644 --- a/params.json +++ b/params.json @@ -1 +1,7 @@ -{"name":"websocket-sharp","tagline":"A C# implementation of the WebSocket protocol client and server","body":"## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET **3.5** or later (includes compatible)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)\r\n- **[WebGL Networking]** (Not available in WebGL)\r\n- **Weak Support for the System.IO.Compression** (The compression extension isn't available on Windows)\r\n- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\n**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i've fixed it in the asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\nIf you would like to get the message data, you should access `e.Data` or `e.RawData` property.\r\n\r\nAnd you can determine which property you should access by checking `e.IsText` or `e.IsBinary` property.\r\n\r\nIf `e.IsText` is `true`, you should access `e.Data` that returns a `string` (represents a **text** message).\r\n\r\nOr if `e.IsBinary` is `true`, you should access `e.RawData` that returns a `byte[]` (represents a **binary** message).\r\n\r\n```csharp\r\nif (e.IsText) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.IsBinary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\nAnd if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.\r\n\r\n```csharp\r\nws.EmitOnPing = true;\r\nws.OnMessage += (sender, e) => {\r\n if (e.IsPing) {\r\n // Do something to notify that a ping has been received.\r\n ...\r\n\r\n return;\r\n }\r\n};\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code indicating the reason for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it's called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method sends data to the client on a session in the service.\r\n\r\nIf you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method sends data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes of **[Mono]** to create the HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).\r\n\r\nAs a WebSocket client, if you would like to enable this extension, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header in the connection request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n#### Ignoring the extensions ####\r\n\r\nAs a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n // To ignore the extensions requested from a client.\r\n IgnoreExtensions = true\r\n });\r\n```\r\n\r\nIf it's set to `true`, the server doesn't return the **Sec-WebSocket-Extensions header** in the connection response.\r\n\r\nI think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n};\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the WebSocket connection request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin header** with the WebSocket connection request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin header] before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the WebSocket connection request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in a WebSocket connection request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin header**, **Cookies**, or both included in a WebSocket connection request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () => new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty () &&\r\n Uri.TryCreate (val, UriKind.Absolute, out origin) &&\r\n origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'\r\n // if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n });\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class includes the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n**[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)\r\n\r\nAnd Example1 uses **[Json.NET]**.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin header]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file +{ + "name": "websocket-sharp", + "tagline": "A C# implementation of the WebSocket protocol client and server", + "body": "## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET Framework **3.5** or later (includes compatible environment such as **[Mono]**)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)\r\n- **[WebGL Networking]** (Not available in WebGL)\r\n- **Incompatible platform** (Not available for such UWP)\r\n- **Limited support for the System.IO.Compression** (The compression extension isn't available on Windows)\r\n- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\n**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i have added them in that asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n };\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\nIf you would like to get the message data, you should access `e.Data` or `e.RawData` property.\r\n\r\nAnd you can determine which property you should access by checking `e.IsText` or `e.IsBinary` property.\r\n\r\nIf `e.IsText` is `true`, you should access `e.Data` that returns a `string` (represents a **text** message).\r\n\r\nOr if `e.IsBinary` is `true`, you should access `e.RawData` that returns a `byte[]` (represents a **binary** message).\r\n\r\n```csharp\r\nif (e.IsText) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.IsBinary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\nAnd if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.\r\n\r\n```csharp\r\nws.EmitOnPing = true;\r\nws.OnMessage += (sender, e) => {\r\n if (e.IsPing) {\r\n // Do something to notify that a ping has been received.\r\n ...\r\n\r\n return;\r\n }\r\n };\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it will be called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them will be called when each of the `WebSocket` events (`OnOpen`, `OnError`, and `OnClose`) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method can send data to the client on a session in the service.\r\n\r\nIf you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method can send data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI have modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes from **[Mono]** to create an HTTP server that allows to accept the WebSocket handshake requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).\r\n\r\nAs a WebSocket client, if you would like to enable this extension, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header in the handshake request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n#### Ignoring the extensions ####\r\n\r\nAs a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () =>\r\n new Chat () {\r\n // To ignore the extensions requested from a client.\r\n IgnoreExtensions = true\r\n }\r\n);\r\n```\r\n\r\nIf it's set to `true`, the service will not return the **Sec-WebSocket-Extensions** header in its handshake response.\r\n\r\nI think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first handshake request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication credentials with the second handshake request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n };\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the handshake request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin** header with the handshake request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin] header before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the handshake request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in a handshake request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin** header, **Cookies**, or both included in a handshake request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () =>\r\n new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty ()\r\n && Uri.TryCreate (val, UriKind.Absolute, out origin)\r\n && origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the cookies in 'req', and set the cookies to send to\r\n // the client with 'res' if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n }\r\n);\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI have tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class has the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes have the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket handshake requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n", + "google": "UA-9752433-2", + "note": "Don't delete this file! It's used internally to help with page regeneration." +} \ No newline at end of file diff --git a/stylesheets/github-light.css b/stylesheets/github-light.css index 872a6f4b2..0c6b24d82 100644 --- a/stylesheets/github-light.css +++ b/stylesheets/github-light.css @@ -1,17 +1,25 @@ /* - Copyright 2014 GitHub Inc. +The MIT License (MIT) - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +Copyright (c) 2016 GitHub, Inc. - http://www.apache.org/licenses/LICENSE-2.0 +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: - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +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. */ @@ -19,18 +27,18 @@ color: #969896; } -.pl-c1 /* constant, markup.raw, meta.diff.header, meta.module-reference, meta.property-name, support, support.constant, support.variable, variable.other.constant */, +.pl-c1 /* constant, variable.other.constant, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header */, .pl-s .pl-v /* string variable */ { color: #0086b3; } -.pl-e /* entity */, +.pl-e /* entity */, .pl-en /* entity.name */ { color: #795da3; } -.pl-s .pl-s1 /* string source */, -.pl-smi /* storage.modifier.import, storage.modifier.package, storage.type.java, variable.other, variable.parameter.function */ { +.pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */, +.pl-s .pl-s1 /* string source */ { color: #333; } @@ -42,13 +50,13 @@ color: #a71d5d; } -.pl-pds /* punctuation.definition.string, string.regexp.character-class */, -.pl-s /* string */, +.pl-s /* string */, +.pl-pds /* punctuation.definition.string, string.regexp.character-class */, .pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, -.pl-sr /* string.regexp */, -.pl-sr .pl-cce /* string.regexp constant.character.escape */, -.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */, -.pl-sr .pl-sre /* string.regexp source.ruby.embedded */ { +.pl-sr /* string.regexp */, +.pl-sr .pl-cce /* string.regexp constant.character.escape */, +.pl-sr .pl-sre /* string.regexp source.ruby.embedded */, +.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ { color: #183691; } @@ -61,24 +69,24 @@ } .pl-ii /* invalid.illegal */ { - background-color: #b52a1d; color: #f8f8f8; + background-color: #b52a1d; } .pl-sr .pl-cce /* string.regexp constant.character.escape */ { - color: #63a35c; font-weight: bold; + color: #63a35c; } .pl-ml /* markup.list */ { color: #693a17; } -.pl-mh /* markup.heading */, +.pl-mh /* markup.heading */, .pl-mh .pl-en /* markup.heading entity.name */, -.pl-ms /* meta.separator */ { - color: #1d3e81; +.pl-ms /* meta.separator */ { font-weight: bold; + color: #1d3e81; } .pl-mq /* markup.quote */ { @@ -86,28 +94,28 @@ } .pl-mi /* markup.italic */ { - color: #333; font-style: italic; + color: #333; } .pl-mb /* markup.bold */ { - color: #333; font-weight: bold; + color: #333; } .pl-md /* markup.deleted, meta.diff.header.from-file */ { - background-color: #ffecec; color: #bd2c00; + background-color: #ffecec; } .pl-mi1 /* markup.inserted, meta.diff.header.to-file */ { - background-color: #eaffea; color: #55a532; + background-color: #eaffea; } .pl-mdr /* meta.diff.range */ { - color: #795da3; font-weight: bold; + color: #795da3; } .pl-mo /* meta.output */ { From 3f8539970d2553dda16030aa39d94ec4a6744edb Mon Sep 17 00:00:00 2001 From: sta Date: Tue, 19 Jul 2016 15:00:12 +0900 Subject: [PATCH 25/27] Create gh-pages branch via GitHub --- index.html | 6 +++--- params.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index c45f8ea92..3633f5473 100644 --- a/index.html +++ b/index.html @@ -43,7 +43,7 @@

    websocket-sharp is built as a single assembly, websocket-sharp.dll.

    -

    websocket-sharp is developed with MonoDevelop. So the simple way to build is to open websocket-sharp.sln and run build for websocket-sharp project with any of the build configurations (e.g. Debug) in MonoDevelop.

    +

    websocket-sharp is developed with MonoDevelop. So a simple way to build is to open websocket-sharp.sln and run build for websocket-sharp project with any of the build configurations (e.g. Debug) in MonoDevelop.

    Install

    @@ -593,12 +593,12 @@

    websocket-sharp supports to connect through the HTTP Proxy server.

    -

    If you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the WebSocket.SetProxy (string, string, string) method before connecting.

    +

    If you would like to connect to a WebSocket server through the HTTP proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the WebSocket.SetProxy (string, string, string) method before connecting.

    var ws = new WebSocket ("ws://example.com");
     ws.SetProxy ("http://localhost:3128", "nobita", "password");
    -

    I have tested this with the Squid. And it's necessary to disable the following configuration option in squid.conf (e.g. /etc/squid/squid.conf).

    +

    I have tested this with Squid. It's necessary to disable the following configuration option in squid.conf (e.g. /etc/squid/squid.conf).

    # Deny CONNECT to other than SSL ports
     #http_access deny CONNECT !SSL_ports
    diff --git a/params.json b/params.json
    index bec69800c..344d6ca80 100644
    --- a/params.json
    +++ b/params.json
    @@ -1,7 +1,7 @@
     {
       "name": "websocket-sharp",
       "tagline": "A C# implementation of the WebSocket protocol client and server",
    -  "body": "## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET Framework **3.5** or later (includes compatible environment such as **[Mono]**)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n    PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)\r\n- **[WebGL Networking]** (Not available in WebGL)\r\n- **Incompatible platform** (Not available for such UWP)\r\n- **Limited support for the System.IO.Compression** (The compression extension isn't available on Windows)\r\n- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\n**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i have added them in that asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n  public class Program\r\n  {\r\n    public static void Main (string[] args)\r\n    {\r\n      using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n        ws.OnMessage += (sender, e) =>\r\n            Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n        ws.Connect ();\r\n        ws.Send (\"BALUS\");\r\n        Console.ReadKey (true);\r\n      }\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n  ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n    ...\r\n  };\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n    ...\r\n  };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\nIf you would like to get the message data, you should access `e.Data` or `e.RawData` property.\r\n\r\nAnd you can determine which property you should access by checking `e.IsText` or `e.IsBinary` property.\r\n\r\nIf `e.IsText` is `true`, you should access `e.Data` that returns a `string` (represents a **text** message).\r\n\r\nOr if `e.IsBinary` is `true`, you should access `e.RawData` that returns a `byte[]` (represents a **binary** message).\r\n\r\n```csharp\r\nif (e.IsText) {\r\n  // Do something with e.Data.\r\n  ...\r\n\r\n  return;\r\n}\r\n\r\nif (e.IsBinary) {\r\n  // Do something with e.RawData.\r\n  ...\r\n\r\n  return;\r\n}\r\n```\r\n\r\nAnd if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.\r\n\r\n```csharp\r\nws.EmitOnPing = true;\r\nws.OnMessage += (sender, e) => {\r\n    if (e.IsPing) {\r\n      // Do something to notify that a ping has been received.\r\n      ...\r\n\r\n      return;\r\n    }\r\n  };\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n    ...\r\n  };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n    ...\r\n  };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n  public class Laputa : WebSocketBehavior\r\n  {\r\n    protected override void OnMessage (MessageEventArgs e)\r\n    {\r\n      var msg = e.Data == \"BALUS\"\r\n                ? \"I've been balused already...\"\r\n                : \"I'm not available now.\";\r\n\r\n      Send (msg);\r\n    }\r\n  }\r\n\r\n  public class Program\r\n  {\r\n    public static void Main (string[] args)\r\n    {\r\n      var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n      wssv.AddWebSocketService (\"/Laputa\");\r\n      wssv.Start ();\r\n      Console.ReadKey (true);\r\n      wssv.Stop ();\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n  protected override void OnMessage (MessageEventArgs e)\r\n  {\r\n    Send (e.Data);\r\n  }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n  private string _suffix;\r\n\r\n  public Chat ()\r\n    : this (null)\r\n  {\r\n  }\r\n\r\n  public Chat (string suffix)\r\n  {\r\n    _suffix = suffix ?? String.Empty;\r\n  }\r\n\r\n  protected override void OnMessage (MessageEventArgs e)\r\n  {\r\n    Sessions.Broadcast (e.Data + _suffix);\r\n  }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it will be called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them will be called when each of the `WebSocket` events (`OnOpen`, `OnError`, and `OnClose`) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method can send data to the client on a session in the service.\r\n\r\nIf you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method can send data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n    $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI have modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes from **[Mono]** to create an HTTP server that allows to accept the WebSocket handshake requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).\r\n\r\nAs a WebSocket client, if you would like to enable this extension, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header in the handshake request to the server.\r\n\r\n    Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n#### Ignoring the extensions ####\r\n\r\nAs a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n  \"/Chat\",\r\n  () =>\r\n    new Chat () {\r\n      // To ignore the extensions requested from a client.\r\n      IgnoreExtensions = true\r\n    }\r\n);\r\n```\r\n\r\nIf it's set to `true`, the service will not return the **Sec-WebSocket-Extensions** header in its handshake response.\r\n\r\nI think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n  ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n  (sender, certificate, chain, sslPolicyErrors) => {\r\n    // Do something to validate the server certificate.\r\n    ...\r\n\r\n    return true; // If the server certificate is valid.\r\n  };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n  new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first handshake request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication credentials with the second handshake request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n    var name = id.Name;\r\n\r\n    // Return user name, password, and roles.\r\n    return name == \"nobita\"\r\n           ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n           : null; // If the user credentials aren't found.\r\n  };\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the handshake request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n  ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin** header with the handshake request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin] header before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the handshake request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in a handshake request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n  private string _name;\r\n  ...\r\n\r\n  protected override void OnOpen ()\r\n  {\r\n    _name = Context.QueryString[\"name\"];\r\n  }\r\n\r\n  ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin** header, **Cookies**, or both included in a handshake request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n  \"/Chat\",\r\n  () =>\r\n    new Chat () {\r\n      OriginValidator = val => {\r\n          // Check the value of the Origin header, and return true if valid.\r\n          Uri origin;\r\n          return !val.IsNullOrEmpty ()\r\n                 && Uri.TryCreate (val, UriKind.Absolute, out origin)\r\n                 && origin.Host == \"example.com\";\r\n        },\r\n      CookiesValidator = (req, res) => {\r\n          // Check the cookies in 'req', and set the cookies to send to\r\n          // the client with 'res' if necessary.\r\n          foreach (Cookie cookie in req) {\r\n            cookie.Expired = true;\r\n            res.Add (cookie);\r\n          }\r\n\r\n          return true; // If valid.\r\n        }\r\n    }\r\n);\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI have tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class has the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes have the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket handshake requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n",
    +  "body": "## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET Framework **3.5** or later (includes compatible environment such as **[Mono]**)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So a simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n    PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)\r\n- **[WebGL Networking]** (Not available in WebGL)\r\n- **Incompatible platform** (Not available for such UWP)\r\n- **Limited support for the System.IO.Compression** (The compression extension isn't available on Windows)\r\n- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\n**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i have added them in that asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n  public class Program\r\n  {\r\n    public static void Main (string[] args)\r\n    {\r\n      using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n        ws.OnMessage += (sender, e) =>\r\n            Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n        ws.Connect ();\r\n        ws.Send (\"BALUS\");\r\n        Console.ReadKey (true);\r\n      }\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n  ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n    ...\r\n  };\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n    ...\r\n  };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\nIf you would like to get the message data, you should access `e.Data` or `e.RawData` property.\r\n\r\nAnd you can determine which property you should access by checking `e.IsText` or `e.IsBinary` property.\r\n\r\nIf `e.IsText` is `true`, you should access `e.Data` that returns a `string` (represents a **text** message).\r\n\r\nOr if `e.IsBinary` is `true`, you should access `e.RawData` that returns a `byte[]` (represents a **binary** message).\r\n\r\n```csharp\r\nif (e.IsText) {\r\n  // Do something with e.Data.\r\n  ...\r\n\r\n  return;\r\n}\r\n\r\nif (e.IsBinary) {\r\n  // Do something with e.RawData.\r\n  ...\r\n\r\n  return;\r\n}\r\n```\r\n\r\nAnd if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.\r\n\r\n```csharp\r\nws.EmitOnPing = true;\r\nws.OnMessage += (sender, e) => {\r\n    if (e.IsPing) {\r\n      // Do something to notify that a ping has been received.\r\n      ...\r\n\r\n      return;\r\n    }\r\n  };\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n    ...\r\n  };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n    ...\r\n  };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n  public class Laputa : WebSocketBehavior\r\n  {\r\n    protected override void OnMessage (MessageEventArgs e)\r\n    {\r\n      var msg = e.Data == \"BALUS\"\r\n                ? \"I've been balused already...\"\r\n                : \"I'm not available now.\";\r\n\r\n      Send (msg);\r\n    }\r\n  }\r\n\r\n  public class Program\r\n  {\r\n    public static void Main (string[] args)\r\n    {\r\n      var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n      wssv.AddWebSocketService (\"/Laputa\");\r\n      wssv.Start ();\r\n      Console.ReadKey (true);\r\n      wssv.Stop ();\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n  protected override void OnMessage (MessageEventArgs e)\r\n  {\r\n    Send (e.Data);\r\n  }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n  private string _suffix;\r\n\r\n  public Chat ()\r\n    : this (null)\r\n  {\r\n  }\r\n\r\n  public Chat (string suffix)\r\n  {\r\n    _suffix = suffix ?? String.Empty;\r\n  }\r\n\r\n  protected override void OnMessage (MessageEventArgs e)\r\n  {\r\n    Sessions.Broadcast (e.Data + _suffix);\r\n  }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it will be called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them will be called when each of the `WebSocket` events (`OnOpen`, `OnError`, and `OnClose`) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method can send data to the client on a session in the service.\r\n\r\nIf you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method can send data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n    $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI have modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes from **[Mono]** to create an HTTP server that allows to accept the WebSocket handshake requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).\r\n\r\nAs a WebSocket client, if you would like to enable this extension, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header in the handshake request to the server.\r\n\r\n    Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n#### Ignoring the extensions ####\r\n\r\nAs a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n  \"/Chat\",\r\n  () =>\r\n    new Chat () {\r\n      // To ignore the extensions requested from a client.\r\n      IgnoreExtensions = true\r\n    }\r\n);\r\n```\r\n\r\nIf it's set to `true`, the service will not return the **Sec-WebSocket-Extensions** header in its handshake response.\r\n\r\nI think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n  ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n  (sender, certificate, chain, sslPolicyErrors) => {\r\n    // Do something to validate the server certificate.\r\n    ...\r\n\r\n    return true; // If the server certificate is valid.\r\n  };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n  new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first handshake request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication credentials with the second handshake request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n    var name = id.Name;\r\n\r\n    // Return user name, password, and roles.\r\n    return name == \"nobita\"\r\n           ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n           : null; // If the user credentials aren't found.\r\n  };\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the handshake request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n  ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin** header with the handshake request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin] header before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the handshake request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in a handshake request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n  private string _name;\r\n  ...\r\n\r\n  protected override void OnOpen ()\r\n  {\r\n    _name = Context.QueryString[\"name\"];\r\n  }\r\n\r\n  ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin** header, **Cookies**, or both included in a handshake request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n  \"/Chat\",\r\n  () =>\r\n    new Chat () {\r\n      OriginValidator = val => {\r\n          // Check the value of the Origin header, and return true if valid.\r\n          Uri origin;\r\n          return !val.IsNullOrEmpty ()\r\n                 && Uri.TryCreate (val, UriKind.Absolute, out origin)\r\n                 && origin.Host == \"example.com\";\r\n        },\r\n      CookiesValidator = (req, res) => {\r\n          // Check the cookies in 'req', and set the cookies to send to\r\n          // the client with 'res' if necessary.\r\n          foreach (Cookie cookie in req) {\r\n            cookie.Expired = true;\r\n            res.Add (cookie);\r\n          }\r\n\r\n          return true; // If valid.\r\n        }\r\n    }\r\n);\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI have tested this with **[Squid]**. It's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class has the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes have the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket handshake requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n",
       "google": "UA-9752433-2",
       "note": "Don't delete this file! It's used internally to help with page regeneration."
     }
    \ No newline at end of file
    
    From 9b3b2c58afb5edb348b8a0f1d952e1531378c7c0 Mon Sep 17 00:00:00 2001
    From: sta 
    Date: Sat, 31 Dec 2016 16:41:03 +0900
    Subject: [PATCH 26/27] Set theme jekyll-theme-cayman and migrate Page
     Generator content
    
    ---
     _config.yml |   8 +
     index.html  | 691 ----------------------------------------------------
     index.md    | 686 +++++++++++++++++++++++++++++++++++++++++++++++++++
     params.json |   7 -
     4 files changed, 694 insertions(+), 698 deletions(-)
     create mode 100644 _config.yml
     delete mode 100644 index.html
     create mode 100644 index.md
     delete mode 100644 params.json
    
    diff --git a/_config.yml b/_config.yml
    new file mode 100644
    index 000000000..2dad95fc8
    --- /dev/null
    +++ b/_config.yml
    @@ -0,0 +1,8 @@
    +title: websocket-sharp
    +description: A C# implementation of the WebSocket protocol client and server
    +google_analytics: UA-9752433-2
    +show_downloads: true
    +theme: jekyll-theme-cayman
    +
    +gems:
    +  - jekyll-mentions
    diff --git a/index.html b/index.html
    deleted file mode 100644
    index 3633f5473..000000000
    --- a/index.html
    +++ /dev/null
    @@ -1,691 +0,0 @@
    -
    -
    -  
    -    
    -    websocket-sharp by sta
    -    
    -    
    -    
    -    
    -    
    -  
    -  
    -    
    -
    -    
    -

    -Welcome to websocket-sharp!

    - -

    websocket-sharp supports:

    - - - -

    -Build

    - -

    websocket-sharp is built as a single assembly, websocket-sharp.dll.

    - -

    websocket-sharp is developed with MonoDevelop. So a simple way to build is to open websocket-sharp.sln and run build for websocket-sharp project with any of the build configurations (e.g. Debug) in MonoDevelop.

    - -

    -Install

    - -

    -Self Build

    - -

    You should add your websocket-sharp.dll (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) to the library references of your project.

    - -

    If you would like to use that dll in your Unity project, you should add it to any folder of your project (e.g. Assets/Plugins) in Unity Editor.

    - -

    -NuGet Gallery

    - -

    websocket-sharp is available on the NuGet Gallery, as still a prerelease version.

    - - - -

    You can add websocket-sharp to your project with the NuGet Package Manager, by using the following command in the Package Manager Console.

    - -
    PM> Install-Package WebSocketSharp -Pre
    -
    - -

    -Unity Asset Store

    - -

    websocket-sharp is available on the Unity Asset Store.

    - - - -

    It works with Unity Free, but there are some limitations:

    - -
      -
    • -Security Sandbox of the Webplayer (The server isn't available in Web Player)
    • -
    • -WebGL Networking (Not available in WebGL)
    • -
    • -Incompatible platform (Not available for such UWP)
    • -
    • -Limited support for the System.IO.Compression (The compression extension isn't available on Windows)
    • -
    • -.NET Socket Support for iOS/Android (It requires iOS/Android Pro if your Unity is earlier than Unity 5)
    • -
    • .NET API 2.0 compatibility level for iOS/Android
    • -
    - -

    .NET API 2.0 compatibility level for iOS/Android may require to fix lack of some features for later than .NET 2.0, such as the System.Func<...> delegates (so i have added them in that asset package).

    - -

    And it's priced at US$15. I think your $15 makes this project more better and accelerated, Thank you!

    - -

    -Usage

    - -

    -WebSocket Client

    - -
    using System;
    -using WebSocketSharp;
    -
    -namespace Example
    -{
    -  public class Program
    -  {
    -    public static void Main (string[] args)
    -    {
    -      using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) {
    -        ws.OnMessage += (sender, e) =>
    -            Console.WriteLine ("Laputa says: " + e.Data);
    -
    -        ws.Connect ();
    -        ws.Send ("BALUS");
    -        Console.ReadKey (true);
    -      }
    -    }
    -  }
    -}
    - -

    -Step 1

    - -

    Required namespace.

    - -
    using WebSocketSharp;
    - -

    The WebSocket class exists in the WebSocketSharp namespace.

    - -

    -Step 2

    - -

    Creating a new instance of the WebSocket class with the WebSocket URL to connect.

    - -
    using (var ws = new WebSocket ("ws://example.com")) {
    -  ...
    -}
    - -

    The WebSocket class inherits the System.IDisposable interface, so you can use the using statement. And the WebSocket connection will be closed with close status 1001 (going away) when the control leaves the using block.

    - -

    -Step 3

    - -

    Setting the WebSocket events.

    - -
    -WebSocket.OnOpen Event
    - -

    A WebSocket.OnOpen event occurs when the WebSocket connection has been established.

    - -
    ws.OnOpen += (sender, e) => {
    -    ...
    -  };
    - -

    e has passed as the System.EventArgs.Empty, so you don't need to use it.

    - -
    -WebSocket.OnMessage Event
    - -

    A WebSocket.OnMessage event occurs when the WebSocket receives a message.

    - -
    ws.OnMessage += (sender, e) => {
    -    ...
    -  };
    - -

    e has passed as a WebSocketSharp.MessageEventArgs.

    - -

    If you would like to get the message data, you should access e.Data or e.RawData property.

    - -

    And you can determine which property you should access by checking e.IsText or e.IsBinary property.

    - -

    If e.IsText is true, you should access e.Data that returns a string (represents a text message).

    - -

    Or if e.IsBinary is true, you should access e.RawData that returns a byte[] (represents a binary message).

    - -
    if (e.IsText) {
    -  // Do something with e.Data.
    -  ...
    -
    -  return;
    -}
    -
    -if (e.IsBinary) {
    -  // Do something with e.RawData.
    -  ...
    -
    -  return;
    -}
    - -

    And if you would like to notify that a ping has been received, via this event, you should set the WebSocket.EmitOnPing property to true, such as the following.

    - -
    ws.EmitOnPing = true;
    -ws.OnMessage += (sender, e) => {
    -    if (e.IsPing) {
    -      // Do something to notify that a ping has been received.
    -      ...
    -
    -      return;
    -    }
    -  };
    - -
    -WebSocket.OnError Event
    - -

    A WebSocket.OnError event occurs when the WebSocket gets an error.

    - -
    ws.OnError += (sender, e) => {
    -    ...
    -  };
    - -

    e has passed as a WebSocketSharp.ErrorEventArgs.

    - -

    e.Message property returns a string that represents the error message.

    - -

    If the error is due to an exception, e.Exception property returns a System.Exception instance that caused the error.

    - -
    -WebSocket.OnClose Event
    - -

    A WebSocket.OnClose event occurs when the WebSocket connection has been closed.

    - -
    ws.OnClose += (sender, e) => {
    -    ...
    -  };
    - -

    e has passed as a WebSocketSharp.CloseEventArgs.

    - -

    e.Code property returns a ushort that represents the status code for the close, and e.Reason property returns a string that represents the reason for the close.

    - -

    -Step 4

    - -

    Connecting to the WebSocket server.

    - -
    ws.Connect ();
    - -

    If you would like to connect to the server asynchronously, you should use the WebSocket.ConnectAsync () method.

    - -

    -Step 5

    - -

    Sending data to the WebSocket server.

    - -
    ws.Send (data);
    - -

    The WebSocket.Send method is overloaded.

    - -

    You can use the WebSocket.Send (string), WebSocket.Send (byte[]), or WebSocket.Send (System.IO.FileInfo) method to send the data.

    - -

    If you would like to send the data asynchronously, you should use the WebSocket.SendAsync method.

    - -
    ws.SendAsync (data, completed);
    - -

    And also if you would like to do something when the send is complete, you should set completed to any Action<bool> delegate.

    - -

    -Step 6

    - -

    Closing the WebSocket connection.

    - -
    ws.Close (code, reason);
    - -

    If you would like to close the connection explicitly, you should use the WebSocket.Close method.

    - -

    The WebSocket.Close method is overloaded.

    - -

    You can use the WebSocket.Close (), WebSocket.Close (ushort), WebSocket.Close (WebSocketSharp.CloseStatusCode), WebSocket.Close (ushort, string), or WebSocket.Close (WebSocketSharp.CloseStatusCode, string) method to close the connection.

    - -

    If you would like to close the connection asynchronously, you should use the WebSocket.CloseAsync method.

    - -

    -WebSocket Server

    - -
    using System;
    -using WebSocketSharp;
    -using WebSocketSharp.Server;
    -
    -namespace Example
    -{
    -  public class Laputa : WebSocketBehavior
    -  {
    -    protected override void OnMessage (MessageEventArgs e)
    -    {
    -      var msg = e.Data == "BALUS"
    -                ? "I've been balused already..."
    -                : "I'm not available now.";
    -
    -      Send (msg);
    -    }
    -  }
    -
    -  public class Program
    -  {
    -    public static void Main (string[] args)
    -    {
    -      var wssv = new WebSocketServer ("ws://dragonsnest.far");
    -      wssv.AddWebSocketService<Laputa> ("/Laputa");
    -      wssv.Start ();
    -      Console.ReadKey (true);
    -      wssv.Stop ();
    -    }
    -  }
    -}
    - -

    -Step 1

    - -

    Required namespace.

    - -
    using WebSocketSharp.Server;
    - -

    The WebSocketBehavior and WebSocketServer classes exist in the WebSocketSharp.Server namespace.

    - -

    -Step 2

    - -

    Creating the class that inherits the WebSocketBehavior class.

    - -

    For example, if you would like to provide an echo service,

    - -
    using System;
    -using WebSocketSharp;
    -using WebSocketSharp.Server;
    -
    -public class Echo : WebSocketBehavior
    -{
    -  protected override void OnMessage (MessageEventArgs e)
    -  {
    -    Send (e.Data);
    -  }
    -}
    - -

    And if you would like to provide a chat service,

    - -
    using System;
    -using WebSocketSharp;
    -using WebSocketSharp.Server;
    -
    -public class Chat : WebSocketBehavior
    -{
    -  private string _suffix;
    -
    -  public Chat ()
    -    : this (null)
    -  {
    -  }
    -
    -  public Chat (string suffix)
    -  {
    -    _suffix = suffix ?? String.Empty;
    -  }
    -
    -  protected override void OnMessage (MessageEventArgs e)
    -  {
    -    Sessions.Broadcast (e.Data + _suffix);
    -  }
    -}
    - -

    You can define the behavior of any WebSocket service by creating the class that inherits the WebSocketBehavior class.

    - -

    If you override the WebSocketBehavior.OnMessage (MessageEventArgs) method, it will be called when the WebSocket used in a session in the service receives a message.

    - -

    And if you override the WebSocketBehavior.OnOpen (), WebSocketBehavior.OnError (ErrorEventArgs), and WebSocketBehavior.OnClose (CloseEventArgs) methods, each of them will be called when each of the WebSocket events (OnOpen, OnError, and OnClose) occurs.

    - -

    The WebSocketBehavior.Send method can send data to the client on a session in the service.

    - -

    If you would like to get the sessions in the service, you should access the WebSocketBehavior.Sessions property (returns a WebSocketSharp.Server.WebSocketSessionManager).

    - -

    The WebSocketBehavior.Sessions.Broadcast method can send data to every client in the service.

    - -

    -Step 3

    - -

    Creating a new instance of the WebSocketServer class.

    - -
    var wssv = new WebSocketServer (4649);
    -wssv.AddWebSocketService<Echo> ("/Echo");
    -wssv.AddWebSocketService<Chat> ("/Chat");
    -wssv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));
    - -

    You can add any WebSocket service to your WebSocketServer with the specified behavior and path to the service, by using the WebSocketServer.AddWebSocketService<TBehaviorWithNew> (string) or WebSocketServer.AddWebSocketService<TBehavior> (string, Func<TBehavior>) method.

    - -

    The type of TBehaviorWithNew must inherit the WebSocketBehavior class, and must have a public parameterless constructor.

    - -

    And also the type of TBehavior must inherit the WebSocketBehavior class.

    - -

    So you can use the classes created in Step 2 to add the service.

    - -

    If you create a instance of the WebSocketServer class without a port number, the WebSocketServer class set the port number to 80 automatically. So it's necessary to run with root permission.

    - -
    $ sudo mono example2.exe
    -
    - -

    -Step 4

    - -

    Starting the WebSocket server.

    - -
    wssv.Start ();
    - -

    -Step 5

    - -

    Stopping the WebSocket server.

    - -
    wssv.Stop (code, reason);
    - -

    The WebSocketServer.Stop method is overloaded.

    - -

    You can use the WebSocketServer.Stop (), WebSocketServer.Stop (ushort, string), or WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string) method to stop the server.

    - -

    -HTTP Server with the WebSocket

    - -

    I have modified the System.Net.HttpListener, System.Net.HttpListenerContext, and some other classes from Mono to create an HTTP server that allows to accept the WebSocket handshake requests.

    - -

    So websocket-sharp provides the WebSocketSharp.Server.HttpServer class.

    - -

    You can add any WebSocket service to your HttpServer with the specified behavior and path to the service, by using the HttpServer.AddWebSocketService<TBehaviorWithNew> (string) or HttpServer.AddWebSocketService<TBehavior> (string, Func<TBehavior>) method.

    - -
    var httpsv = new HttpServer (4649);
    -httpsv.AddWebSocketService<Echo> ("/Echo");
    -httpsv.AddWebSocketService<Chat> ("/Chat");
    -httpsv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));
    - -

    For more information, would you see Example3?

    - -

    -WebSocket Extensions

    - -

    -Per-message Compression

    - -

    websocket-sharp supports the Per-message Compression extension (but doesn't support this extension with the context take over).

    - -

    As a WebSocket client, if you would like to enable this extension, you should set such as the following.

    - -
    ws.Compression = CompressionMethod.Deflate;
    - -

    And then your client will send the following header in the handshake request to the server.

    - -
    Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover
    -
    - -

    If the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.

    - -

    -Ignoring the extensions

    - -

    As a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the WebSocketBehavior.IgnoreExtensions property to true in your WebSocketBehavior constructor or initializing it, such as the following.

    - -
    wssv.AddWebSocketService<Chat> (
    -  "/Chat",
    -  () =>
    -    new Chat () {
    -      // To ignore the extensions requested from a client.
    -      IgnoreExtensions = true
    -    }
    -);
    - -

    If it's set to true, the service will not return the Sec-WebSocket-Extensions header in its handshake response.

    - -

    I think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.

    - -

    -Secure Connection

    - -

    websocket-sharp supports the Secure Connection with SSL/TLS.

    - -

    As a WebSocket Client, you should create a new instance of the WebSocket class with the wss scheme WebSocket URL.

    - -
    using (var ws = new WebSocket ("wss://example.com")) {
    -  ...
    -}
    - -

    And if you would like to use the custom validation for the server certificate, you should set the WebSocket.SslConfiguration.ServerCertificateValidationCallback property.

    - -
    ws.SslConfiguration.ServerCertificateValidationCallback =
    -  (sender, certificate, chain, sslPolicyErrors) => {
    -    // Do something to validate the server certificate.
    -    ...
    -
    -    return true; // If the server certificate is valid.
    -  };
    - -

    If you set this property to nothing, the validation does nothing with the server certificate, and returns true.

    - -

    As a WebSocket Server, you should create a new instance of the WebSocketServer or HttpServer class with some settings for secure connection, such as the following.

    - -
    var wssv = new WebSocketServer (5963, true);
    -wssv.SslConfiguration.ServerCertificate =
    -  new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");
    - -

    -HTTP Authentication

    - -

    websocket-sharp supports the HTTP Authentication (Basic/Digest).

    - -

    As a WebSocket Client, you should set a pair of user name and password for the HTTP authentication, by using the WebSocket.SetCredentials (string, string, bool) method before connecting.

    - -
    ws.SetCredentials ("nobita", "password", preAuth);
    - -

    If preAuth is true, the WebSocket sends the Basic authentication credentials with the first handshake request to the server.

    - -

    Or if preAuth is false, the WebSocket sends either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication credentials with the second handshake request to the server.

    - -

    As a WebSocket Server, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.

    - -
    wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
    -wssv.Realm = "WebSocket Test";
    -wssv.UserCredentialsFinder = id => {
    -    var name = id.Name;
    -
    -    // Return user name, password, and roles.
    -    return name == "nobita"
    -           ? new NetworkCredential (name, "password", "gunfighter")
    -           : null; // If the user credentials aren't found.
    -  };
    - -

    If you would like to provide the Digest authentication, you should set such as the following.

    - -
    wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;
    - -

    -Query String, Origin header and Cookies

    - -

    As a WebSocket Client, if you would like to send the Query String with the handshake request to the server, you should create a new instance of the WebSocket class with the WebSocket URL that includes the Query string parameters.

    - -
    using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
    -  ...
    -}
    - -

    And if you would like to send the Origin header with the handshake request to the server, you should set the WebSocket.Origin property to an allowable value as the Origin header before connecting, such as the following.

    - -
    ws.Origin = "http://example.com";
    - -

    And also if you would like to send the Cookies with the handshake request to the server, you should set any cookie by using the WebSocket.SetCookie (WebSocketSharp.Net.Cookie) method before connecting, such as the following.

    - -
    ws.SetCookie (new Cookie ("name", "nobita"));
    - -

    As a WebSocket Server, if you would like to get the Query String included in a handshake request, you should access the WebSocketBehavior.Context.QueryString property, such as the following.

    - -
    public class Chat : WebSocketBehavior
    -{
    -  private string _name;
    -  ...
    -
    -  protected override void OnOpen ()
    -  {
    -    _name = Context.QueryString["name"];
    -  }
    -
    -  ...
    -}
    - -

    And if you would like to validate the Origin header, Cookies, or both included in a handshake request, you should set each validation with your WebSocketBehavior, for example, by using the AddWebSocketService<TBehavior> (string, Func<TBehavior>) method with initializing, such as the following.

    - -
    wssv.AddWebSocketService<Chat> (
    -  "/Chat",
    -  () =>
    -    new Chat () {
    -      OriginValidator = val => {
    -          // Check the value of the Origin header, and return true if valid.
    -          Uri origin;
    -          return !val.IsNullOrEmpty ()
    -                 && Uri.TryCreate (val, UriKind.Absolute, out origin)
    -                 && origin.Host == "example.com";
    -        },
    -      CookiesValidator = (req, res) => {
    -          // Check the cookies in 'req', and set the cookies to send to
    -          // the client with 'res' if necessary.
    -          foreach (Cookie cookie in req) {
    -            cookie.Expired = true;
    -            res.Add (cookie);
    -          }
    -
    -          return true; // If valid.
    -        }
    -    }
    -);
    - -

    And also if you would like to get each value of the Origin header and cookies, you should access each of the WebSocketBehavior.Context.Origin and WebSocketBehavior.Context.CookieCollection properties.

    - -

    -Connecting through the HTTP Proxy server

    - -

    websocket-sharp supports to connect through the HTTP Proxy server.

    - -

    If you would like to connect to a WebSocket server through the HTTP proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the WebSocket.SetProxy (string, string, string) method before connecting.

    - -
    var ws = new WebSocket ("ws://example.com");
    -ws.SetProxy ("http://localhost:3128", "nobita", "password");
    - -

    I have tested this with Squid. It's necessary to disable the following configuration option in squid.conf (e.g. /etc/squid/squid.conf).

    - -
    # Deny CONNECT to other than SSL ports
    -#http_access deny CONNECT !SSL_ports
    -
    - -

    -Logging

    - -

    The WebSocket class has the own logging function.

    - -

    You can use it with the WebSocket.Log property (returns a WebSocketSharp.Logger).

    - -

    So if you would like to change the current logging level (WebSocketSharp.LogLevel.Error as the default), you should set the WebSocket.Log.Level property to any of the LogLevel enum values.

    - -
    ws.Log.Level = LogLevel.Debug;
    - -

    The above means a log with lower than LogLevel.Debug cannot be outputted.

    - -

    And if you would like to output a log, you should use any of the output methods. The following outputs a log with LogLevel.Debug.

    - -
    ws.Log.Debug ("This is a debug message.");
    - -

    The WebSocketServer and HttpServer classes have the same logging function.

    - -

    -Examples

    - -

    Examples using websocket-sharp.

    - -

    -Example

    - -

    Example connects to the Echo server with the WebSocket.

    - -

    -Example2

    - -

    Example2 starts a WebSocket server.

    - -

    -Example3

    - -

    Example3 starts an HTTP server that allows to accept the WebSocket handshake requests.

    - -

    Would you access to http://localhost:4649 to do WebSocket Echo Test with your web browser while Example3 is running?

    - -

    -Supported WebSocket Specifications

    - -

    websocket-sharp supports RFC 6455, and it's based on the following WebSocket references:

    - - - -

    Thanks for translating to japanese.

    - - - -

    -License

    - -

    websocket-sharp is provided under The MIT License.

    - - - -
    - - - - - - diff --git a/index.md b/index.md new file mode 100644 index 000000000..ac0ef186b --- /dev/null +++ b/index.md @@ -0,0 +1,686 @@ +## Welcome to websocket-sharp! ## + +**websocket-sharp** supports: + +- **[RFC 6455](#supported-websocket-specifications)** +- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)** +- **[Per-message Compression](#per-message-compression)** extension +- **[Secure Connection](#secure-connection)** +- **[HTTP Authentication](#http-authentication)** +- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)** +- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)** +- .NET Framework **3.5** or later (includes compatible environment such as **[Mono]**) + +## Build ## + +websocket-sharp is built as a single assembly, **websocket-sharp.dll**. + +websocket-sharp is developed with **[MonoDevelop]**. So a simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop. + +## Install ## + +### Self Build ### + +You should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project. + +If you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**. + +### NuGet Gallery ### + +websocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version. + +- **[NuGet Gallery: websocket-sharp]** + +You can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**. + + PM> Install-Package WebSocketSharp -Pre + +### Unity Asset Store ### + +websocket-sharp is available on the **Unity Asset Store**. + +- **[WebSocket-Sharp for Unity]** + +It works with **Unity Free**, but there are some limitations: + +- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player) +- **[WebGL Networking]** (Not available in WebGL) +- **Incompatible platform** (Not available for such UWP) +- **Limited support for the System.IO.Compression** (The compression extension isn't available on Windows) +- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5) +- **.NET API 2.0 compatibility level for iOS/Android** + +**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i have added them in that asset package). + +And it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!** + +## Usage ## + +### WebSocket Client ### + +```csharp +using System; +using WebSocketSharp; + +namespace Example +{ + public class Program + { + public static void Main (string[] args) + { + using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) { + ws.OnMessage += (sender, e) => + Console.WriteLine ("Laputa says: " + e.Data); + + ws.Connect (); + ws.Send ("BALUS"); + Console.ReadKey (true); + } + } + } +} +``` + +#### Step 1 #### + +Required namespace. + +```csharp +using WebSocketSharp; +``` + +The `WebSocket` class exists in the `WebSocketSharp` namespace. + +#### Step 2 #### + +Creating a new instance of the `WebSocket` class with the WebSocket URL to connect. + +```csharp +using (var ws = new WebSocket ("ws://example.com")) { + ... +} +``` + +The `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block. + +#### Step 3 #### + +Setting the `WebSocket` events. + +##### WebSocket.OnOpen Event ##### + +A `WebSocket.OnOpen` event occurs when the WebSocket connection has been established. + +```csharp +ws.OnOpen += (sender, e) => { + ... + }; +``` + +`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it. + +##### WebSocket.OnMessage Event ##### + +A `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message. + +```csharp +ws.OnMessage += (sender, e) => { + ... + }; +``` + +`e` has passed as a `WebSocketSharp.MessageEventArgs`. + +If you would like to get the message data, you should access `e.Data` or `e.RawData` property. + +And you can determine which property you should access by checking `e.IsText` or `e.IsBinary` property. + +If `e.IsText` is `true`, you should access `e.Data` that returns a `string` (represents a **text** message). + +Or if `e.IsBinary` is `true`, you should access `e.RawData` that returns a `byte[]` (represents a **binary** message). + +```csharp +if (e.IsText) { + // Do something with e.Data. + ... + + return; +} + +if (e.IsBinary) { + // Do something with e.RawData. + ... + + return; +} +``` + +And if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following. + +```csharp +ws.EmitOnPing = true; +ws.OnMessage += (sender, e) => { + if (e.IsPing) { + // Do something to notify that a ping has been received. + ... + + return; + } + }; +``` + +##### WebSocket.OnError Event ##### + +A `WebSocket.OnError` event occurs when the `WebSocket` gets an error. + +```csharp +ws.OnError += (sender, e) => { + ... + }; +``` + +`e` has passed as a `WebSocketSharp.ErrorEventArgs`. + +`e.Message` property returns a `string` that represents the error message. + +If the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error. + +##### WebSocket.OnClose Event ##### + +A `WebSocket.OnClose` event occurs when the WebSocket connection has been closed. + +```csharp +ws.OnClose += (sender, e) => { + ... + }; +``` + +`e` has passed as a `WebSocketSharp.CloseEventArgs`. + +`e.Code` property returns a `ushort` that represents the status code for the close, and `e.Reason` property returns a `string` that represents the reason for the close. + +#### Step 4 #### + +Connecting to the WebSocket server. + +```csharp +ws.Connect (); +``` + +If you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method. + +#### Step 5 #### + +Sending data to the WebSocket server. + +```csharp +ws.Send (data); +``` + +The `WebSocket.Send` method is overloaded. + +You can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data. + +If you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method. + +```csharp +ws.SendAsync (data, completed); +``` + +And also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate. + +#### Step 6 #### + +Closing the WebSocket connection. + +```csharp +ws.Close (code, reason); +``` + +If you would like to close the connection explicitly, you should use the `WebSocket.Close` method. + +The `WebSocket.Close` method is overloaded. + +You can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection. + +If you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method. + +### WebSocket Server ### + +```csharp +using System; +using WebSocketSharp; +using WebSocketSharp.Server; + +namespace Example +{ + public class Laputa : WebSocketBehavior + { + protected override void OnMessage (MessageEventArgs e) + { + var msg = e.Data == "BALUS" + ? "I've been balused already..." + : "I'm not available now."; + + Send (msg); + } + } + + public class Program + { + public static void Main (string[] args) + { + var wssv = new WebSocketServer ("ws://dragonsnest.far"); + wssv.AddWebSocketService ("/Laputa"); + wssv.Start (); + Console.ReadKey (true); + wssv.Stop (); + } + } +} +``` + +#### Step 1 #### + +Required namespace. + +```csharp +using WebSocketSharp.Server; +``` + +The `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace. + +#### Step 2 #### + +Creating the class that inherits the `WebSocketBehavior` class. + +For example, if you would like to provide an echo service, + +```csharp +using System; +using WebSocketSharp; +using WebSocketSharp.Server; + +public class Echo : WebSocketBehavior +{ + protected override void OnMessage (MessageEventArgs e) + { + Send (e.Data); + } +} +``` + +And if you would like to provide a chat service, + +```csharp +using System; +using WebSocketSharp; +using WebSocketSharp.Server; + +public class Chat : WebSocketBehavior +{ + private string _suffix; + + public Chat () + : this (null) + { + } + + public Chat (string suffix) + { + _suffix = suffix ?? String.Empty; + } + + protected override void OnMessage (MessageEventArgs e) + { + Sessions.Broadcast (e.Data + _suffix); + } +} +``` + +You can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class. + +If you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it will be called when the `WebSocket` used in a session in the service receives a message. + +And if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them will be called when each of the `WebSocket` events (`OnOpen`, `OnError`, and `OnClose`) occurs. + +The `WebSocketBehavior.Send` method can send data to the client on a session in the service. + +If you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`). + +The `WebSocketBehavior.Sessions.Broadcast` method can send data to every client in the service. + +#### Step 3 #### + +Creating a new instance of the `WebSocketServer` class. + +```csharp +var wssv = new WebSocketServer (4649); +wssv.AddWebSocketService ("/Echo"); +wssv.AddWebSocketService ("/Chat"); +wssv.AddWebSocketService ("/ChatWithNyan", () => new Chat (" Nyan!")); +``` + +You can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method. + +The type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor. + +And also the type of `TBehavior` must inherit the `WebSocketBehavior` class. + +So you can use the classes created in **Step 2** to add the service. + +If you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission. + + $ sudo mono example2.exe + +#### Step 4 #### + +Starting the WebSocket server. + +```csharp +wssv.Start (); +``` + +#### Step 5 #### + +Stopping the WebSocket server. + +```csharp +wssv.Stop (code, reason); +``` + +The `WebSocketServer.Stop` method is overloaded. + +You can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server. + +### HTTP Server with the WebSocket ### + +I have modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes from **[Mono]** to create an HTTP server that allows to accept the WebSocket handshake requests. + +So websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class. + +You can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method. + +```csharp +var httpsv = new HttpServer (4649); +httpsv.AddWebSocketService ("/Echo"); +httpsv.AddWebSocketService ("/Chat"); +httpsv.AddWebSocketService ("/ChatWithNyan", () => new Chat (" Nyan!")); +``` + +For more information, would you see **[Example3]**? + +### WebSocket Extensions ### + +#### Per-message Compression #### + +websocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]). + +As a WebSocket client, if you would like to enable this extension, you should set such as the following. + +```csharp +ws.Compression = CompressionMethod.Deflate; +``` + +And then your client will send the following header in the handshake request to the server. + + Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover + +If the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available. + +#### Ignoring the extensions #### + +As a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following. + +```csharp +wssv.AddWebSocketService ( + "/Chat", + () => + new Chat () { + // To ignore the extensions requested from a client. + IgnoreExtensions = true + } +); +``` + +If it's set to `true`, the service will not return the **Sec-WebSocket-Extensions** header in its handshake response. + +I think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error. + +### Secure Connection ### + +websocket-sharp supports the **Secure Connection** with **SSL/TLS**. + +As a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL. + +```csharp +using (var ws = new WebSocket ("wss://example.com")) { + ... +} +``` + +And if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property. + +```csharp +ws.SslConfiguration.ServerCertificateValidationCallback = + (sender, certificate, chain, sslPolicyErrors) => { + // Do something to validate the server certificate. + ... + + return true; // If the server certificate is valid. + }; +``` + +If you set this property to nothing, the validation does nothing with the server certificate, and returns `true`. + +As a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following. + +```csharp +var wssv = new WebSocketServer (5963, true); +wssv.SslConfiguration.ServerCertificate = + new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx"); +``` + +### HTTP Authentication ### + +websocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**. + +As a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting. + +```csharp +ws.SetCredentials ("nobita", "password", preAuth); +``` + +If `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first handshake request to the server. + +Or if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication credentials with the second handshake request to the server. + +As a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following. + +```csharp +wssv.AuthenticationSchemes = AuthenticationSchemes.Basic; +wssv.Realm = "WebSocket Test"; +wssv.UserCredentialsFinder = id => { + var name = id.Name; + + // Return user name, password, and roles. + return name == "nobita" + ? new NetworkCredential (name, "password", "gunfighter") + : null; // If the user credentials aren't found. + }; +``` + +If you would like to provide the Digest authentication, you should set such as the following. + +```csharp +wssv.AuthenticationSchemes = AuthenticationSchemes.Digest; +``` + +### Query String, Origin header and Cookies ### + +As a **WebSocket Client**, if you would like to send the **Query String** with the handshake request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters. + +```csharp +using (var ws = new WebSocket ("ws://example.com/?name=nobita")) { + ... +} +``` + +And if you would like to send the **Origin** header with the handshake request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin] header before connecting, such as the following. + +```csharp +ws.Origin = "http://example.com"; +``` + +And also if you would like to send the **Cookies** with the handshake request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following. + +```csharp +ws.SetCookie (new Cookie ("name", "nobita")); +``` + +As a **WebSocket Server**, if you would like to get the **Query String** included in a handshake request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following. + +```csharp +public class Chat : WebSocketBehavior +{ + private string _name; + ... + + protected override void OnOpen () + { + _name = Context.QueryString["name"]; + } + + ... +} +``` + +And if you would like to validate the **Origin** header, **Cookies**, or both included in a handshake request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following. + +```csharp +wssv.AddWebSocketService ( + "/Chat", + () => + new Chat () { + OriginValidator = val => { + // Check the value of the Origin header, and return true if valid. + Uri origin; + return !val.IsNullOrEmpty () + && Uri.TryCreate (val, UriKind.Absolute, out origin) + && origin.Host == "example.com"; + }, + CookiesValidator = (req, res) => { + // Check the cookies in 'req', and set the cookies to send to + // the client with 'res' if necessary. + foreach (Cookie cookie in req) { + cookie.Expired = true; + res.Add (cookie); + } + + return true; // If valid. + } + } +); +``` + +And also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties. + +### Connecting through the HTTP Proxy server ### + +websocket-sharp supports to connect through the **HTTP Proxy** server. + +If you would like to connect to a WebSocket server through the HTTP proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting. + +```csharp +var ws = new WebSocket ("ws://example.com"); +ws.SetProxy ("http://localhost:3128", "nobita", "password"); +``` + +I have tested this with **[Squid]**. It's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`). + +``` +# Deny CONNECT to other than SSL ports +#http_access deny CONNECT !SSL_ports +``` + +### Logging ### + +The `WebSocket` class has the own logging function. + +You can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`). + +So if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values. + +```csharp +ws.Log.Level = LogLevel.Debug; +``` + +The above means a log with lower than `LogLevel.Debug` cannot be outputted. + +And if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`. + +```csharp +ws.Log.Debug ("This is a debug message."); +``` + +The `WebSocketServer` and `HttpServer` classes have the same logging function. + +## Examples ## + +Examples using websocket-sharp. + +### Example ### + +**[Example]** connects to the **[Echo server]** with the WebSocket. + +### Example2 ### + +**[Example2]** starts a WebSocket server. + +### Example3 ### + +**[Example3]** starts an HTTP server that allows to accept the WebSocket handshake requests. + +Would you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running? + +## Supported WebSocket Specifications ## + +websocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references: + +- **[The WebSocket Protocol][rfc6455]** +- **[The WebSocket API][api]** +- **[Compression Extensions for WebSocket][compression]** + +Thanks for translating to japanese. + +- **[The WebSocket Protocol 日本語訳][rfc6455_ja]** +- **[The WebSocket API 日本語訳][api_ja]** + +## License ## + +websocket-sharp is provided under **[The MIT License]**. + + +[Echo server]: http://www.websocket.org/echo.html +[Example]: https://github.com/sta/websocket-sharp/tree/master/Example +[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2 +[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3 +[Mono]: http://www.mono-project.com +[MonoDevelop]: http://monodevelop.com +[NuGet Gallery]: http://www.nuget.org +[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp +[Origin]: http://tools.ietf.org/html/rfc6454#section-7 +[Query]: http://tools.ietf.org/html/rfc3986#section-3.4 +[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html +[Squid]: http://www.squid-cache.org +[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt +[Unity]: http://unity3d.com +[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html +[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity +[api]: http://www.w3.org/TR/websockets +[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html +[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19 +[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1 +[rfc2617]: http://tools.ietf.org/html/rfc2617 +[rfc6455]: http://tools.ietf.org/html/rfc6455 +[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html diff --git a/params.json b/params.json deleted file mode 100644 index 344d6ca80..000000000 --- a/params.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "websocket-sharp", - "tagline": "A C# implementation of the WebSocket protocol client and server", - "body": "## Welcome to websocket-sharp! ##\r\n\r\n**websocket-sharp** supports:\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- **[HTTP Authentication](#http-authentication)**\r\n- **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**\r\n- **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**\r\n- .NET Framework **3.5** or later (includes compatible environment such as **[Mono]**)\r\n\r\n## Build ##\r\n\r\nwebsocket-sharp is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So a simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.\r\n\r\nIf you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\nwebsocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\nwebsocket-sharp is available on the **Unity Asset Store**.\r\n\r\n- **[WebSocket-Sharp for Unity]**\r\n\r\nIt works with **Unity Free**, but there are some limitations:\r\n\r\n- **[Security Sandbox of the Webplayer]** (The server isn't available in Web Player)\r\n- **[WebGL Networking]** (Not available in WebGL)\r\n- **Incompatible platform** (Not available for such UWP)\r\n- **Limited support for the System.IO.Compression** (The compression extension isn't available on Windows)\r\n- **.NET Socket Support for iOS/Android** (It requires iOS/Android Pro if your Unity is earlier than Unity 5)\r\n- **.NET API 2.0 compatibility level for iOS/Android**\r\n\r\n**.NET API 2.0 compatibility level for iOS/Android** may require to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i have added them in that asset package).\r\n\r\nAnd it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\")) {\r\n ws.OnMessage += (sender, e) =>\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating a new instance of the `WebSocket` class with the WebSocket URL to connect.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```csharp\r\nws.OnOpen += (sender, e) => {\r\n ...\r\n };\r\n```\r\n\r\n`e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.\r\n\r\n```csharp\r\nws.OnMessage += (sender, e) => {\r\n ...\r\n };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.MessageEventArgs`.\r\n\r\nIf you would like to get the message data, you should access `e.Data` or `e.RawData` property.\r\n\r\nAnd you can determine which property you should access by checking `e.IsText` or `e.IsBinary` property.\r\n\r\nIf `e.IsText` is `true`, you should access `e.Data` that returns a `string` (represents a **text** message).\r\n\r\nOr if `e.IsBinary` is `true`, you should access `e.RawData` that returns a `byte[]` (represents a **binary** message).\r\n\r\n```csharp\r\nif (e.IsText) {\r\n // Do something with e.Data.\r\n ...\r\n\r\n return;\r\n}\r\n\r\nif (e.IsBinary) {\r\n // Do something with e.RawData.\r\n ...\r\n\r\n return;\r\n}\r\n```\r\n\r\nAnd if you would like to notify that a **ping** has been received, via this event, you should set the `WebSocket.EmitOnPing` property to `true`, such as the following.\r\n\r\n```csharp\r\nws.EmitOnPing = true;\r\nws.OnMessage += (sender, e) => {\r\n if (e.IsPing) {\r\n // Do something to notify that a ping has been received.\r\n ...\r\n\r\n return;\r\n }\r\n };\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```csharp\r\nws.OnError += (sender, e) => {\r\n ...\r\n };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.ErrorEventArgs`.\r\n\r\n`e.Message` property returns a `string` that represents the error message.\r\n\r\nIf the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```csharp\r\nws.OnClose += (sender, e) => {\r\n ...\r\n };\r\n```\r\n\r\n`e` has passed as a `WebSocketSharp.CloseEventArgs`.\r\n\r\n`e.Code` property returns a `ushort` that represents the status code for the close, and `e.Reason` property returns a `string` that represents the reason for the close.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```csharp\r\nws.Connect ();\r\n```\r\n\r\nIf you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.\r\n\r\n#### Step 5 ####\r\n\r\nSending data to the WebSocket server.\r\n\r\n```csharp\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nYou can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.\r\n\r\nIf you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.\r\n\r\n```csharp\r\nws.SendAsync (data, completed);\r\n```\r\n\r\nAnd also if you would like to do something when the send is complete, you should set `completed` to any `Action` delegate.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```csharp\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you would like to close the connection explicitly, you should use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nYou can use the `WebSocket.Close ()`, `WebSocket.Close (ushort)`, `WebSocket.Close (WebSocketSharp.CloseStatusCode)`, `WebSocket.Close (ushort, string)`, or `WebSocket.Close (WebSocketSharp.CloseStatusCode, string)` method to close the connection.\r\n\r\nIf you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.\r\n\r\n### WebSocket Server ###\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketBehavior\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string[] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```csharp\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketBehavior` class.\r\n\r\nFor example, if you would like to provide an echo service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketBehavior\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you would like to provide a chat service,\r\n\r\n```csharp\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (null)\r\n {\r\n }\r\n\r\n public Chat (string suffix)\r\n {\r\n _suffix = suffix ?? String.Empty;\r\n }\r\n\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Sessions.Broadcast (e.Data + _suffix);\r\n }\r\n}\r\n```\r\n\r\nYou can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.\r\n\r\nIf you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it will be called when the `WebSocket` used in a session in the service receives a message.\r\n\r\nAnd if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them will be called when each of the `WebSocket` events (`OnOpen`, `OnError`, and `OnClose`) occurs.\r\n\r\nThe `WebSocketBehavior.Send` method can send data to the client on a session in the service.\r\n\r\nIf you would like to get the sessions in the service, you should access the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).\r\n\r\nThe `WebSocketBehavior.Sessions.Broadcast` method can send data to every client in the service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating a new instance of the `WebSocketServer` class.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService (\"/Echo\");\r\nwssv.AddWebSocketService (\"/Chat\");\r\nwssv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nYou can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService (string)` or `WebSocketServer.AddWebSocketService (string, Func)` method.\r\n\r\nThe type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.\r\n\r\nAnd also the type of `TBehavior` must inherit the `WebSocketBehavior` class.\r\n\r\nSo you can use the classes created in **Step 2** to add the service.\r\n\r\nIf you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the WebSocket server.\r\n\r\n```csharp\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the WebSocket server.\r\n\r\n```csharp\r\nwssv.Stop (code, reason);\r\n```\r\n\r\nThe `WebSocketServer.Stop` method is overloaded.\r\n\r\nYou can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI have modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext`, and some other classes from **[Mono]** to create an HTTP server that allows to accept the WebSocket handshake requests.\r\n\r\nSo websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.\r\n\r\nYou can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService (string)` or `HttpServer.AddWebSocketService (string, Func)` method.\r\n\r\n```csharp\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService (\"/Echo\");\r\nhttpsv.AddWebSocketService (\"/Chat\");\r\nhttpsv.AddWebSocketService (\"/ChatWithNyan\", () => new Chat (\" Nyan!\"));\r\n```\r\n\r\nFor more information, would you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\nwebsocket-sharp supports the **[Per-message Compression][compression]** extension (but doesn't support this extension with the [context take over]).\r\n\r\nAs a WebSocket client, if you would like to enable this extension, you should set such as the following.\r\n\r\n```csharp\r\nws.Compression = CompressionMethod.Deflate;\r\n```\r\n\r\nAnd then your client will send the following header in the handshake request to the server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n\r\nIf the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.\r\n\r\n#### Ignoring the extensions ####\r\n\r\nAs a WebSocket server, if you would like to ignore the extensions requested from a client, you should set the `WebSocketBehavior.IgnoreExtensions` property to `true` in your `WebSocketBehavior` constructor or initializing it, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () =>\r\n new Chat () {\r\n // To ignore the extensions requested from a client.\r\n IgnoreExtensions = true\r\n }\r\n);\r\n```\r\n\r\nIf it's set to `true`, the service will not return the **Sec-WebSocket-Extensions** header in its handshake response.\r\n\r\nI think this is useful when you get something error in connecting the server and exclude the extensions as a cause of the error.\r\n\r\n### Secure Connection ###\r\n\r\nwebsocket-sharp supports the **Secure Connection** with **SSL/TLS**.\r\n\r\nAs a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"wss://example.com\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.\r\n\r\n```csharp\r\nws.SslConfiguration.ServerCertificateValidationCallback =\r\n (sender, certificate, chain, sslPolicyErrors) => {\r\n // Do something to validate the server certificate.\r\n ...\r\n\r\n return true; // If the server certificate is valid.\r\n };\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.\r\n\r\nAs a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.\r\n\r\n```csharp\r\nvar wssv = new WebSocketServer (5963, true);\r\nwssv.SslConfiguration.ServerCertificate =\r\n new X509Certificate2 (\"/path/to/cert.pfx\", \"password for cert.pfx\");\r\n```\r\n\r\n### HTTP Authentication ###\r\n\r\nwebsocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.\r\n\r\nAs a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.\r\n\r\n```csharp\r\nws.SetCredentials (\"nobita\", \"password\", preAuth);\r\n```\r\n\r\nIf `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first handshake request to the server.\r\n\r\nOr if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first handshake request) authentication credentials with the second handshake request to the server.\r\n\r\nAs a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Basic;\r\nwssv.Realm = \"WebSocket Test\";\r\nwssv.UserCredentialsFinder = id => {\r\n var name = id.Name;\r\n\r\n // Return user name, password, and roles.\r\n return name == \"nobita\"\r\n ? new NetworkCredential (name, \"password\", \"gunfighter\")\r\n : null; // If the user credentials aren't found.\r\n };\r\n```\r\n\r\nIf you would like to provide the Digest authentication, you should set such as the following.\r\n\r\n```csharp\r\nwssv.AuthenticationSchemes = AuthenticationSchemes.Digest;\r\n```\r\n\r\n### Query String, Origin header and Cookies ###\r\n\r\nAs a **WebSocket Client**, if you would like to send the **Query String** with the handshake request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.\r\n\r\n```csharp\r\nusing (var ws = new WebSocket (\"ws://example.com/?name=nobita\")) {\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to send the **Origin** header with the handshake request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin] header before connecting, such as the following.\r\n\r\n```csharp\r\nws.Origin = \"http://example.com\";\r\n```\r\n\r\nAnd also if you would like to send the **Cookies** with the handshake request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.\r\n\r\n```csharp\r\nws.SetCookie (new Cookie (\"name\", \"nobita\"));\r\n```\r\n\r\nAs a **WebSocket Server**, if you would like to get the **Query String** included in a handshake request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.\r\n\r\n```csharp\r\npublic class Chat : WebSocketBehavior\r\n{\r\n private string _name;\r\n ...\r\n\r\n protected override void OnOpen ()\r\n {\r\n _name = Context.QueryString[\"name\"];\r\n }\r\n\r\n ...\r\n}\r\n```\r\n\r\nAnd if you would like to validate the **Origin** header, **Cookies**, or both included in a handshake request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService (string, Func)` method with initializing, such as the following.\r\n\r\n```csharp\r\nwssv.AddWebSocketService (\r\n \"/Chat\",\r\n () =>\r\n new Chat () {\r\n OriginValidator = val => {\r\n // Check the value of the Origin header, and return true if valid.\r\n Uri origin;\r\n return !val.IsNullOrEmpty ()\r\n && Uri.TryCreate (val, UriKind.Absolute, out origin)\r\n && origin.Host == \"example.com\";\r\n },\r\n CookiesValidator = (req, res) => {\r\n // Check the cookies in 'req', and set the cookies to send to\r\n // the client with 'res' if necessary.\r\n foreach (Cookie cookie in req) {\r\n cookie.Expired = true;\r\n res.Add (cookie);\r\n }\r\n\r\n return true; // If valid.\r\n }\r\n }\r\n);\r\n```\r\n\r\nAnd also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.\r\n\r\n### Connecting through the HTTP Proxy server ###\r\n\r\nwebsocket-sharp supports to connect through the **HTTP Proxy** server.\r\n\r\nIf you would like to connect to a WebSocket server through the HTTP proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.\r\n\r\n```csharp\r\nvar ws = new WebSocket (\"ws://example.com\");\r\nws.SetProxy (\"http://localhost:3128\", \"nobita\", \"password\");\r\n```\r\n\r\nI have tested this with **[Squid]**. It's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).\r\n\r\n```\r\n# Deny CONNECT to other than SSL ports\r\n#http_access deny CONNECT !SSL_ports\r\n```\r\n\r\n### Logging ###\r\n\r\nThe `WebSocket` class has the own logging function.\r\n\r\nYou can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).\r\n\r\nSo if you would like to change the current logging level (`WebSocketSharp.LogLevel.Error` as the default), you should set the `WebSocket.Log.Level` property to any of the `LogLevel` enum values.\r\n\r\n```csharp\r\nws.Log.Level = LogLevel.Debug;\r\n```\r\n\r\nThe above means a log with lower than `LogLevel.Debug` cannot be outputted.\r\n\r\nAnd if you would like to output a log, you should use any of the output methods. The following outputs a log with `LogLevel.Debug`.\r\n\r\n```csharp\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes have the same logging function.\r\n\r\n## Examples ##\r\n\r\nExamples using websocket-sharp.\r\n\r\n### Example ###\r\n\r\n**[Example]** connects to the **[Echo server]** with the WebSocket.\r\n\r\n### Example2 ###\r\n\r\n**[Example2]** starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n**[Example3]** starts an HTTP server that allows to accept the WebSocket handshake requests.\r\n\r\nWould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser while Example3 is running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\nwebsocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\nwebsocket-sharp is provided under **[The MIT License]**.\r\n\r\n\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[Origin]: http://tools.ietf.org/html/rfc6454#section-7\r\n[Query]: http://tools.ietf.org/html/rfc3986#section-3.4\r\n[Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html\r\n[Squid]: http://www.squid-cache.org\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[WebGL Networking]: http://docs.unity3d.com/Manual/webgl-networking.html\r\n[WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19\r\n[context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1\r\n[rfc2617]: http://tools.ietf.org/html/rfc2617\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n", - "google": "UA-9752433-2", - "note": "Don't delete this file! It's used internally to help with page regeneration." -} \ No newline at end of file From 4ea821ea55254f75acbaae48e3956456411ae379 Mon Sep 17 00:00:00 2001 From: sta Date: Sat, 31 Dec 2016 16:48:27 +0900 Subject: [PATCH 27/27] Set theme jekyll-theme-cayman