commit 64ec8cd4f4813644de7a0333326addb14e1a212e Author: sta Date: Fri Nov 15 06:21:00 2013 -0800 Create gh-pages branch via GitHub diff --git a/images/body-bg.jpg b/images/body-bg.jpg new file mode 100644 index 00000000..0e0f861b Binary files /dev/null and b/images/body-bg.jpg differ diff --git a/images/download-button.png b/images/download-button.png new file mode 100644 index 00000000..df3f09a6 Binary files /dev/null and b/images/download-button.png differ diff --git a/images/github-button.png b/images/github-button.png new file mode 100644 index 00000000..efe07f9a Binary files /dev/null and b/images/github-button.png differ diff --git a/images/header-bg.jpg b/images/header-bg.jpg new file mode 100644 index 00000000..960bff75 Binary files /dev/null and b/images/header-bg.jpg differ diff --git a/images/highlight-bg.jpg b/images/highlight-bg.jpg new file mode 100644 index 00000000..4c4a78ef Binary files /dev/null and b/images/highlight-bg.jpg differ diff --git a/images/sidebar-bg.jpg b/images/sidebar-bg.jpg new file mode 100644 index 00000000..42890fe7 Binary files /dev/null and b/images/sidebar-bg.jpg differ diff --git a/index.html b/index.html new file mode 100644 index 00000000..ac3d2ce5 --- /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 00000000..d8135d37 --- /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 00000000..1de32ca0 --- /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 00000000..541695bf --- /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 00000000..c6a6452d --- /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 00000000..7e3b8f0e --- /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) {}