DmdataSharp 0.6.0-rc1
See the version list below for details.
dotnet add package DmdataSharp --version 0.6.0-rc1
NuGet\Install-Package DmdataSharp -Version 0.6.0-rc1
<PackageReference Include="DmdataSharp" Version="0.6.0-rc1" />
<PackageVersion Include="DmdataSharp" Version="0.6.0-rc1" />
<PackageReference Include="DmdataSharp" />
paket add DmdataSharp --version 0.6.0-rc1
#r "nuget: DmdataSharp, 0.6.0-rc1"
#:package DmdataSharp@0.6.0-rc1
#addin nuget:?package=DmdataSharp&version=0.6.0-rc1&prerelease
#tool nuget:?package=DmdataSharp&version=0.6.0-rc1&prerelease
DmdataSharp
dmdata.jp からの情報の取得を楽にするための非公式ライブラリ
v0.6.0.0 からの変更点
追加
- 高冗長性WebSocketクライアント (
DmdataV2RedundantSocket) を追加しました。- 複数のエンドポイントに同時接続して耐障害性が向上できるモードです。
- 自動で再接続されるため、単一コネクションの管理にも使えます。
v0.5.0.0 からの変更点
廃止
- V1 API系が廃止されました。
- OAuth Introspect API の公開終了に伴い Obsolate 属性を付与しました。
追加
DmdataApiErrorExceptionを追加しました。APIレスポンスがエラーの場合はこの例外が発生します。DmdataNotValidContractExceptionを追加しました。認証情報は正しいが、情報を取得するための契約が存在しない場合に発生します。DmdataV2ApiClientにAllowPararellRequestプロパティを追加しました。- デフォルトでは
falseのため実質並列リクエストが許可されなくなることになります。
- デフォルトでは
- EEW GD APIを追加しました(thx! @iedred7584)
- WebSocket接続時、任意のサーバーに接続できるようになりました。(利用方法は下記参照)
変更
- OAuth 利用時、回線に問題が起きたときに
DmdataAuthenticationExceptionが発生しないようにしました。 - .NET 5 への対応を終了し、 .NET 7 に対応させました。
v0.4.0.0 からの変更点
全体
- 主にDPoP対応のため内部構造を変更しています。
DmdataApiClientBuilder
UseOAuthClientCredential , UseOAuthRefreshToken が非推奨となりました。
UseOAuth を使用してください。
SimpleOAuthAuthenticator
- 直接認可情報(
OAuthRefreshTokenCredential)を返すようになりました。- それを
builder.UseOAuthでセットして使用します。 - 保存した認可情報を使用する場合は
OAuthRefreshTokenCredentialのインスタンスを自分で作成してください。
- それを
- ローカルホストにおけるリダイレクトURIのチェックの緩和に適応できるようにしました。
- ポートの指定が動的に行えるようになりました。
- DPoP を使用した認証の開始に対応しました。鍵は自動で生成されます。
- (この規格はまだドラフト段階にあるため広く公開するアプリケーションでの利用はまだ推奨しません。)
OAuth
- 認可コードフロー/リフレッシュトークンフローにおいて DPoP に対応しています。
- (この規格はまだドラフト段階にあるため広く公開するアプリケーションでの利用はまだ推奨しません。)
- 各Credentialクラスが Introspect API に対応しました。
情報取得のチュートリアル
実装する際は必ずDM-D.S.Sのドキュメントを読みながら進めてください。
1. OAuthクライアントを作成する
DM-D.S.Sの管理画面からOAuthクライアントを作成します。
各項目を埋めます。注意点としては、
- リダイレクトURIは
http://127.0.0.1/を設定してください。 - 各URIは厳密に判定されており、大文字が使用できません。
- 認証周りについては以下のように設定してください。
- クライアントの種類:
公開 - 使用するフロー:
認可コードフロー/リフレッシュトークンフロー- 現状このライブラリはインプリシットフローに対応していません。
- クライアントの種類:
2. インスタンスを初期化する
APIを叩くためのインスタンスを作成します。 まずはBuilderを作成し、UserAgentなどを設定しておきます(任意)。
// using DmdataSharp;
var builder = DmdataApiClientBuilder.Default
.UserAgent("アプリ名")
.Referrer(new Uri("リファラにいれるURL"));
3. 認可を求める
リフレッシュトークンを保存した場合、この手順はスキップすることができます。
1で作成したOAuthクライアントIDと許可を求めたい(呼びたいAPIが該当する)スコープを SimpleOAuthAuthenticator.AuthorizationAsync に渡して各種トークン(資格情報)の取得を行います。
// using DmdataSharp.Authentication.OAuth;
var clientId = "クライアントID";
var scopes = new[] { "contract.list", "telegram.list", "socket.start", "telegram.get.earthquake" };
// 認可を得る
var credential = await SimpleOAuthAuthenticator.AuthorizationAsync(
builder.HttpClient,
clientId,
scopes,
"DmdataSharp サンプルアプリケーション",
u =>
{
Process.Start(new ProcessStartInfo("cmd", $"/c start {u.Replace("&", "^&")}") { CreateNoWindow = true });
});
// 得た資格情報を登録する(4の内容)
builder = builder.UseOAuth(credential);
{好きなポート} の部分は好みで設定してください。
後述する 内部でホストするHTTPサーバー で使用します。
AuthorizationAsync の解説をしておきます。
Task<OAuthRefreshTokenCredential> AuthorizationAsync(
HttpClient client, // 内部でAPIを呼ぶ際に使用するHttpClient 今回はBuilderで作成したHttpClientを使用します
string clientId, // OAuthクライアントID
string[] scopes, // 認可を求めるスコープ
string title, // 認可時にブラウザ上に表示されるアプリケーション名
Action<string> openUrl, // URLが求められた際にブラウザを開くためのデリゲート
bool useDpop = true, // DPoPを使用するか ※まだ試験中の機能のため実験目的以外の利用は推奨しません
CancellationToken? token = null,// 認可フロー自体の CancellationToken 指定した場合中断させることができる
ushort? listenPort = null) // 内部でホストするHTTPサーバーのポート 未指定の場合はランダム
内部でホストするHTTPサーバーについて
この認可フローはWebブラウザを使用した方式であるため、認可ボタンを押した後ライブラリ内で建てたHTTPサーバーにリダイレクトすることでトークンの取得を行います。
尚、Listenするポートがすでに使用されているなどの問題などが発生した場合 HttpListenerException が発生します。リトライを行うなど、適当に対処してください。
4. 資格情報を登録する
作成していたBuilderに3で取得した資格情報の登録を行います(3のコード内に含まれています)。
リフレッシュトークンは長期間使用することができるため、起動のたびにブラウザを開かないようにするためにも、アプリケーションに組み込むときは保存しておくとよいでしょう。
保存したリフレッシュトークンなどを使用したい場合、 OAuthRefreshTokenCredential のコンストラクタに指定します。
クライアント・クレデンシャルフローを使用する場合も同様に OAuthClientCredential のコンストラクタにクライアントID・シークレットを指定します。
builder = builder.UseOAuth(credential);
なお、この認可情報についてはトークンの無効化などで使用するため変数として保持しておくようにしましょう。
5. APIクライアントを作成する
BuildV2ApiClient でAPIクライアントを作成します。
using var client = builder.BuildV2ApiClient();
これで各種APIが呼べるようになりました。
Disposeにアクセストークンの失効が含まれているため、アプリケーションの終了時などにDisposeを忘れないようにしましょう。
6. 電文リストを取得する
var telegramList = await client.GetTelegramListAsync(limit: 10);
これで最新の電文を10件取得することが可能です。
レスポンスなどはAPIドキュメントを参考にしてください。
注意
ポーリングする場合は必ず cursorToken オプションを使用しましょう。
7. 電文を取得する
using var stream = await client.GetTelegramStreamAsync(id);
keyに取得する電文のKeyパラメータを指定します。これでStreamインスタンスが取得可能です。
メモリ消費削減のためStreamをそのまま返しているため、usingもしくはDisposeを忘れないようにしましょう。
var telegramString = await client.GetTelegramStringAsync(id);
Streamの扱いがめんどくさい人向けにstringに変換する処理を追加したメソッドもあります。
取得からXMLを解析するまでのサンプル
XDocument document;
XmlNamespaceManager nsManager;
using (var telegramStream = await ApiClient.GetTelegramStreamAsync("電文のId"))
using (var reader = XmlReader.Create(telegramStream, new XmlReaderSettings { Async = true }))
{
document = await XDocument.LoadAsync(reader, LoadOptions.None, CancellationToken.None);
nsManager = new XmlNamespaceManager(reader.NameTable);
}
nsManager.AddNamespace("jmx", "http://xml.kishou.go.jp/jmaxml1/");
// 地震情報の場合以下の追記が必要
// nsManager.AddNamespace("eb", "http://xml.kishou.go.jp/jmaxml1/body/seismology1/");
// nsManager.AddNamespace("jmx_eb", "http://xml.kishou.go.jp/jmaxml1/elementBasis1/");
// XPathを使用して電文のタイトルが取得できる
var title = document.Root.XPathSelectElement("/jmx:Report/jmx:Control/jmx:Title", nsManager)?.Value;
8. アプリケーションの連携を解除する
アプリケーションの連携を解除する際はリフレッシュトークンの失効が必要です。
3,4で作成した認可情報のインスタンスから失効を行います。
await credential.RevokeRefreshTokenAsync();
WebSocketに接続する
1. クライアントインスタンスを作成する
using var socket = new DmdataV2Socket(client);
1で作成したAPIクライアントを引数にソケットのインスタンスを作成します。
2. イベントハンドラを登録する
データを受信した際のイベントハンドラを登録します。
socket.Connected += (s, e) => Console.WriteLine("EVENT: connected");
socket.Disconnected += (s, e) => Console.WriteLine("EVENT: disconnected");
socket.Error += (s, e) => Console.WriteLine("EVENT: error c:" + e.Code + " e:" + e.Error);
socket.DataReceived += (s, e) =>
{
Console.WriteLine($@"EVENT: data type: {e.Head.Type} key: {e.Id} valid: {e.Validate()} body: {e.GetBodyString().Substring(0, 20)}...");
};
Connected
接続が完了し、 start を受信したときに発火します。
メッセージの内容をそのまま参照することができます。
Disconnected
切断された・切断したときに発火します。
Error
error を受信したときに発火します。
メッセージの内容をそのまま参照することができます。
DataReceived
data を受信したときに発火します。
public bool Validate()
電文が正しいかどうかの検証を行います。
正しくない場合、大抵のケースはこのライブラリのバグです。
public Stream GetBodyStream()
圧縮されているかなどを自動で判別し展開やデコードを行います。
こちらも念の為usingもしくはDisposeを忘れないように注意してください。
public string GetBodyString(Encoding? encoding = null)
GetBodyStream にstringに変換する処理を追加したものです。
XMLを解析するまでのサンプル
GetTelegramを同じノリで取得できます
XDocument document;
XmlNamespaceManager nsManager;
using (var telegramStream = data.GetBodyStream())
using (var reader = XmlReader.Create(telegramStream, new XmlReaderSettings { Async = true }))
{
document = await XDocument.LoadAsync(reader, LoadOptions.None, CancellationToken.None);
nsManager = new XmlNamespaceManager(reader.NameTable);
}
nsManager.AddNamespace("jmx", "http://xml.kishou.go.jp/jmaxml1/");
// 地震情報の場合以下の追記が必要
// nsManager.AddNamespace("eb", "http://xml.kishou.go.jp/jmaxml1/body/seismology1/");
// nsManager.AddNamespace("jmx_eb", "http://xml.kishou.go.jp/jmaxml1/elementBasis1/");
// XPathを使用して電文のタイトルが取得できる
var title = document.Root.XPathSelectElement("/jmx:Report/jmx:Control/jmx:Title", nsManager)?.Value;
3. 接続を開始する
await socket.ConnectAsync(new SocketStartRequestParameter(
TelegramCategoryV1.Earthquake,
TelegramCategoryV1.Scheduled,
TelegramCategoryV1.Volcano,
TelegramCategoryV1.Weather
)
{
AppName = "アプリ名",
});
SocketStartRequestParameter の引数には受信したい情報のカテゴリを、 AppName は管理画面の 状況 ページで表示される メモ の指定が行なえます。(文字数制限に注意)
その他にも Types で電文のフィルタなども行えますのでご活用ください。
冗長性を確保したい等、接続先のサーバーを指定したいときは追加で引数を指定することもできます。
await socket.ConnectAsync(
new SocketStartRequestParameter(TelegramCategoryV1.Earthquake),
DmdataV2SocketEndpoints.Osaka
);
冗長性を高めた状態でWebSocketを利用する
v0.6.0.0で追加された DmdataV2RedundantSocket を使用することで、複数のエンドポイントに同時接続し、耐障害性を向上させることができます。
1. 高冗長性クライアントインスタンスを作成する
// using DmdataSharp.Redundancy;
using var redundantSocket = new DmdataV2RedundantSocket(client);
通常の DmdataV2Socket と同様にAPIクライアントを引数に指定します。
2. イベントハンドラを登録する
高冗長性クライアントでは、通常のWebSocketイベントに加えて、詳細な接続状態やデータの流れを監視できます。
// 基本的なデータ受信(重複除去後)
redundantSocket.DataReceived += (s, e) =>
{
Console.WriteLine($"Data: {e.Head.Type} from {redundantSocket.ActiveConnectionCount} connections");
};
// 生データ受信(重複除去前、接続別)
redundantSocket.RawDataReceived += (s, e) =>
{
Console.WriteLine($"Raw data from {e.EndpointName}, Duplicate: {e.IsDuplicate}");
};
// 個別接続の確立
redundantSocket.ConnectionEstablished += (s, e) =>
{
Console.WriteLine($"Connection established: {e.EndpointName}");
};
// 個別接続の切断
redundantSocket.ConnectionLost += (s, e) =>
{
Console.WriteLine($"Connection lost: {e.EndpointName}, Reason: {e.Reason}");
};
// 全接続の切断
redundantSocket.AllConnectionsLost += (s, e) =>
{
Console.WriteLine($"ALL CONNECTIONS LOST! Will retry in {e.NextReconnectAttempt.TotalSeconds}s");
};
// 冗長性復旧
redundantSocket.RedundancyRestored += (s, e) =>
{
Console.WriteLine($"Redundancy restored via {e.RestoredEndpoint}");
};
// 冗長性状況変更
redundantSocket.RedundancyStatusChanged += (s, e) =>
{
Console.WriteLine($"Status: {e.Status}, Active: {e.ActiveConnections}");
};
// 接続エラー
redundantSocket.ConnectionError += (s, e) =>
{
Console.WriteLine($"Error on {e.EndpointName}: {e.Exception?.Message}");
};
3. 接続を開始する
// デフォルト(東京+大阪)に接続
await redundantSocket.ConnectAsync(new SocketStartRequestParameter(
TelegramCategoryV1.Earthquake,
TelegramCategoryV1.Scheduled
)
{
AppName = "冗長性アプリ",
});
エンドポイントを明示的に指定することも可能です:
// カスタムエンドポイントに接続
await redundantSocket.ConnectAsync(
new SocketStartRequestParameter(TelegramCategoryV1.Earthquake),
[
DmdataV2SocketEndpoints.Tokyo,
DmdataV2SocketEndpoints.Osaka,
DmdataV2SocketEndpoints.Apne1Az4
]
);
4. 接続状態の確認
Console.WriteLine($"Status: {redundantSocket.Status}");
Console.WriteLine($"Active connections: {redundantSocket.ActiveConnectionCount}");
Console.WriteLine($"Connected endpoints: {string.Join(", ", redundantSocket.ConnectedEndpoints)}");
Console.WriteLine($"Total messages: {redundantSocket.TotalMessagesReceived}");
Console.WriteLine($"Duplicates filtered: {redundantSocket.DuplicateMessagesFiltered}");
5. 設定オプション
var options = new RedundantSocketOptions
{
DefaultEndpoints = new[] { DmdataV2SocketEndpoints.Tokyo, DmdataV2SocketEndpoints.Osaka },
DeduplicationCacheSize = 2000, // 重複除去キャッシュサイズ(デフォルト: 1000)
EnableRawDataEvents = true, // 生データイベントを有効化(デフォルト: true)
ReconnectDelay = TimeSpan.FromSeconds(10) // 再接続間隔(デフォルト: 5秒)
};
using var redundantSocket = new DmdataV2RedundantSocket(client, options);
主な機能
- 複数エンドポイント同時接続: デフォルトで東京・大阪の2箇所に接続
- 重複メッセージ除去: ハッシュによる自動重複検出・除去
- 詳細な状態監視: 個別接続の状態変化を細かく追跡
- 自動フェイルオーバー: 一部接続が失われても継続動作
- 統計情報: 受信数・重複数・接続状況の統計
発生する例外について
APIキー認証の場合、メッセージにAPIキーが含まれている場合文字の置き換えを行います。
DmdataAuthenticationException
各種資格情報が失効しているか、認可されませんでした。
DmdataUnauthorizedException
認証情報が不正です。
DmdataForbiddenException
認証情報が不正です。
使用中の資格情報に権限がない場合などに発生します。
APIv1の場合はAPIキーが不正な場合もこの例外が発生します。
DmdataNotValidContractException
認証情報は正しいが、情報を取得するための契約が存在しない場合に発生します。
DmdataApiErrorException
APIレスポンスがエラーです。 エラーの詳細は例外クラスのプロパティに代入されます。
DmdataApiTimeoutException
APIをリクエストした際にタイムアウトしました。
DmdataRateLimitExceededException
レートリミットに引っかかりました。
このライブラリは同時アクセスの制御を行いません。
しばらく待ってアクセスし直してください。
DmdataException
上記の例外が継承している基底クラスです。
いくつかのエラーで使用されています。
また、ネットワークエラーの場合はその状況に合わせた例外が発生します。
このライブラリで未実装のAPIを使用したい場合
このライブラリには実装されていない、dmdata.jpのAPIを使用したい場合は DmdataV2ApiClient を継承したクラスを作ることで拡張可能です。
DmdataApiClientBuilder の Build メソッドの型引数に継承したクラスを入れることで既存の機能と同様に初期化することができます。
注意点としては、コンストラクタの引数は継承元のクラスに合わせるようにしてください。
protected なメソッドを使用することでライブラリの認証機能などを使用することができます。詳細は DmdataV2ApiClient のコードなどを読んでみてください。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- System.Net.Http (>= 4.3.4)
- System.Text.Json (>= 9.0.6)
-
.NETStandard 2.0
- System.Text.Json (>= 9.0.6)
-
net8.0
- System.Text.Json (>= 9.0.6)
-
net9.0
- System.Text.Json (>= 9.0.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on DmdataSharp:
| Repository | Stars |
|---|---|
|
ingen084/KyoshinEewViewerIngen
Custom client for Kyoshin Monitor
|
| Version | Downloads | Last Updated |
|---|---|---|
| 0.6.0-rc6 | 92 | 10/4/2025 |
| 0.6.0-rc5 | 216 | 8/31/2025 |
| 0.6.0-rc4 | 214 | 8/27/2025 |
| 0.6.0-rc3 | 135 | 7/13/2025 |
| 0.6.0-rc2 | 175 | 7/9/2025 |
| 0.6.0-rc1 | 154 | 7/6/2025 |
| 0.5.6 | 1,052 | 7/9/2023 |
| 0.5.5 | 850 | 8/23/2022 |
| 0.5.4 | 511 | 7/24/2022 |
| 0.5.3 | 583 | 7/23/2022 |
| 0.5.2.2 | 490 | 7/21/2022 |
| 0.5.2.1 | 684 | 4/19/2022 |
| 0.5.2 | 551 | 4/17/2022 |
| 0.5.1.1 | 634 | 3/6/2022 |
| 0.5.1 | 558 | 3/6/2022 |
| 0.5.0.3 | 543 | 3/1/2022 |
| 0.5.0.2 | 546 | 2/28/2022 |
| 0.5.0.1 | 553 | 2/23/2022 |
| 0.5.0 | 538 | 2/20/2022 |
| 0.4.9.1 | 560 | 2/4/2022 |
| 0.4.9 | 527 | 11/28/2021 |
| 0.4.8.1 | 445 | 11/8/2021 |
| 0.4.8 | 486 | 10/9/2021 |
| 0.4.7 | 455 | 10/9/2021 |
| 0.4.6 | 445 | 10/3/2021 |
| 0.4.5 | 491 | 9/12/2021 |
| 0.4.4 | 523 | 8/8/2021 |
| 0.4.3 | 447 | 8/5/2021 |
| 0.4.2 | 484 | 7/31/2021 |
| 0.4.1 | 500 | 7/4/2021 |
| 0.4.0 | 503 | 7/4/2021 |
| 0.3.2 | 492 | 4/30/2021 |
| 0.3.1 | 442 | 4/11/2021 |
| 0.3.0.3 | 461 | 4/3/2021 |
| 0.3.0.2 | 456 | 4/3/2021 |
| 0.3.0.1 | 447 | 4/3/2021 |
| 0.3.0 | 439 | 4/3/2021 |
| 0.2.0 | 478 | 2/24/2021 |
| 0.1.0 | 532 | 2/2/2021 |