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