1 line
16 KiB
JSON
1 line
16 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 the followings.\r\n\r\n- **[RFC 6455](#supported-websocket-specifications)**\r\n- **[Per-message Compression](#per-message-compression)** extension\r\n- **[Secure Connection](#secure-connection)**\r\n- .NET **3.5** (includes compatible) or later\r\n\r\n## Branches ##\r\n\r\n- **[master]** for production releases.\r\n- **[hybi-00]** for older [draft-ietf-hybi-thewebsocketprotocol-00]. No longer maintained.\r\n- **[draft75]** for even more old [draft-hixie-thewebsocketprotocol-75]. No longer maintained.\r\n\r\n## Build ##\r\n\r\n**websocket-sharp** is built as a single assembly, **websocket-sharp.dll**.\r\n\r\nwebsocket-sharp is developed with **[MonoDevelop]**. So the simple way to build is to open **websocket-sharp.sln** and run build for the websocket-sharp project with any of the build configurations (e.g. Debug) in the MonoDevelop.\r\n\r\n## Install ##\r\n\r\n### Self Build ###\r\n\r\nYou should add **websocket-sharp.dll** (e.g. /path/to/websocket-sharp/bin/Debug/websocket-sharp.dll) that you built it yourself to the library references of your project.\r\n\r\nIf you use websocket-sharp.dll in your **[Unity]** project, you should add it to any folder of your project (e.g. Assets/Plugins) in the **Unity Editor**.\r\n\r\n### NuGet Gallery ###\r\n\r\n**websocket-sharp** has now been displayed on the **[NuGet Gallery]**, as still a **prerelease** version.\r\n\r\n- **[NuGet Gallery: websocket-sharp]**\r\n\r\nYou can add websocket-sharp to your project using the **NuGet Package Manager**, the following command in the **Package Manager Console**.\r\n\r\n PM> Install-Package WebSocketSharp -Pre\r\n\r\n### Unity Asset Store ###\r\n\r\n**websocket-sharp** has now been displayed on the **Unity Asset Store**.\r\n\r\n- **[websocket-sharp for Unity]**\r\n\r\nThat's priced at **US$15**. I think your $15 makes this project more better and accelerated, Thank you!\r\n\r\n## Usage ##\r\n\r\n### WebSocket Client ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\n\r\nnamespace Example\r\n{\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n using (var ws = new WebSocket (\"ws://dragonsnest.far/Laputa\"))\r\n {\r\n ws.OnMessage += (sender, e) =>\r\n {\r\n Console.WriteLine (\"Laputa says: \" + e.Data);\r\n };\r\n\r\n ws.Connect ();\r\n ws.Send (\"BALUS\");\r\n Console.ReadKey (true);\r\n }\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp;\r\n```\r\n\r\nThe `WebSocket` class exists in the `WebSocketSharp` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating an instance of the `WebSocket` class with the specified WebSocket URL to connect.\r\n\r\n```cs\r\nusing (var ws = new WebSocket (\"ws://example.com\"))\r\n{\r\n ...\r\n}\r\n```\r\n\r\nThe `WebSocket` class inherits the `IDisposable` interface, so you can use the `using` statement.\r\n\r\n#### Step 3 ####\r\n\r\nSetting the `WebSocket` events.\r\n\r\n##### WebSocket.OnOpen Event #####\r\n\r\nA `WebSocket.OnOpen` event occurs when the WebSocket connection has been established.\r\n\r\n```cs\r\nws.OnOpen += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e` has passed as `EventArgs.Empty`, so you don't use `e`.\r\n\r\n##### WebSocket.OnMessage Event #####\r\n\r\nA `WebSocket.OnMessage` event occurs when the `WebSocket` receives a WebSocket data frame.\r\n\r\n```cs\r\nws.OnMessage += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e.Type` (`WebSocketSharp.MessageEventArgs.Type`, its type is `WebSocketSharp.Opcode`) indicates the type of a received data. So by checking it, you determine which item you should use.\r\n\r\nIf `e.Type` equals `Opcode.TEXT`, you use `e.Data` (`WebSocketSharp.MessageEventArgs.Data`, its type is `string`) that contains a received **Text** data.\r\n\r\nIf `e.Type` equals `Opcode.BINARY`, you use `e.RawData` (`WebSocketSharp.MessageEventArgs.RawData`, its type is `byte []`) that contains a received **Binary** data.\r\n\r\n```cs\r\nif (e.Type == Opcode.TEXT)\r\n{\r\n // Do something with e.Data\r\n return;\r\n}\r\n\r\nif (e.Type == Opcode.BINARY)\r\n{\r\n // Do something with e.RawData\r\n return;\r\n}\r\n```\r\n\r\n##### WebSocket.OnError Event #####\r\n\r\nA `WebSocket.OnError` event occurs when the `WebSocket` gets an error.\r\n\r\n```cs\r\nws.OnError += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e.Message` (`WebSocketSharp.ErrorEventArgs.Message`, its type is `string`) contains an error message, so you use it.\r\n\r\n##### WebSocket.OnClose Event #####\r\n\r\nA `WebSocket.OnClose` event occurs when the WebSocket connection has been closed.\r\n\r\n```cs\r\nws.OnClose += (sender, e) =>\r\n{\r\n ...\r\n};\r\n```\r\n\r\n`e.Code` (`WebSocketSharp.CloseEventArgs.Code`, its type is `ushort`) contains a status code indicating the reason for closure and `e.Reason` (`WebSocketSharp.CloseEventArgs.Reason`, its type is `string`) contains the reason for closure, so you use them.\r\n\r\n#### Step 4 ####\r\n\r\nConnecting to the WebSocket server.\r\n\r\n```cs\r\nws.Connect ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nSending a data.\r\n\r\n```cs\r\nws.Send (data);\r\n```\r\n\r\nThe `WebSocket.Send` method is overloaded.\r\n\r\nThe types of `data` are `string`, `byte []` and `System.IO.FileInfo`.\r\n\r\nIn addition, the `WebSocket.Send (stream, length)` method exists, too.\r\n\r\nThese methods don't wait for the send to be complete. This means that these methods behave asynchronously.\r\n\r\nIf you do something when the send is complete, you use any of some `WebSocket.Send (data, completed)` methods.\r\n\r\n#### Step 6 ####\r\n\r\nClosing the WebSocket connection.\r\n\r\n```cs\r\nws.Close (code, reason);\r\n```\r\n\r\nIf you close the WebSocket connection explicitly, you use the `WebSocket.Close` method.\r\n\r\nThe `WebSocket.Close` method is overloaded.\r\n\r\nThe types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, and the type of `reason` is `string`.\r\n\r\nIn addition, the `WebSocket.Close ()` and `WebSocket.Close (code)` methods exist, too.\r\n\r\n### WebSocket Server ###\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\nnamespace Example\r\n{\r\n public class Laputa : WebSocketService\r\n {\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n var msg = e.Data == \"BALUS\"\r\n ? \"I've been balused already...\"\r\n : \"I'm not available now.\";\r\n\r\n Send (msg);\r\n }\r\n }\r\n\r\n public class Program\r\n {\r\n public static void Main (string [] args)\r\n {\r\n var wssv = new WebSocketServer (\"ws://dragonsnest.far\");\r\n wssv.AddWebSocketService<Laputa> (\"/Laputa\");\r\n wssv.Start ();\r\n Console.ReadKey (true);\r\n wssv.Stop ();\r\n }\r\n }\r\n}\r\n```\r\n\r\n#### Step 1 ####\r\n\r\nRequired namespace.\r\n\r\n```cs\r\nusing WebSocketSharp.Server;\r\n```\r\n\r\nThe `WebSocketService` and `WebSocketServer` classes exist in the `WebSocketSharp.Server` namespace.\r\n\r\n#### Step 2 ####\r\n\r\nCreating the class that inherits the `WebSocketService` class.\r\n\r\nFor example, if you provide an echo service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Echo : WebSocketService\r\n{\r\n protected override void OnMessage (MessageEventArgs e)\r\n {\r\n Send (e.Data);\r\n }\r\n}\r\n```\r\n\r\nAnd if you provide a chat service,\r\n\r\n```cs\r\nusing System;\r\nusing WebSocketSharp;\r\nusing WebSocketSharp.Server;\r\n\r\npublic class Chat : WebSocketService\r\n{\r\n private string _suffix;\r\n\r\n public Chat ()\r\n : this (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 `WebSocketService.OnMessage` method, it's bound to the server side `WebSocket.OnMessage` event.\r\n\r\nAnd if you override the `WebSocketService.OnOpen`, `WebSocketService.OnError` and `WebSocketService.OnClose` methods, each of them is bound to each server side event of `WebSocket.OnOpen`, `WebSocket.OnError` and `WebSocket.OnClose`.\r\n\r\nThe `WebSocketService.Send` method sends a data to the client of the current session to the WebSocket service.\r\n\r\nThe `WebSocketService.Sessions` (its type is `WebSocketSharp.Server.WebSocketSessionManager`) property provides some functions for the sessions to the WebSocket service.\r\n\r\nThe `WebSocketService.Sessions.Broadcast` method sends a data to all clients of the WebSocket service.\r\n\r\n#### Step 3 ####\r\n\r\nCreating an instance of the `WebSocketServer` class.\r\n\r\n```cs\r\nvar wssv = new WebSocketServer (4649);\r\nwssv.AddWebSocketService<Echo> (\"/Echo\");\r\nwssv.AddWebSocketService<Chat> (\"/Chat\");\r\nwssv.AddWebSocketService<Chat> (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nYou can add any WebSocket service with the specified path to the service to your `WebSocketServer` by using the `WebSocketServer.AddWebSocketService<TWithNew>` or `WebSocketServer.AddWebSocketService<T>` method.\r\n\r\nThe type of `TWithNew` must inherit the `WebSocketService` class and must have a public parameterless constructor.\r\n\r\nThe type of `T` must inherit `WebSocketService` class.\r\n\r\nSo you can use the classes created in **Step 2**.\r\n\r\nIf you create an instance of the `WebSocketServer` class without the port number, the `WebSocketServer` set the port number to **80** automatically. So it's necessary to run with root permission.\r\n\r\n $ sudo mono example2.exe\r\n\r\n#### Step 4 ####\r\n\r\nStarting the server.\r\n\r\n```cs\r\nwssv.Start ();\r\n```\r\n\r\n#### Step 5 ####\r\n\r\nStopping the server.\r\n\r\n```cs\r\nwssv.Stop ();\r\n```\r\n\r\n### HTTP Server with the WebSocket ###\r\n\r\nI modified the `System.Net.HttpListener`, `System.Net.HttpListenerContext` and some other classes of [Mono] to create the HTTP server that can upgrade the connection to the WebSocket connection when it receives a WebSocket connection request.\r\n\r\nYou can add any WebSocket service with the specified path to the service to your `HttpServer` by using the `HttpServer.AddWebSocketService<TWithNew>` or `HttpServer.AddWebSocketService<T>` method.\r\n\r\n```cs\r\nvar httpsv = new HttpServer (4649);\r\nhttpsv.AddWebSocketService<Echo> (\"/Echo\");\r\nhttpsv.AddWebSocketService<Chat> (\"/Chat\");\r\nhttpsv.AddWebSocketService<Chat> (\"/ChatWithNiceBoat\", () => new Chat (\" Nice boat.\"));\r\n```\r\n\r\nFor more information, could you see **[Example3]**?\r\n\r\n### WebSocket Extensions ###\r\n\r\n#### Per-message Compression ####\r\n\r\n**websocket-sharp** supports **[Per-message Compression][compression]** extension. (But it doesn't support with [extension parameters].)\r\n\r\nIf you enable this extension as a WebSocket client, you should do the following.\r\n\r\n```cs\r\nws.Compression = CompressionMethod.DEFLATE;\r\n```\r\n\r\nAnd then your WebSocket client sends the following header in the opening handshake to a WebSocket server.\r\n\r\n Sec-WebSocket-Extensions: permessage-deflate\r\n\r\nIf the server supports this extension, it responds the same header. And when your client receives the header, it enables this extension.\r\n\r\n### Secure Connection ###\r\n\r\nAs a **WebSocket Client**, creating an instance of the `WebSocket` class with the 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 set the custom validation for the server certificate, you use the `WebSocket.ServerCertificateValidationCallback` property.\r\n\r\n```cs\r\nws.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>\r\n{\r\n // Do something to validate the server certificate.\r\n return true; // If the server certificate is valid.\r\n};\r\n```\r\n\r\nIf you set this property to nothing, the validation does nothing with the server certificate, 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 change the current logging level (the default is `LogLevel.ERROR`), you use the `WebSocket.Log.Level` property.\r\n\r\n```cs\r\nws.Log.Level = LogLevel.DEBUG;\r\n```\r\n\r\nThe above means that the logging outputs with a less than `LogLevel.DEBUG` are not outputted.\r\n\r\nAnd if you output a log, you use any of some output methods. The following outputs a log with `LogLevel.DEBUG`.\r\n\r\n```cs\r\nws.Log.Debug (\"This is a debug message.\");\r\n```\r\n\r\nThe `WebSocketServer` and `HttpServer` classes include the same logging functions.\r\n\r\n## Examples ##\r\n\r\nExamples using **websocket-sharp**.\r\n\r\n### Example ###\r\n\r\n[Example] connects to the [Echo server] using the WebSocket.\r\n\r\n### Example1 ###\r\n\r\n[Example1] connects to the [Audio Data delivery server] using the WebSocket ([Example1] is only implemented the chat feature, still unfinished).\r\n\r\nAnd [Example1] uses [Json.NET].\r\n\r\n### Example2 ###\r\n\r\n[Example2] starts a WebSocket server.\r\n\r\n### Example3 ###\r\n\r\n[Example3] starts an HTTP server that can upgrade the connection to the WebSocket connection.\r\n\r\nCould you access to [http://localhost:4649](http://localhost:4649) to do **WebSocket Echo Test** with your web browser after [Example3] running?\r\n\r\n## Supported WebSocket Specifications ##\r\n\r\n**websocket-sharp** supports **[RFC 6455][rfc6455]** and is based on the following WebSocket references.\r\n\r\n- **[The WebSocket Protocol][rfc6455]**\r\n- **[The WebSocket API][api]**\r\n- **[Compression Extensions for WebSocket][compression]**\r\n\r\nThanks for translating to japanese.\r\n\r\n- **[The WebSocket Protocol 日本語訳][rfc6455_ja]**\r\n- **[The WebSocket API 日本語訳][api_ja]**\r\n\r\n## License ##\r\n\r\n**websocket-sharp** is provided under **[The MIT License]**.\r\n\r\n\r\n[Audio Data delivery server]: http://agektmr.node-ninja.com:3000\r\n[Echo server]: http://www.websocket.org/echo.html\r\n[Example]: https://github.com/sta/websocket-sharp/tree/master/Example\r\n[Example1]: https://github.com/sta/websocket-sharp/tree/master/Example1\r\n[Example2]: https://github.com/sta/websocket-sharp/tree/master/Example2\r\n[Example3]: https://github.com/sta/websocket-sharp/tree/master/Example3\r\n[Json.NET]: http://james.newtonking.com/projects/json-net.aspx\r\n[Mono]: http://www.mono-project.com\r\n[MonoDevelop]: http://monodevelop.com\r\n[NuGet Gallery]: http://www.nuget.org\r\n[NuGet Gallery: websocket-sharp]: http://www.nuget.org/packages/WebSocketSharp\r\n[The MIT License]: https://raw.github.com/sta/websocket-sharp/master/LICENSE.txt\r\n[Unity]: http://unity3d.com\r\n[api]: http://www.w3.org/TR/websockets\r\n[api_ja]: http://www.hcn.zaq.ne.jp/___/WEB/WebSocket-ja.html\r\n[compression]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09\r\n[draft-hixie-thewebsocketprotocol-75]: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75\r\n[draft-ietf-hybi-thewebsocketprotocol-00]: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00\r\n[draft75]: https://github.com/sta/websocket-sharp/tree/draft75\r\n[extension parameters]: http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-09#section-8.1\r\n[hybi-00]: https://github.com/sta/websocket-sharp/tree/hybi-00\r\n[master]: https://github.com/sta/websocket-sharp/tree/master\r\n[rfc6455]: http://tools.ietf.org/html/rfc6455\r\n[rfc6455_ja]: http://www.hcn.zaq.ne.jp/___/WEB/RFC6455-ja.html\r\n[websocket-sharp for Unity]: http://u3d.as/content/sta-blockhead/websocket-sharp-for-unity","google":"UA-9752433-2","note":"Don't delete this file! It's used internally to help with page regeneration."} |