{"id":23983771,"url":"https://github.com/nenonaninu/rxwebsocket","last_synced_at":"2025-10-09T14:29:25.046Z","repository":{"id":103980424,"uuid":"218516207","full_name":"nenoNaninu/RxWebSocket","owner":"nenoNaninu","description":"WebSocket Client for Unity and .NET Standard2.0 / .NET 5 using Rx. (C#)","archived":false,"fork":false,"pushed_at":"2020-11-19T15:40:42.000Z","size":3120,"stargazers_count":11,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-04T17:32:53.544Z","etag":null,"topics":["csharp","net-core","net-standard","netstandard","reactive","reactive-programming","unity3d","websocket","websocket-server","websockets"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nenoNaninu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-30T11:53:01.000Z","updated_at":"2025-05-02T11:39:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"cc400ee9-bf93-4ffb-83e0-9592937314b7","html_url":"https://github.com/nenoNaninu/RxWebSocket","commit_stats":null,"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/nenoNaninu/RxWebSocket","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nenoNaninu%2FRxWebSocket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nenoNaninu%2FRxWebSocket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nenoNaninu%2FRxWebSocket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nenoNaninu%2FRxWebSocket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nenoNaninu","download_url":"https://codeload.github.com/nenoNaninu/RxWebSocket/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nenoNaninu%2FRxWebSocket/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001537,"owners_count":26083119,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","net-core","net-standard","netstandard","reactive","reactive-programming","unity3d","websocket","websocket-server","websockets"],"created_at":"2025-01-07T12:28:42.845Z","updated_at":"2025-10-09T14:29:25.003Z","avatar_url":"https://github.com/nenoNaninu.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RxWebSocket\nRxWebSocket is a WebSocket client for Unity and .NET Standard2.0/2.1. Since Unity 2018 supports .NET Standard 2.0, [ClientWebSocket](https://docs.microsoft.com/ja-jp/dotnet/api/system.net.websockets.clientwebsocket?view=netstandard-2.0) can be used. Therefore, WebSocket protocol can be used without an extra library. However, [ClientWebSocket](https://docs.microsoft.com/ja-jp/dotnet/api/system.net.websockets.clientwebsocket?view=netstandard-2.0) is very cumbersome.\nRxWebSocket is a wrapper of ClientWebSocket for easy handling.\n\n# Tested platform(Unity)\n| \u0026nbsp; |  UWP  |  iOS  | Android | Windows10 Standalone | Mac OSX Standalone | \n| ---- | ---- | ---- | ---- | ---- |-----|\n| IL2CPP | ⭕️ | ⭕️ | \u0026nbsp; | \u0026nbsp; ||\n| Mono \u003cbr\u003e(.NET Standard2.0 \u0026 .NET 4.x) | \u0026nbsp; | \u0026nbsp; | ⭕️ | ⭕️ | ⭕️|\n| .NET Backend | ❌ | \u0026nbsp; | \u0026nbsp; | \u0026nbsp; | \u0026nbsp;|\n\n# Download\n## Unity\n[Releases page](https://github.com/nenoNaninu/RxWebSocket/releases)\n\n## .NET Standard 2.0/2.1\n```\ndotnet add package RxWebSocket\n```\n\n# Requirements for Unity\n- [UniRx](https://github.com/neuecc/UniRx/releases)\n\n# Usage\nThe main class is `WebSocketClient`.\nVarious settings can be made in the constructor.\n- Logger\n  - If you are using unity, you can use the `UnityConsoleLogger` class. It is a simple wrapper such as Debug.log ().\n  - if you use `Microsoft.Extensions.Logging.ILogger\u003cT\u003e` in ASP.NET Core or Console environment, it is easy to integrate using  `AsWebSocketLogger()` which is extension method.\n- [Memory settings for receiving](#memory-settings-for-receiving). \n  - You can set how to use the memory when receiving messages.\n  - By default, a 64KB buffer is allocated. The buffer is automatically expanded as needed.\n  - If you know that you will receive large messages, a larger initial memory allocation will reduce wasted allocation.\n- [Message sending method setting](#sending-options).\n  - Internally, System.Threading.Channels is run in the background to send messages. \n  - You can choose various sending methods by using [these classes](#sending-options).\n- [WebSocket Options(KeepAliveInterval, Proxy,...)](#websocket-options)\n  - If you want to make detailed settings for WebSocket, use the factory method. This is because the `class ClientWebSocketOptions`  constructor is interlnal. You can set [like this](#websocket-options).\n\n\n## Client Code\n```csharp\n#if Unity\nvar webSocketClient = new WebSocketClient(new Uri(\"wss://echo.websocket.org/\"), logger: new UnityConsoleLogger());\n#else \nMicrosoft.Extensions.Logging.ILogger\u003cT\u003e logger;\nvar webSocketClient = new WebSocketClient(new Uri(\"wss://echo.websocket.org/\"), logger: logger.AsWebSocketLogger());\n#endif\n\n//IObservable\u003cbyte[]\u003e\nwebSocketClient.BinaryMessageReceived\n    .Subscribe(x =\u003e DoSomething(x));\n\n// IObservable\u003cstring\u003e\nwebSocketClient.TextMessageReceived\n    .Subscribe(x =\u003e DoSomething(x));\n\n// IObservable\u003cbyte[]\u003e\nwebSocketClient.RawTextMessageReceived\n    .Subscribe(x =\u003e DoSomething(x));\n\n/// Invoke when a close message is received,\n/// before disconnecting the connection in normal system.\nwebSocketClient.CloseMessageReceived\n    .Subscribe(x =\u003e DoSomething(x));\n\nwebSocketClient.OnDispose\n    .Subscribe(_ =\u003e DoSomething());\n\n//Issued when an exception occurs in processing of the background thread(receiving and sending). \nwebSocketClient.ExceptionHappenedInBackground\n    .Subscribe(x =\u003e DoSomething(x));\n\ntry\n{\n    //connect and start listening in background thread.\n    //await until websocket can connect.\n    await webSocketClient.ConnectAsync();\n\n    \n    //Send() method return bool.\n    //If you set the channel created by Channel.CreateBounded () when setting the transmission method, \n    //false may be returned if it is not possible to write to the queue.\n    //Send() function end as soon as writing is completed in the queue. \n    //Therefore, it does not matter whether the sending is finished.\n    byte[] array = MakeSomeArray();\n    bool check1 = webSocketClient.Send(array);\n    bool check2 = webSocketClient.Send(\"string or byte[]\");\n\n    //The SendInstant function ignores the queue used inside the Send function and sends it immediately.\n    //await for transmission to complete.\n    await webSocketClient.SendInstant(\"string or byte[]\");\n\n    //You can decide whether to dispose at the same time as Close with the last bool parameter.\n    await webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, \"description\", true);\n}\ncatch\n{\n}\n\n```\n## Server Code ([ASP.NET Core](https://dotnet.microsoft.com/apps/aspnet))\n```csharp\nHttpContext context;\nMicrosoft.Extensions.Logging.ILogger\u003cT\u003e logger;\n\nif (!context.WebSockets.IsWebSocketRequest) return;\n\nWebSocket socket = await context.WebSockets.AcceptWebSocketAsync();\n\n//You can set the connected socket in the constructor.\nusing var webSocketClient = new WebSocketClient(socket, logger: logger.AsWebSocketLogger());\n\n// subscribe setting...\n\nawait webSocketClient.ConnectAsync();\n\n//If you do not wait, the connection will be disconnected.\nawait webSocketClient.WaitUntilCloseAsync();\n```\n[Here](Sample/Server/WebSocketChat/WebSocketChat/WebSocketChat/WebSocketChatMiddleware.cs#L29-L47) is sample.\n\n# Memory settings for receiving.\nYou can set how to use the memory when receiving messages.\nBy default, a 64KB buffer is allocated. The buffer is automatically expanded as needed.\nIf you know that you will receive large messages, a larger initial memory allocation will reduce wasted allocation.\nYou can use `ReceiverMemoryConfig`.\n```csharp\n// 1024KB\nvar config = new ReceiverMemoryConfig(1024 * 1024);\nvar client = new WebSocketClient(uri, receiverConfig: config);\n```\n\n# Sending options\nInternally, System.Threading.Channels is run in the background to send messages. \nYou can choose various sending methods by using the following class.\n\n- `SingleQueueSender`\n  - By using a single queue, the sending order of both Binary type and Text Type is guaranteed.\n  - It is default.\n- `DoubleQueueSender`\n  - By using two queues, the sending order of Binary type and Text Type is guaranteed separately.\n- `BinaryOnlySender`\n  - Use one queue to send only binary type messages. It is less allocations than SingleQueueSender.\n- `TextOnlySender`\n  - Use one queue to send only text type messages. It is less allocations than SingleQueueSender.\n\nThe above class can inject a Channel in its constructor. By default Channel.CreateUnbounded is used, but if you want to limit the capacity you can use Channel.CreateBounded. At that time, it is recommended to set `SingleReader = true, SingleWriter = false` in the options of `Channel` class.\n\n```csharp\nvar client = new WebSocketClient(new Uri(uri), new DoubleQueueSender());\n\nvar channel = Channel.CreateBounded\u003cSentMessage\u003e(new BoundedChannelOptions(5) { SingleReader = true, SingleWriter = false });\nvar client = new WebSocketClient(new Uri(uri), new SingleQueueSender(channel));\n```\n\n# WebSocket options\nIf you want to make detailed settings for WebSocket, use the factory method.\n```csharp\nvar factory = new Func\u003cClientWebSocket\u003e(() =\u003e new ClientWebSocket\n{\n    Options =\n    {\n        KeepAliveInterval = TimeSpan.FromSeconds(5),\n        Proxy = ...\n        ClientCertificates = ...\n    }\n});\n\nvar webSocketClient = new WebSocketClient(url, clientFactory: factory);\n```\n\n# Notice for Unity\nWebSocketClient issues all events from thread pool. Therefore, you cannot operate the components on Unity in Subscribe directly. So please handle from the main thread using an operator such as 'ObserveOnMainThread' as follows.\n```csharp\n//error will occur.\nwebSocketClient.TextMessageReceived\n    .Subscribe(x =\u003e unityObj.text = x);\n    \n//The following is correct.\nwebSocketClient.TextMessageReceived\n    .ObserveOnMainThread()\n    .Subscribe(x =\u003e unityObj.text = x);\n```\n# Sample\nI prepared a simple chat app as a sample. When the server starts, connect to ```ws://ip:port/ws```.\n## Unity 2018\nopen [this scene](https://github.com/nenoNaninu/RxWebSocket/tree/master/Unity/UniWebSocket/Assets/Scenes) and run.\n\n\n## Server(C#/ ASP.NET Core3.1)\nRequires [.NET Core3.1](https://dotnet.microsoft.com/download/dotnet-core/3.0).  First, set your ip [here](https://github.com/nenoNaninu/UniWebSocket/blob/master/Sample/Server/WebSocketChat/WebSocketChat/Program.cs#L23).\nThen type the following command\n```\n$ cd Sample/Server/WebSocketChat/WebSocketChat/\n$ dotnet run\n```\n\n## Web(bonus)\nopen [```Sample/Web/WebSocketChat.html```](Sample/Web/WebSocketChat.html)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnenonaninu%2Frxwebsocket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnenonaninu%2Frxwebsocket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnenonaninu%2Frxwebsocket/lists"}