+
+
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 @@
+
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.
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 @@
-
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.
+Starting the server.
+Starting the WebSocket server.
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.
-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.
+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.
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 00000000..08716c00
--- /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 9b9fcf5b..898bdd90 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 c6a6452d..1926cfdf 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 00000000..466b9d68
--- /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/';
+ }
+}