{"id":19966773,"url":"https://github.com/aptpod/iscp-cs","last_synced_at":"2026-04-08T12:05:35.000Z","repository":{"id":139362933,"uuid":"562787215","full_name":"aptpod/iscp-cs","owner":"aptpod","description":"iSCP client library for C#. iSCP (intdash Stream Control Protocol) is an L7 network protocol authored by aptpod, Inc.","archived":false,"fork":false,"pushed_at":"2025-11-27T06:22:43.000Z","size":2179,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-02-13T23:29:03.557Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aptpod.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-11-07T09:00:51.000Z","updated_at":"2025-11-27T06:22:46.000Z","dependencies_parsed_at":"2025-01-12T08:41:53.492Z","dependency_job_id":"7397aa6e-2e8a-4df3-b580-f90e5cce7b14","html_url":"https://github.com/aptpod/iscp-cs","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/aptpod/iscp-cs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aptpod%2Fiscp-cs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aptpod%2Fiscp-cs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aptpod%2Fiscp-cs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aptpod%2Fiscp-cs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aptpod","download_url":"https://codeload.github.com/aptpod/iscp-cs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aptpod%2Fiscp-cs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31554168,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T10:21:54.569Z","status":"ssl_error","status_checked_at":"2026-04-08T10:21:38.171Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2024-11-13T02:38:11.894Z","updated_at":"2026-04-08T12:05:34.945Z","avatar_url":"https://github.com/aptpod.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# iSCP 2.0 Client Library for C#\n\niSCP Client for C# は、iSCP version 2を用いたリアルタイムAPIにアクセスするためのクライアントライブラリです。\n\n## Requirements\n\n- .NET Standard 2.0\n\n## Dependencies\n\n- [Google.Protobuf](https://github.com/protocolbuffers/protobuf)\n\n## Installation for Unity\n\nUnityへのインポートはパッケージマネージャーから可能です。\n\nパッケージマネージャーの `Add Package from Git URL...` で表示されるテキストボックスに\n\n```\nhttps://github.com/aptpod/iscp-csharp.git?path=/package\n```\n\nを入力しインポートを行ってください。\n\n## Implementation\n\n### Connect to intdash API\n\nこのサンプルではiscp-csを使ってintdash APIに接続します。\n\n```csharp\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\n// iSCPをインポート。\nusing iSCP;\nusing iSCP.Model;\nusing iSCP.Transport;\n\npublic partial class ExampleForUnity : MonoBehaviour, IConnectionCallbacks\n{\n    /// \u003csummary\u003e\n    /// 接続するintdashサーバー\n    /// \u003c/summary\u003e\n    string targetServer = \"https://example.com\";\n    /// \u003csummary\u003e\n    /// ノードUUID（ここで指定されたノードとして送受信を行います。\n    /// intdash APIでノードを生成した際に発行されたノードUUIDを指定します。）\n    /// \u003c/summary\u003e\n    string nodeId = \"00000000-0000-0000-0000-000000000000\";\n    /// \u003csummary\u003e\n    /// アクセストークン\n    /// \u003cpara\u003eintdash APIで取得したアクセストークンを指定して下さい。\u003c/para\u003e\n    /// \u003c/summary\u003e\n    string accessToken = \"\";\n    /// \u003csummary\u003e\n    /// コネクション\n    /// \u003c/summary\u003e\n    Connection connection;\n\n    void Connect()\n    {\n        // 接続情報のセットアップをします。\n        var urls = targetServer.Split(new string[] { \"://\" }, StringSplitOptions.None);\n        string address;\n        var enableTls = false;\n        if (urls.Length == 1)\n        {\n            address = urls[0];\n        }\n        else\n        {\n            enableTls = urls[0] == \"https\";\n            address = urls[1];\n        }\n        // WebSocketを使って接続するように指定します。\n        IConnector connector = new WebSocketConnector(enableTls: enableTls);\n        Connection.Connect(\n            address: address, \n            connector: connector, \n            tokenSource: (token) =\u003e\n            {\n                // アクセス用のトークンを指定します。接続時に発生するイベントにより使用されます。\n                // ここでは固定のトークンを返していますが随時トークンの更新を行う実装にするとトークンの期限切れを考える必要がなくなります。\n                token(accessToken);\n            }, \n            nodeId: nodeId,\n            completion: (con, exception) =\u003e\n            {\n                if (!(con is Connection connection))\n                {\n                    // 接続失敗。\n                    return;\n                }\n                // 接続成功。\n                this.connection = connection;\n                connection.Callbacks = this; // IConnectionCallbacks\n                // 以降、StartUpstreamやStartDownstreamなどが実行可能になります。\n            });\n    }\n\n    #region IConnectionCallbacks\n\n    public void OnReconnect(Connection connection)\n    {\n        // Connectionが再オープンされた際にコールされます。\n    }\n\n    public void OnDisconnect(Connection connection)\n    {\n        // Connectionがクローズされた際にコールされます。\n    }\n\n    public void OnFailWithError(Connection connection, Exception error)\n    {\n        // Connection内部で何らかのエラーが発生した際にコールされます。\n    }\n\n    #endregion\n}\n```\n\n### Start Upstream\n\nアップストリームの送信サンプルです。\n\nこのサンプルでは、基準時刻のメタデータと、文字列型のデータポイントをiSCPサーバーへ送信しています。\n\n```csharp\npublic partial class ExampleForUnity : IUpstreamCallbacks\n{\n    /// \u003csummary\u003e\n    /// 送信するデータを永続化するかどうか\n    /// \u003c/summary\u003e\n    bool upstreamPersist = false;\n    /// \u003csummary\u003e\n    /// オープンしたストリーム一覧\n    /// \u003c/summary\u003e\n    List\u003cUpstream\u003e upstreams = new List\u003cUpstream\u003e();\n\n    void StartUpstream()\n    {\n        // セッションIDを払い出します。\n        var sessionId = Guid.NewGuid().ToString().ToLower();\n\n        // Upstreamをオープンします。\n        connection?.OpenUpstream(\n            sessionId: sessionId, \n            persist: upstreamPersist,\n            completion: (upstream, exception) =\u003e\n            {\n                if (upstream == null)\n                {\n                    // オープン失敗。\n                    return;\n                }\n                // オープン成功。\n                upstreams.Add(upstream);\n\n                // 送信するデータポイントを保存したい場合や、アップストリームのエラーをハンドリングしたい場合はコールバックを設定します。\n                upstream.Callbacks = this; // IUpstreamCallbacks\n\n                var baseTime = DateTime.UtcNow; // 基準時刻です。\n\n                // 基準時刻をiSCPサーバーへ送信します。\n                connection?.SendBaseTime(\n                    baseTime: new BaseTime(\n                        sessionId: sessionId,\n                        name: \"manual\",\n                        priority: 60,\n                        elapsedTime: 0,\n                        baseTime: baseTime.ToUnixTimeTicks()), // 送信する基準時刻はUNIX時刻である必要があります。\n                    persist: upstreamPersist,\n                    completion: (sendBaseTimeEx) =\u003e\n                    {\n                        if (sendBaseTimeEx != null)\n                        {\n                        // 基準時刻の送信に失敗。\n                        return;\n                        }\n                    // 基準時刻の送信に成功。\n\n                    // 文字列型のデータポイントをiSCPサーバーへ送信します。\n                    upstream.WriteDataPoint(\n                            dataId: new DataId(\n                                name: \"greeting\",\n                                type: \"string\"),\n                            dataPoint: new DataPoint(\n                                elapsedTime: DateTime.UtcNow.Ticks - baseTime.Ticks, // 基準時刻からの経過時間をデータポイントの経過時間として打刻します。\n                                payload: System.Text.Encoding.UTF8.GetBytes(\"hello\")));\n                    });\n            });\n    }\n\n    #region IUpstreamCallbacks\n\n    public void OnGenerateChunk(Upstream upstream, UpstreamChunk message)\n    {\n        // バッファへ書き込んだデータポイントが実際に送信される直前にコールされます。\n    }\n\n    public void OnReceiveAck(Upstream upstream, UpstreamChunkAck message)\n    {\n        // データポイントの送信後に返却されるACKを受信できた場合にコールされます。\n    }\n\n    public void OnFailWithError(Upstream upstream, Exception error)\n    {\n        // 内部でエラーが発生した場合にコールされます。\n    }\n\n    public void OnCloseWithError(Upstream upstream, Exception error)\n    {\n        // 何らかの理由でストリームがクローズした場合にコールされます。\n        // 再度アップストリームをオープンしたい場合は、 `Connection.ReopenUpstream()` を使用することにより、ストリームの設定を引き継いで別のストリームを開くことが可能です。\n    }\n\n    public void OnResume(Upstream upstream)\n    {\n        // 自動再接続機能が働き、再接続が行われた場合にコールされます。\n    }\n\n    #endregion\n}\n```\n\n### Start Downstream\n\nアップストリームで送信されたデータをダウンストリームで受信するサンプルです。\n\nこのサンプルでは、アップストリーム開始のメタデータ、基準時刻のメタデータ、文字列型のデータポイントを受信しています。\n\n```csharp\npublic partial class ExampleForUnity : IDownstreamCallbacks\n{\n    /// \u003csummary\u003e\n    /// 受信したいデータを送信している送信元ノードのUUID\n    /// （アップストリームを行っている送信元でConnection.Configで設定したnodeIdを指定してください。）\n    /// \u003c/summary\u003e\n    string targetDownstreamNodeId = \"00000000-0000-0000-0000-000000000000\";\n    /// \u003csummary\u003e\n    /// オープンしたダウンストリーム一覧\n    /// \u003c/summary\u003e\n    List\u003cDownstream\u003e downstreams = new List\u003cDownstream\u003e();\n\n    void StartDownstream()\n    {\n        // ダウンストリームをオープンします。\n        connection?.OpenDownstream(\n            downstreamFilters: new DownstreamFilter[]\n            {\n                new DownstreamFilter(\n                    sourceNodeId: targetDownstreamNodeId, // 送信元ノードのIDを指定します。\n                    dataFilters: new DataFilter[]\n                    {\n                        new DataFilter(\n                            name: \"#\", type: \"#\") // 受信したいデータを名称と型で指定します。この例では、ワイルドカード `#` を使用して全てのデータを取得します。\n                    })\n            },\n            completion: (downstream, exception) =\u003e\n            {\n                if (downstream == null)\n                {\n                    // オープン失敗。\n                    return;\n                }\n                // オープン成功。\n                downstreams.Add(downstream);\n                // 受信データを取り扱うためにデリゲートを設定します。\n                downstream.Callbacks = this; // IDownstreamCallbacks\n            });\n    }\n\n    #region IDownstreamCallbacks\n\n\n    public void OnReceiveChunk(Downstream downstream, DownstreamChunk message)\n    {\n        // データポイントを読み込むことができた際にコールされます。\n        Debug.Log($\"Received dataPoints sequenceNumber[{message.SequenceNumber}], sessionId[{message.UpstreamInfo.SessionId}]\");\n        foreach (var g in message.DataPointGroups)\n        {\n            foreach (var dp in g.DataPoints)\n            {\n                Debug.Log($\"Received a dataPoint dataName[{g.DataId.Name}], dataType[{g.DataId.Type}], payload[{System.Text.Encoding.UTF8.GetString(dp.Payload)}]\");\n            }\n        }\n    }\n\n    public void OnReceiveMetadata(Downstream downstream, DownstreamMetadata message)\n    {\n        // メタデータを受信した際にコールされます。\n        Debug.Log($\"Received a metadata sourceNodeId[{message.SourceNodeId}], metadataType:{message.Type}\");\n        switch (message.Type)\n        {\n            case DownstreamMetadata.MetadataType.BaseTime:\n                var baseTime = message.BaseTime.Value;\n                Debug.Log($\"Received baseTime[{baseTime.BaseTime_.ToDateTimeFromUnixTimeTicks()}], priority[{baseTime.Priority}], name[{baseTime.Name}]\");\n                break;\n            default: break;\n        }\n    }\n\n    public void OnFailWithError(Downstream downstream, Exception error)\n    {\n        // 内部でエラーが発生した場合にコールされます。\n    }\n\n    public void OnCloseWithError(Downstream downstream, Exception error)\n    {\n        // 何らかの理由でストリームがクローズした場合にコールされます。\n        // 再度ダウンストリームをオープンしたい場合は、 `Connection.ReopenDownstream()` を使用することにより、ストリームの設定を引き継いで別のストリームを開くことが可能です。\n    }\n\n    public void OnResume(Downstream downstream)\n    {\n        // 自動再接続機能が働き、再接続が行われた場合にコールされます。\n    }\n\n    #endregion\n}\n```\n\n### E2E Call\n\nE2E（エンドツーエンド）コールのサンプルです。\n\nコントローラノードが対象ノードに対して指示を出し、対象ノードは受信完了のリプライを行う簡単なサンプルです。\n\n```csharp\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\n// iSCPをインポート。\nusing iSCP;\nusing iSCP.Transport;\nusing iSCP.Model;\n\npublic partial class E2ECallExampleForUnity : MonoBehaviour\n{\n    /// \u003csummary\u003e\n    /// 接続するintdashサーバー\n    /// \u003c/summary\u003e\n    string targetServer = \"https://example.com\";\n\n    /// \u003csummary\u003e\n    /// コントローラーノードのUUID\n    /// \u003c/summary\u003e\n    string controllerNodeId = \"00000000-0000-0000-0000-000000000000\";\n    /// \u003csummary\u003e\n    /// 対象ノードのUUID\n    /// \u003c/summary\u003e\n    string targetNodeId = \"11111111-1111-1111-1111-111111111111\";\n\n    /// \u003csummary\u003e\n    /// コントローラーノード用のアクセストークン\n    /// \u003cpara\u003eintdash APIで取得したアクセストークンを指定して下さい。\u003c/para\u003e\n    /// \u003c/summary\u003e\n    string accessTokenForController = \"\";\n    /// \u003csummary\u003e\n    /// 対象ノード用のアクセストークン\n    /// \u003cpara\u003eintdash APIで取得したアクセストークンを指定して下さい。\u003c/para\u003e\n    /// \u003c/summary\u003e\n    string accessTokenForTarget = \"\";\n\n    /// \u003csummary\u003e\n    /// コントローラーノード用のコネクション\n    /// \u003c/summary\u003e\n    Connection connectionForController;\n    /// \u003csummary\u003e\n    /// 対象ノード用のコネクション\n    /// \u003c/summary\u003e\n    Connection connectionForTarget;\n}\n\n// コントローラーノードからメッセージを送信するサンプルです。このサンプルでは文字列メッセージを対象ノードに対して送信し、対象ノードからのリプライを待ちます。\npublic partial class E2ECallExampleForUnity\n{\n\n    void ConnectForController()\n    {\n        // 接続情報のセットアップをします。\n        var urls = targetServer.Split(new string[] { \"://\" }, StringSplitOptions.None);\n        string address;\n        var enableTls = false;\n        if (urls.Length == 1)\n        {\n            address = urls[0];\n        }\n        else\n        {\n            enableTls = urls[0] == \"https\";\n            address = urls[1];\n        }\n        // WebSocketを使って接続するように指定します。\n        ITransportConfig transportConfig = new WebSocket.Config(enableTls: enableTls);\n        Connection.Connect(\n            address: address,\n            transportConfig: transportConfig,\n            tokenSource: (token) =\u003e\n            {\n                // アクセストークンを指定します。接続時に発生するイベントにより使用されます。\n                // ここでは固定のトークンを返していますが、随時トークンの更新を行う実装にするとトークンの期限切れを考える必要がなくなります。\n                token(accessTokenForController);\n            },\n            nodeId: controllerNodeId,\n            completion: (con, exception) =\u003e\n            {\n                if (!(con is Connection connection))\n                {\n                    // 接続失敗。\n                    return;\n                }\n                // 接続成功。\n                this.connectionForController = connection;\n            });\n    }\n\n    void SendCall()\n    {\n        // コールを送信し、リプライコールを受信するとコールバックが発生します。\n        connectionForController?.SendCallAndWaitReplyCall(\n            new UpstreamCall(\n                destinationNodeId: targetNodeId,\n                name: \"greeting\",\n                type: \"string\",\n                payload: System.Text.Encoding.UTF8.GetBytes(\"hello\")), (downstreamReplyCall, exception) =\u003e\n                {\n                    if (exception != null)\n                    {\n                        // コールの送信もしくはリプライの受信に失敗。\n                        return;\n                    }\n                    // コールの送信及びリプライの受信に成功。\n                });\n    }\n\n}\n\n// コントローラーノードからのコールを受け付け、すぐにリプライするサンプルです。\npublic partial class E2ECallExampleForUnity : IConnectionE2ECallCallbacks\n{\n\n    void ConnectForTarget()\n    {\n        // 接続情報のセットアップをします。\n        var urls = targetServer.Split(new string[] { \"://\" }, StringSplitOptions.None);\n        string address;\n        var enableTls = false;\n        if (urls.Length == 1)\n        {\n            address = urls[0];\n        }\n        else\n        {\n            enableTls = urls[0] == \"https\";\n            address = urls[1];\n        }\n        // WebSocketを使って接続するように指定します。\n        ITransportConfig transportConfig = new WebSocket.Config(enableTls: enableTls);\n        Connection.Connect(\n            address: address,\n            transportConfig: transportConfig,\n            tokenSource: (token) =\u003e\n            {\n                // アクセス用のトークンを指定します。接続時に発生するイベントにより使用されます。\n                // ここでは固定のトークンを返していますが、随時トークンの更新を行う実装にするとトークンの期限切れを考える必要がなくなります。\n                token(accessTokenForTarget);\n            },\n            nodeId: targetNodeId,\n            completion: (con, exception) =\u003e\n            {\n                if (!(con is Connection connection))\n                {\n                    // 接続失敗。\n                    return;\n                }\n                // 接続成功。\n                this.connectionForTarget = connection;\n                // DownstreamCallの受信を監視するためにコールバックを設定します。\n                connection.E2ECallCallbacks = this; // IConnectionE2ECallCallbacks\n            });\n    }\n\n    #region IConnectionE2ECallCallbacks\n\n    public void OnReceiveCall(Connection connection, DownstreamCall downstreamCall)\n    {\n        // DownstreamCallを受信した際にコールされます。\n        // このサンプルではDownstreamCallを受信したらすぐにリプライコールを送信します。\n        connection.SendReplyCall(\n            upstreamReplyCall:\n            new UpstreamReplyCall(\n                requestCallId: downstreamCall.CallId,\n                destinationNodeId: downstreamCall.SourceNodeId,\n                name: \"reply_greeting\",\n                type: \"string\",\n                payload: System.Text.Encoding.UTF8.GetBytes(\"world\")), (exception) =\u003e\n                {\n                    if (exception != null)\n                    {\n                        // リプライコールの送信に失敗。\n                        return;\n                    }\n                    // リプライコールの送信に成功。\n                });\n    }\n\n    public void OnReceiveReplyCall(Connection connection, DownstreamReplyCall downstreamReplyCall)\n    {\n        // DownstreamReplyCallを受信した際にコールされます。\n    }\n\n    #endregion\n}\n```\n\n## References\n- [APIリファレンス](https://docs.intdash.jp/api/intdash-sdk/csharp/latest/)\n  - 過去のバージョンのリファレンスは [こちら](https://docs.intdash.jp/api/intdash-sdk/csharp-versions)\n- [GitHub](https://github.com/aptpod/iscp-cs)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faptpod%2Fiscp-cs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faptpod%2Fiscp-cs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faptpod%2Fiscp-cs/lists"}