Carambolasは、複数の.NET標準2.0アセンブリで構成される、進化する汎用サポートライブラリです。特に、低レイテンシ/低帯域幅遅延製品ネットワークアプリケーションを対象としたカスタムマルチチャネル信頼できるUDPプロトコル実装を備えています。 。
最初のリリースは、完全に機能するネットワークモジュールを備えた最小コアです。このリポジトリは、将来新しいモジュールを追加することで拡張する予定であるため、単一のソリューションを中心に構成されています。
テストカバレッジはまだ最小限であるため、ソースコードを綿密に検査することなく、正確さのレベルを暗示する必要はありません。これは、最も初期の段階で進行中のプロジェクトです。
バイナリは、アーカイブセクションまたはNugetパッケージの形で間もなく利用可能になります。
ローカルホストは、 carambolas.net.hostのインスタンスで表されます。リモートホストに接続するか、着信接続を受け入れるために使用する必要があります。
すべてのリモートホストは、 carambolas.net.peerのインスタンスで表されます。
接続、切断、データなどのイベントはホストオブジェクトを介して受信されますが、ピアオブジェクトを使用してデータを送信したり、積極的に切断したりすることができます。
この時点で、接続、切断、送信、および受信操作は非ブロッキングです。オープンとクローズはブロックされています(明らかな理由で)。
同じホストオブジェクトを使用して、接続を積極的に要求し、P2Pトポロジで使用できるようにするすべての同じ接続を受け入れることができることに注意してください。クライアント/サーバーの役割は、ホストの構成方法だけで実施されず、現れます。ホストは、複数のリモートホストに接続リクエストを同時に送信することもできます。
例:
ホストオブジェクトは、リモートピアに接続するようにインスタンス化されました。内側のループは、次の反復にイベントが蓄積されないようにする責任があります。
using ( var host = new Host ( "MyHost" )
{
host . Open ( IPEndPoint . Any , new Host . Settings ( 0 ) ) ;
host . Connect ( new IPEndPoint ( IPAddress . Loopback , 1313 ) , out Peer peer ) ;
.. .
while ( true )
{
while ( host . TryGetEvent ( out Event e ) )
{
if ( e . EventType == EventType . Data )
Console . WriteLine ( $ "DATA: { e . Peer } { e . Data } " ) ;
else if ( e . EventType == EventType . Connection )
Console . WriteLine ( $ "CONNECTED: { e . Peer } " ) ;
else if ( e . EventType == EventType . Disconnection )
{
Console . WriteLine ( $ "DISCONNECTED: { e . Peer } { e . Reason } " ) ;
return ;
}
}
Thread . Sleep ( 33 ) ;
}
}ホストオブジェクトは、最大10個の着信接続を待つようにインスタンス化されました。内側のループは、次の反復にイベントが蓄積されないようにする責任があります。
using ( var host = new Host ( "MyHost" )
{
host . Open ( new IPEndPoint ( IPAddress . Loopback , 1313 ) , new Host . Settings ( 10 ) ) ;
.. .
while ( true )
{
while ( host . TryGetEvent ( out Event e ) )
{
if ( e . EventType == EventType . Data )
Console . WriteLine ( $ "DATA: { e . Peer } { e . Data } " ) ;
else if ( e . EventType == EventType . Connection )
Console . WriteLine ( $ "CONNECTED: { e . Peer } " ) ;
else if ( e . EventType == EventType . Disconnection )
{
Console . WriteLine ( $ "DISCONNECTED: { e . Peer } { e . Reason } " ) ;
return ;
}
}
Thread . Sleep ( 33 ) ;
}
} このプロジェクトは、トロント映画学校でビデオゲームのデザインと開発を勉強するためにカナダに来た2015年にさかのぼります。元の動機は、複数のUnity3Dプロジェクトで再利用できるアクセサリクラスのコンピレーションを作成することでした。しばらくして、私は見込み客のマルチプレイヤーゲームのためにネットワークソリューションを調査し始め、フォーカスは再利用可能なネットワークモジュールの設計にシフトしました。当初、私は、UNETまたはその他の適切なサードパーティライブラリを統合するという単純な問題として問題に取り組みました。すぐに、私は壊れた仮定から隠された実装のトレードオフまで、あらゆる種類の問題にぶつかり始めました。膨らんだ(ほぼ誤解を招く)機能リスト、設計の互換性、または単純な壊れた実装を見つけることは珍しくありませんでした。特に、私を最も悩ませたのは、ソリューションの多くの側面がランダムにarbitrary意的であるように見え、そのアプローチが好まれた理由または一定の制限が課された理由をほとんどまたはまったく説明しなかったことです。プロジェクトのソースを検査して、コードの別の部分が直接矛盾していることが後で気付くのはなぜだったのかを理解するために、メモを取って何時間も費やします。
これはすべて私をより多くの仕事に駆り立て、最終的に私は自分で実装して検証できる合理的な機能リストを使用して、軽量のネットワークライブラリを自分で構築することにしました。急いで、締め切りはありません。私が考案できる最高の技術的ソリューションを実装するための真の試み。
その間、私は卒業し、フルタイムの仕事に戻り、このプロジェクトを脇に置かなければなりませんでした。 1年前、古いメモを見つけた後、私はプロトタイプのアーカイブを復元し、他の人がそれを実験できるだけでなく、その仕組みとその理由を理解できるように、私が収集したすべての情報と包括的なビルドをまとめることにしました。
マネージドアセンブリは、C#7.3以降をサポートするコンパイラを備えた任意のプラットフォームで構築できます。テストとアクセサリアプリケーションには、NetCore 2.2が必要です。
ネイティブライブラリは、GCCまたはVisual Studioを使用してCmakeを使用して構築できます。
サポートされているOSバージョン:
他のプラットフォームの場合、または必要なネイティブライブラリがない場合、一般的には効率が低い場合は、完全に機能的で透明でなければならないフォールバックコードが存在します。
すべてのC#プロジェクトとビルドスクリプトは、プロジェクトルートにあるビルドフォルダーに中間ファイルとバイナリを保存するように構成されているため、ビルドを簡単に検査、検証、クリーニングできます。
コードはDllimportを使用してネイティブライブラリをバインドします。 dllimportは常にWindowsライブラリ名を使用する場合があり、必要に応じて他のプラットフォームのプレフィックス/サフィックスを自動的に追加します。たとえば、windowsのネットネイティブライブラリの名前であるcarambolas.net.native.dllは、Linuxおよびlibcarambolas.net.native.dll.dynlibのlibcarambolas.net.native.dll.soになります。ビルドスクリプトは、すでに適切な名前の下にライブラリを作成しています。
視覚的なスタジオソリューションは便利なために含まれているため、Windowsには追加のビルドステップは必要ありません。ホストオペレーティングシステム(x86またはx64)に対応するプラットフォームを必ず選択してください。これは、テストアプリケーションを構築し、ユニットテストに必要です。すべての.NETアセンブリは、選択されたソリューションプラットフォームに関係なくAnyCPU用に構築されていますが、Visual Studioは、関連するアセンブリと並んで展開されると予想されるため、テスト用に構築するネイティブライブラリを知っている必要があります。
nugetpack.batを使用して、ネイティブライブラリとポータブルアセンブリをコンパイルし、すべて1つのアクションでNugetパッケージを作成します。
build.batを使用して、Visual Studioを使用せずにリリースするためにすべてのプロジェクトを構築します。
Mac用のVisual Studioはテストされておらず、サポートされていないため、機能することを期待しないでください。
ネイティブライブラリをコンパイルできるように、cmake(> = 2.8)とGCCを必ず用意してください。 Dotnet Core SDK 2.1は、アセンブリをコンパイルしてNugetパッケージを生成するために必要です。
nugetpack.shを使用して、ネイティブライブラリとポータブルアセンブリをコンパイルし、すべてのアクションでNugetパッケージを作成します。
build.shを使用して、Visual Studioを使用せずにリリースするすべてのプロジェクトを構築します。
X86とX64の両方でネイティブライブラリをコンパイルできるように、CMake(> = 2.8)、ビルドエッセンシャル、GCC-Multilibをインストールしてください。
ubuntu run:$ sudo apt-getインストールビルドエッセンシャルgcc-multilib g ++-multilib cmake
Dotnet Core SDK 2.1は、アセンブリをコンパイルしてNugetパッケージを生成するために必要です。
ubuntu run:
$ wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
$ sudo apt-get update;
sudo apt-get install -y apt-transport-https &&
sudo apt-get update &&
sudo apt-get install -y dotnet-sdk-2.1
nugetpack.shを使用して、ネイティブライブラリとポータブルアセンブリをコンパイルし、すべてのアクションでNugetパッケージを作成します。
build.shを使用して、Visual Studioを使用せずにリリースするすべてのプロジェクトを構築します。
Xunit Projectsを使用して、主要な機能を中心に一連のユニットテストのセットが実装されます。
carambolas.net.tests.hostは、基本的なネットワーク機能を手動で検証するために使用されるシンプルなコンソールアプリケーションです。 Wiresharkと不器用な側面を味わうと、特に便利です
carambolas.net.tests.integrationは、Xunitで実装されたCarambolas.netの統合テストのセットです。テストは順番に実行され、それぞれが2つの個別のスレッド(サーバーとクライアント)を開始し、特定の時間の間ループバックインターフェイスを通信します。ループバックは、往復時間が最小である理想的なネットワークを表しています。パケットは順調に到着することはなく、バフファーのオーバーフローがない限り失われることはありません。これらの特性は、通常の実行パスを検証するのに役立ちます。
Wiresharkは、ネットワークアクティビティを監視し、パケットを検査するために使用できる貴重なデバッグツールです。さらに、Wiresharkは、カスタムプロトコルの分析に使用できる特別なクラスのプラグインをサポートしています。
このプロジェクトには、カランボラの基本的なワイレシャーク分離器が含まれています。それを使用するために、Wiresharkがすでにインストールされていることを確認してください。
Clumsyは、ユーザーモードで実行されるネットワークパケットキャプチャプログラムであり、パケットをインターセプトして、劣化したネットワーク条件をリアルタイムでシミュレートできます。
config.txtファイルに次のようなプリセットフィルターラインを追加して、統合テスト(1313)で使用されている同じポートでループバックインターフェイスで接続されたホストに影響を与えます。
carambolas: udp and outbound and loopback and (udp.DstPort == 1313 or udp.SrcPort == 1313)
ループバックインターフェイスで不器用を使用する場合、いくつかの注意事項があることに注意してください。不器用なユーザーマニュアルから:
- ループバックインバウンドパケットは、キャプチャまたは再注入することはできません。考えてみると、コンピューターからそれ自体にパケットを送信するときに、インバウンドまたはアウトバウンドパケットであることを伝えることは本当に困難です。実際、基礎となるWindowsフィルタリングプラットフォームは、すべてのループバックパケットをアウトバウンドとして分類するようです。覚えておくべきことは、ループバックパケットで処理している場合、フィルターに「インバウンド」を入れることができないということです。ルーターによって割り当てられたイントラネットIPのように、コンピューターには127.0.0.1以外のIPがある可能性があることを知ることが重要です。これらもループバックパケットと見なされます。
- ループバックパケットは2回キャプチャされます。インバウンドループバックパケットがないため、すべてのループバックパケットはアウトバウンドと見なされます。したがって、不器用はそれらを2回処理します。1回目は送信するとき、受信時に2回目です。簡単な例は、フィルターが単に「アウトバウンド」であり、500msの遅れを適用する場合です。ローカルホストをpingすると、1000msの遅れになります。宛先ポートなどを指定して、回避できます。ただし、これを念頭に置いて、パラメーターを設定するときは注意してください。
- インバウンドパケットキャプチャは常に機能していません。前述のように、ループバックのインバウンドパケットを再注入することはできません。問題は、宛先IPがコンピューターのIPでなくても、一部のパケットがインバウンドパケットとして分類される場合があることです。これは、非ループバックパケットにのみ影響します。 LocalHostのみに取り組んでいる場合は、大丈夫です。将来のリリースの目標は、これを引き起こしたものを診断し、ソリューションを提供することです。
- プロセスシステムのワイドネットワークキャプチャに基づいてフィルタリングできません。機能としてリストされています。しかし、実際には、これは堅牢なソリューションを提供する簡単な方法がないためです。
バグレポート、バグ修正(さらに良い!)、またはテストカバレッジの改善の形で、私は常に貢献に対してオープンになります。
機能のリクエストは歓迎されますが、どれだけ広範囲、実行可能、または望ましいかに応じて、バックログに保持される場合があります。機能要求が複雑すぎる場合、リソース(時間とお金)が限られているため、スポンサーシップに依存する可能性があります。
このプロジェクトをサポートしたい場合は、私はあなたからの連絡に興味があるかもしれないので、手を差し伸べてください!
ポルトガル語では、カランボラはカランボラ(=星空)の複数形です。この用語は、ブラジルの特定の地域で口語的にも使用され、驚きや焦りを表現しています。
キャランボラの前に、私は使用可能なプロジェクトで自分のアイデアを整理しようと少なくとも半ダースの試みをしました。 Carambolasを使用すると、設計の問題について学び、さまざまなアプローチをテストするために、一連のプロトタイプを構築することにしました。各プロトタイプには、文字によって形成されたコード名とA1から始まる番号がありました。このリポジトリに最初にインポートされていたソースコードは、第9回プロトタイプの第75回の反復であり、したがってA9でした。
ネイティブライブラリは主にパフォーマンス上の理由で提供されるため、完全にオプションです。すべての可能なプラットフォームにネイティブの実装を提供しようとするのは不合理だったでしょう(すべてのデスクトップ、モバイル、コンソール、埋め込み...)、ネイティブライブラリにのみ依存すると、ターゲットプラットフォームがほんの一握り、おそらくデスクトップのみ(Windows、Linux、およびMacOS)を削減します。したがって、経験則として、ネイティブライブラリによって実装された機能について、マネージドコードに常にフォールバック実装が必要です。
ネイティブライブラリはオプションであるため、プログラムは、欠落しているファイルがそこにあるはずであるかどうかを知ることができないため、不足しているネイティブライブラリのエラーがスローまたはログが表示されない理由です。定義上、欠落しているネイティブライブラリは決してエラーではありません。
一般的に、できません。そして、少なくともAPIの観点からはそうではありません。ユーザー(またはアプリプログラマー)にとっては、依存関係のある基礎となる実装戦略、この場合はCaramborasに関係していることは重要ではありません。ただし、この情報は展開に関連する可能性があるため、自動フォールバックを備えたInteroPオブジェクトが作成されるたびに、コードは指標ログ情報を生成します。たとえば、carambolas.net.socketは、基礎となるソケットの実装のためにネイティブライブラリが見つかったときに「carambolas.net.sockets.native.socketを使用する」と同様のログ情報を作成します。このようにして、ネイティブライブラリを念頭に置いて展開する場合、実際に使用されているかどうかを判断できます。
これは、誤ったCPUアーキテクチャのために破損またはコンパイルされたネイティブライブラリを展開することを意味します。
ネイティブライブラリは、対応するInteropアセンブリを並べて並べる必要があり、CPUアーキテクチャのためにアセンブリを1回コンパイルすることができますが、ネイティブライブラリはできません。実行中のオペレーティングシステムのCPUアーキテクチャと一致する必要があります。そうしないと、破損したファイルとして扱われ、.NETがSystem.BadimageFormatexceptionをスローします。これは、エラーではなく定義上、見つかっていないライブラリをロードしようとすることと同じではないことに注意してください。
帯域幅遅延製品(BDP)は、ネットワークリンクの伝送容量(1秒あたりビット)とその往復遅延時間(秒)の製品です。これは、承認が届く前にネットワークが保持できる最大量のデータを表します。
BDPを使用して、特定のしきい値の上または下のネットワークに応じてネットワークを分類できます。大規模なBDPを持つネットワークは、Long脂肪ネットワーク(LFN)と呼ばれます。 LFNは、非常に大きな平均往復時間(衛星リンクのように帯域幅の再生レス)またはかなり小さな往復時間を表示する広い(帯域幅の高い)ネットワークを持つネットワークである可能性があります(ギガビットイーサネットリンクのように)。
詳細については、ウィキペディアを確認してください。
carammbolas.net.socketオブジェクトは、ネイティブソケットの実装またはSystem.net.sockets.socketに依存するフォールバック実装のファサードとして機能します。ホストオブジェクトとピアオブジェクトの複雑さを分離して減らすのに役立ちます。詳細については、doc/readme-carambolas.netを参照してください。
System.net.ipaddressおよびsystem.net.ipendpointは、.NET Coreおよび.NETフレームワークの現在のすべてのインプレメーションにおける多くの不必要な割り当てを促進する可変オブジェクトです。 carambolas.net.ipaddressおよびcarambolas.net.ipendpointは、GC圧力の低下に寄与する不変の値のタイプです。詳細については、doc/readme-carambolas.netを参照してください。
Chacha20とPoly1305を使用してAEADは、すぐにサポートされています。カスタム戦略は、ホストにcarambolas.net.icipherおよびcarambolas.net.IccherFactoryインターフェイスの実装を提供することにより実装できます。唯一の要件は次のとおりです。
ユーザーアプリケーションは、送信する前にデータを自由に圧縮できますが、現在、個々のメッセージまたは完全なパケットの自動圧縮/減圧を提供するメカニズムはありません。
ユーザーアプリケーションと一緒に展開されるように作成されたすべてのソースコードと生産されるバイナリは、MITライセンスの下でライセンスされています。
carambolas.commandlineargumentsは、GriffonRLの記事に基づいており、MITライセンスの下で公開されたソースコードが、元のソースを拡張したJake Ginnivanの別の記事から追加のアイデアを掲載しています。
carambolas.security.criptography.crc32cは、MITライセンスの下でCRC32.NETに基づいていました。
carambolas.security.criptography.naclは、MITライセンスの下でDavid de Smetによってnacl.coreに基づいて拡張されました。
WiresharkのためにLUAで書かれたプロトコル分離器は、GPLV3ライセンスの下で入手できます。機能の機能を拡張し、Carambolas Network Protocolに従ってフォーマットされたUDPパケットに関する詳細情報を表示できるように、Wiresharkの入力ファイルとしてのみ使用されることになっています。したがって、それは完全に分離されており、ソースファイル、アセンブリ、またはネイティブライブラリに何らかの方法で相互作用したり、依存したり、貢献したりしません。