You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

669 lines
22 KiB

12 years ago
15 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
15 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
15 years ago
12 years ago
12 years ago
12 years ago
15 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
12 years ago
13 years ago
13 years ago
13 years ago
12 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
12 years ago
13 years ago
12 years ago
13 years ago
13 years ago
12 years ago
13 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
12 years ago
12 years ago
12 years ago
12 years ago
13 years ago
13 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
13 years ago
12 years ago
12 years ago
13 years ago
13 years ago
12 years ago
12 years ago
12 years ago
12 years ago
13 years ago
12 years ago
13 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
12 years ago
13 years ago
12 years ago
12 years ago
13 years ago
13 years ago
12 years ago
13 years ago
13 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. ![Logo](websocket-sharp_logo.png)
  2. ## Welcome to websocket-sharp! ##
  3. **websocket-sharp** supports:
  4. - **[RFC 6455](#supported-websocket-specifications)**
  5. - **[WebSocket Client](#websocket-client)** and **[Server](#websocket-server)**
  6. - **[Per-message Compression](#per-message-compression)** extension
  7. - **[Secure Connection](#secure-connection)**
  8. - **[HTTP Authentication](#http-authentication)**
  9. - **[Query String, Origin header and Cookies](#query-string-origin-header-and-cookies)**
  10. - **[Connecting through the HTTP Proxy server](#connecting-through-the-http-proxy-server)**
  11. - .NET **3.5** or later (includes compatible)
  12. ## Branches ##
  13. - **[master]** for production releases.
  14. - **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.
  15. - **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.
  16. ## Build ##
  17. websocket-sharp is built as a single assembly, **websocket-sharp.dll**.
  18. websocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for **websocket-sharp project** with any of the build configurations (e.g. `Debug`) in MonoDevelop.
  19. ## Install ##
  20. ### Self Build ###
  21. You should add your **websocket-sharp.dll** (e.g. `/path/to/websocket-sharp/bin/Debug/websocket-sharp.dll`) to the library references of your project.
  22. If you would like to use that dll in your **[Unity]** project, you should add it to any folder of your project (e.g. `Assets/Plugins`) in **Unity Editor**.
  23. ### NuGet Gallery ###
  24. websocket-sharp is available on the **[NuGet Gallery]**, as still a **prerelease** version.
  25. - **[NuGet Gallery: websocket-sharp]**
  26. You can add websocket-sharp to your project with the **NuGet Package Manager**, by using the following command in the **Package Manager Console**.
  27. PM> Install-Package WebSocketSharp -Pre
  28. ### Unity Asset Store ###
  29. websocket-sharp is available on the **Unity Asset Store**.
  30. - **[WebSocket-Sharp for Unity]**
  31. It works with **Unity Free**, but there are some limitations:
  32. - **[Security Sandbox of the Webplayer]** (the server doesn't work in the webplayer)
  33. - **[.NET Socket Support for iOS/Android][Unity Licenses Comparison]** (requires iOS/Android Pro)
  34. - **Limited support for the System.IO.Compression** (the compression extension isn't available on Windows)
  35. - **.NET API 2.0 compatibility level for iOS/Android**
  36. Using **.NET API 2.0 compatibility level for iOS/Android** requires to fix lack of some features for later than .NET 2.0, such as the `System.Func<...>` delegates (so i've fixed it in the asset package).
  37. And it's priced at **US$15**. I think your $15 makes this project more better and accelerated, **Thank you!**
  38. ## Usage ##
  39. ### WebSocket Client ###
  40. ```csharp
  41. using System;
  42. using WebSocketSharp;
  43. namespace Example
  44. {
  45. public class Program
  46. {
  47. public static void Main (string[] args)
  48. {
  49. using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) {
  50. ws.OnMessage += (sender, e) =>
  51. Console.WriteLine ("Laputa says: " + e.Data);
  52. ws.Connect ();
  53. ws.Send ("BALUS");
  54. Console.ReadKey (true);
  55. }
  56. }
  57. }
  58. }
  59. ```
  60. #### Step 1 ####
  61. Required namespace.
  62. ```csharp
  63. using WebSocketSharp;
  64. ```
  65. The `WebSocket` class exists in the `WebSocketSharp` namespace.
  66. #### Step 2 ####
  67. Creating a new instance of the `WebSocket` class with the WebSocket URL to connect.
  68. ```csharp
  69. using (var ws = new WebSocket ("ws://example.com")) {
  70. ...
  71. }
  72. ```
  73. The `WebSocket` class inherits the `System.IDisposable` interface, so you can use the `using` statement. And the WebSocket connection will be closed with close status `1001` (going away) when the control leaves the `using` block.
  74. #### Step 3 ####
  75. Setting the `WebSocket` events.
  76. ##### WebSocket.OnOpen Event #####
  77. A `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.
  78. ```csharp
  79. ws.OnOpen += (sender, e) => {
  80. ...
  81. };
  82. ```
  83. `e` has passed as the `System.EventArgs.Empty`, so you don't need to use it.
  84. ##### WebSocket.OnMessage Event #####
  85. A `WebSocket.OnMessage` event occurs when the `WebSocket` receives a message.
  86. ```csharp
  87. ws.OnMessage += (sender, e) => {
  88. ...
  89. };
  90. ```
  91. `e` has passed as a `WebSocketSharp.MessageEventArgs`.
  92. `e.Type` property returns either `WebSocketSharp.Opcode.Text` or `WebSocketSharp.Opcode.Binary` that represents the type of the message. So by checking it, you can determine which item you should use.
  93. If it returns `Opcode.Text`, you should use `e.Data` property that returns a `string` (represents the **Text** message).
  94. Or if it returns `Opcode.Binary`, you should use `e.RawData` property that returns a `byte[]` (represents the **Binary** message).
  95. ```csharp
  96. if (e.Type == Opcode.Text) {
  97. // Do something with e.Data.
  98. ...
  99. return;
  100. }
  101. if (e.Type == Opcode.Binary) {
  102. // Do something with e.RawData.
  103. ...
  104. return;
  105. }
  106. ```
  107. ##### WebSocket.OnError Event #####
  108. A `WebSocket.OnError` event occurs when the `WebSocket` gets an error.
  109. ```csharp
  110. ws.OnError += (sender, e) => {
  111. ...
  112. };
  113. ```
  114. `e` has passed as a `WebSocketSharp.ErrorEventArgs`.
  115. `e.Message` property returns a `string` that represents the error message.
  116. If the error is due to an exception, `e.Exception` property returns a `System.Exception` instance that caused the error.
  117. ##### WebSocket.OnClose Event #####
  118. A `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.
  119. ```csharp
  120. ws.OnClose += (sender, e) => {
  121. ...
  122. };
  123. ```
  124. `e` has passed as a `WebSocketSharp.CloseEventArgs`.
  125. `e.Code` property returns a `ushort` that represents the status code indicating the reason for the close, and `e.Reason` property returns a `string` that represents the reason for the close.
  126. #### Step 4 ####
  127. Connecting to the WebSocket server.
  128. ```csharp
  129. ws.Connect ();
  130. ```
  131. If you would like to connect to the server asynchronously, you should use the `WebSocket.ConnectAsync ()` method.
  132. #### Step 5 ####
  133. Sending data to the WebSocket server.
  134. ```csharp
  135. ws.Send (data);
  136. ```
  137. The `WebSocket.Send` method is overloaded.
  138. You can use the `WebSocket.Send (string)`, `WebSocket.Send (byte[])`, or `WebSocket.Send (System.IO.FileInfo)` method to send the data.
  139. If you would like to send the data asynchronously, you should use the `WebSocket.SendAsync` method.
  140. ```csharp
  141. ws.SendAsync (data, completed);
  142. ```
  143. And also if you would like to do something when the send is complete, you should set `completed` to any `Action<bool>` delegate.
  144. #### Step 6 ####
  145. Closing the WebSocket connection.
  146. ```csharp
  147. ws.Close (code, reason);
  148. ```
  149. If you would like to close the connection explicitly, you should use the `WebSocket.Close` method.
  150. The `WebSocket.Close` method is overloaded.
  151. 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.
  152. If you would like to close the connection asynchronously, you should use the `WebSocket.CloseAsync` method.
  153. ### WebSocket Server ###
  154. ```csharp
  155. using System;
  156. using WebSocketSharp;
  157. using WebSocketSharp.Server;
  158. namespace Example
  159. {
  160. public class Laputa : WebSocketBehavior
  161. {
  162. protected override void OnMessage (MessageEventArgs e)
  163. {
  164. var msg = e.Data == "BALUS"
  165. ? "I've been balused already..."
  166. : "I'm not available now.";
  167. Send (msg);
  168. }
  169. }
  170. public class Program
  171. {
  172. public static void Main (string[] args)
  173. {
  174. var wssv = new WebSocketServer ("ws://dragonsnest.far");
  175. wssv.AddWebSocketService<Laputa> ("/Laputa");
  176. wssv.Start ();
  177. Console.ReadKey (true);
  178. wssv.Stop ();
  179. }
  180. }
  181. }
  182. ```
  183. #### Step 1 ####
  184. Required namespace.
  185. ```csharp
  186. using WebSocketSharp.Server;
  187. ```
  188. The `WebSocketBehavior` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.
  189. #### Step 2 ####
  190. Creating the class that inherits the `WebSocketBehavior` class.
  191. For example, if you would like to provide an echo service,
  192. ```csharp
  193. using System;
  194. using WebSocketSharp;
  195. using WebSocketSharp.Server;
  196. public class Echo : WebSocketBehavior
  197. {
  198. protected override void OnMessage (MessageEventArgs e)
  199. {
  200. Send (e.Data);
  201. }
  202. }
  203. ```
  204. And if you would like to provide a chat service,
  205. ```csharp
  206. using System;
  207. using WebSocketSharp;
  208. using WebSocketSharp.Server;
  209. public class Chat : WebSocketBehavior
  210. {
  211. private string _suffix;
  212. public Chat ()
  213. : this (null)
  214. {
  215. }
  216. public Chat (string suffix)
  217. {
  218. _suffix = suffix ?? String.Empty;
  219. }
  220. protected override void OnMessage (MessageEventArgs e)
  221. {
  222. Sessions.Broadcast (e.Data + _suffix);
  223. }
  224. }
  225. ```
  226. You can define the behavior of any WebSocket service by creating the class that inherits the `WebSocketBehavior` class.
  227. If you override the `WebSocketBehavior.OnMessage (MessageEventArgs)` method, it's called when the `WebSocket` used in a session in the service receives a message.
  228. And if you override the `WebSocketBehavior.OnOpen ()`, `WebSocketBehavior.OnError (ErrorEventArgs)`, and `WebSocketBehavior.OnClose (CloseEventArgs)` methods, each of them is called when each event of the `WebSocket` (the `OnOpen`, `OnError`, and `OnClose` events) occurs.
  229. The `WebSocketBehavior.Send` method sends data to the client on a session in the service.
  230. If you would like to access the sessions in the service, you should use the `WebSocketBehavior.Sessions` property (returns a `WebSocketSharp.Server.WebSocketSessionManager`).
  231. The `WebSocketBehavior.Sessions.Broadcast` method sends data to every client in the service.
  232. #### Step 3 ####
  233. Creating a new instance of the `WebSocketServer` class.
  234. ```csharp
  235. var wssv = new WebSocketServer (4649);
  236. wssv.AddWebSocketService<Echo> ("/Echo");
  237. wssv.AddWebSocketService<Chat> ("/Chat");
  238. wssv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));
  239. ```
  240. You can add any WebSocket service to your `WebSocketServer` with the specified behavior and path to the service, by using the `WebSocketServer.AddWebSocketService<TBehaviorWithNew> (string)` or `WebSocketServer.AddWebSocketService<TBehavior> (string, Func<TBehavior>)` method.
  241. The type of `TBehaviorWithNew` must inherit the `WebSocketBehavior` class, and must have a public parameterless constructor.
  242. And also the type of `TBehavior` must inherit the `WebSocketBehavior` class.
  243. So you can use the classes created in **Step 2** to add the service.
  244. If you create a instance of the `WebSocketServer` class without a port number, the `WebSocketServer` class set the port number to **80** automatically. So it's necessary to run with root permission.
  245. $ sudo mono example2.exe
  246. #### Step 4 ####
  247. Starting the WebSocket server.
  248. ```csharp
  249. wssv.Start ();
  250. ```
  251. #### Step 5 ####
  252. Stopping the WebSocket server.
  253. ```csharp
  254. wssv.Stop (code, reason);
  255. ```
  256. The `WebSocketServer.Stop` method is overloaded.
  257. You can use the `WebSocketServer.Stop ()`, `WebSocketServer.Stop (ushort, string)`, or `WebSocketServer.Stop (WebSocketSharp.CloseStatusCode, string)` method to stop the server.
  258. ### HTTP Server with the WebSocket ###
  259. 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.
  260. So websocket-sharp provides the `WebSocketSharp.Server.HttpServer` class.
  261. You can add any WebSocket service to your `HttpServer` with the specified behavior and path to the service, by using the `HttpServer.AddWebSocketService<TBehaviorWithNew> (string)` or `HttpServer.AddWebSocketService<TBehavior> (string, Func<TBehavior>)` method.
  262. ```csharp
  263. var httpsv = new HttpServer (4649);
  264. httpsv.AddWebSocketService<Echo> ("/Echo");
  265. httpsv.AddWebSocketService<Chat> ("/Chat");
  266. httpsv.AddWebSocketService<Chat> ("/ChatWithNyan", () => new Chat (" Nyan!"));
  267. ```
  268. For more information, would you see **[Example3]**?
  269. ### WebSocket Extensions ###
  270. #### Per-message Compression ####
  271. websocket-sharp supports the **[Per-message Compression][compression]** extension. (But this doesn't support it with the [context take over].)
  272. If you would like to enable this extension as a WebSocket client, you should set such as the following.
  273. ```csharp
  274. ws.Compression = CompressionMethod.Deflate;
  275. ```
  276. And then your client will send the following header with the connection request to the server.
  277. Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover
  278. If the server accepts this extension, it will return the same header which has the corresponding value. And when your client receives it, this extension will be available.
  279. ### Secure Connection ###
  280. websocket-sharp supports the **Secure Connection** with **SSL/TLS**.
  281. As a **WebSocket Client**, you should create a new instance of the `WebSocket` class with the **wss** scheme WebSocket URL.
  282. ```csharp
  283. using (var ws = new WebSocket ("wss://example.com")) {
  284. ...
  285. }
  286. ```
  287. And if you would like to use the custom validation for the server certificate, you should set the `WebSocket.SslConfiguration.ServerCertificateValidationCallback` property.
  288. ```csharp
  289. ws.SslConfiguration.ServerCertificateValidationCallback =
  290. (sender, certificate, chain, sslPolicyErrors) => {
  291. // Do something to validate the server certificate.
  292. ...
  293. return true; // If the server certificate is valid.
  294. };
  295. ```
  296. If you set this property to nothing, the validation does nothing with the server certificate, and returns `true`.
  297. As a **WebSocket Server**, you should create a new instance of the `WebSocketServer` or `HttpServer` class with some settings for secure connection, such as the following.
  298. ```csharp
  299. var wssv = new WebSocketServer (5963, true);
  300. wssv.SslConfiguration.ServerCertificate =
  301. new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");
  302. ```
  303. ### HTTP Authentication ###
  304. websocket-sharp supports the **[HTTP Authentication (Basic/Digest)][rfc2617]**.
  305. As a **WebSocket Client**, you should set a pair of user name and password for the HTTP authentication, by using the `WebSocket.SetCredentials (string, string, bool)` method before connecting.
  306. ```csharp
  307. ws.SetCredentials ("nobita", "password", preAuth);
  308. ```
  309. If `preAuth` is `true`, the `WebSocket` sends the Basic authentication credentials with the first connection request to the server.
  310. Or if `preAuth` is `false`, the `WebSocket` sends either the Basic or Digest (determined by the unauthorized response to the first connection request) authentication credentials with the second connection request to the server.
  311. As a **WebSocket Server**, you should set an HTTP authentication scheme, a realm, and any function to find the user credentials before starting, such as the following.
  312. ```csharp
  313. wssv.AuthenticationSchemes = AuthenticationSchemes.Basic;
  314. wssv.Realm = "WebSocket Test";
  315. wssv.UserCredentialsFinder = id => {
  316. var name = id.Name;
  317. // Return user name, password, and roles.
  318. return name == "nobita"
  319. ? new NetworkCredential (name, "password", "gunfighter")
  320. : null; // If the user credentials aren't found.
  321. };
  322. ```
  323. If you would like to provide the Digest authentication, you should set such as the following.
  324. ```csharp
  325. wssv.AuthenticationSchemes = AuthenticationSchemes.Digest;
  326. ```
  327. ### Query String, Origin header and Cookies ###
  328. As a **WebSocket Client**, if you would like to send the **Query String** with the WebSocket connection request to the server, you should create a new instance of the `WebSocket` class with the WebSocket URL that includes the [Query] string parameters.
  329. ```csharp
  330. using (var ws = new WebSocket ("ws://example.com/?name=nobita")) {
  331. ...
  332. }
  333. ```
  334. And if you would like to send the **Origin header** with the WebSocket connection request to the server, you should set the `WebSocket.Origin` property to an allowable value as the [Origin header] before connecting, such as the following.
  335. ```csharp
  336. ws.Origin = "http://example.com";
  337. ```
  338. And also if you would like to send the **Cookies** with the WebSocket connection request to the server, you should set any cookie by using the `WebSocket.SetCookie (WebSocketSharp.Net.Cookie)` method before connecting, such as the following.
  339. ```csharp
  340. ws.SetCookie (new Cookie ("name", "nobita"));
  341. ```
  342. As a **WebSocket Server**, if you would like to get the **Query String** included in each WebSocket connection request, you should access the `WebSocketBehavior.Context.QueryString` property, such as the following.
  343. ```csharp
  344. public class Chat : WebSocketBehavior
  345. {
  346. private string _name;
  347. ...
  348. protected override void OnOpen ()
  349. {
  350. _name = Context.QueryString["name"];
  351. }
  352. ...
  353. }
  354. ```
  355. And if you would like to validate the **Origin header**, **Cookies**, or both included in each WebSocket connection request, you should set each validation with your `WebSocketBehavior`, for example, by using the `AddWebSocketService<TBehavior> (string, Func<TBehavior>)` method with initializing, such as the following.
  356. ```csharp
  357. wssv.AddWebSocketService<Chat> (
  358. "/Chat",
  359. () => new Chat () {
  360. OriginValidator = val => {
  361. // Check the value of the Origin header, and return true if valid.
  362. Uri origin;
  363. return !val.IsNullOrEmpty () &&
  364. Uri.TryCreate (val, UriKind.Absolute, out origin) &&
  365. origin.Host == "example.com";
  366. },
  367. CookiesValidator = (req, res) => {
  368. // Check the Cookies in 'req', and set the Cookies to send to the client with 'res'
  369. // if necessary.
  370. foreach (Cookie cookie in req) {
  371. cookie.Expired = true;
  372. res.Add (cookie);
  373. }
  374. return true; // If valid.
  375. }
  376. });
  377. ```
  378. And also if you would like to get each value of the Origin header and cookies, you should access each of the `WebSocketBehavior.Context.Origin` and `WebSocketBehavior.Context.CookieCollection` properties.
  379. ### Connecting through the HTTP Proxy server ###
  380. websocket-sharp supports to connect through the **HTTP Proxy** server.
  381. If you would like to connect to a WebSocket server through the HTTP Proxy server, you should set the proxy server URL, and if necessary, a pair of user name and password for the proxy server authentication (Basic/Digest), by using the `WebSocket.SetProxy (string, string, string)` method before connecting.
  382. ```csharp
  383. var ws = new WebSocket ("ws://example.com");
  384. ws.SetProxy ("http://localhost:3128", "nobita", "password");
  385. ```
  386. I tested this with the [Squid]. And it's necessary to disable the following configuration option in **squid.conf** (e.g. `/etc/squid/squid.conf`).
  387. ```
  388. # Deny CONNECT to other than SSL ports
  389. #http_access deny CONNECT !SSL_ports
  390. ```
  391. ### Logging ###
  392. The `WebSocket` class includes the own logging function.
  393. You can use it with the `WebSocket.Log` property (returns a `WebSocketSharp.Logger`).
  394. 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.
  395. ```csharp
  396. ws.Log.Level = LogLevel.Debug;
  397. ```
  398. The above means a log with lower than `LogLevel.Debug` cannot be outputted.
  399. 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`.
  400. ```csharp
  401. ws.Log.Debug ("This is a debug message.");
  402. ```
  403. The `WebSocketServer` and `HttpServer` classes include the same logging function.
  404. ## Examples ##
  405. Examples using websocket-sharp.
  406. ### Example ###
  407. **[Example]** connects to the **[Echo server]** with the WebSocket.
  408. ### Example1 ###
  409. **[Example1]** connects to the **[Audio Data delivery server]** with the WebSocket. (But it's only implemented the chat feature, still unfinished.)
  410. And Example1 uses **[Json.NET]**.
  411. ### Example2 ###
  412. **[Example2]** starts a WebSocket server.
  413. ### Example3 ###
  414. **[Example3]** starts an HTTP server that allows to accept the WebSocket connection requests.
  415. Would you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after Example3 running?
  416. ## Supported WebSocket Specifications ##
  417. websocket-sharp supports **[RFC 6455][rfc6455]**, and it's based on the following WebSocket references:
  418. - **[The WebSocket Protocol][rfc6455]**
  419. - **[The WebSocket API][api]**
  420. - **[Compression Extensions for WebSocket][compression]**
  421. Thanks for translating to japanese.
  422. - **[The WebSocket Protocol 日本語訳][rfc6455_ja]**
  423. - **[The WebSocket API 日本語訳][api_ja]**
  424. ## License ##
  425. websocket-sharp is provided under **[The MIT License]**.
  426. [Audio Data delivery server]: http://agektmr.node-ninja.com:3000
  427. [Echo server]: http://www.websocket.org/echo.html
  428. [Example]: https://github.com/sta/websocket-sharp/tree/master/Example
  429. [Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1
  430. [Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2
  431. [Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3
  432. [Json.NET]: http://james.newtonking.com/projects/json-net.aspx
  433. [Mono]: http://www.mono-project.com
  434. [MonoDevelop]: http://monodevelop.com
  435. [NuGet Gallery]: http://www.nuget.org
  436. [NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp
  437. [Origin header]: http://tools.ietf.org/html/rfc6454#section-7
  438. [Query]: http://tools.ietf.org/html/rfc3986#section-3.4
  439. [Security Sandbox of the Webplayer]: http://docs.unity3d.com/Manual/SecuritySandbox.html
  440. [Squid]: http://www.squid-cache.org
  441. [The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt
  442. [Unity]: http://unity3d.com
  443. [Unity Licenses Comparison]: http://unity3d.com/unity/licenses
  444. [WebSocket-Sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity
  445. [api]: http://www.w3.org/TR/websockets
  446. [api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html
  447. [compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19
  448. [context take over]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#section-8.1.1
  449. [draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75
  450. [draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00
  451. [draft75]: https://github.com/sta/websocket-sharp/tree/draft75
  452. [hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00
  453. [master]: https://github.com/sta/websocket-sharp/tree/master
  454. [rfc2617]: http://tools.ietf.org/html/rfc2617
  455. [rfc6455]: http://tools.ietf.org/html/rfc6455
  456. [rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html