.NETとC#でリアルタイム投票アプリを作る方法
Published: 2024-03-05 03:52:54

C#と.NETを使えば、ブラウザ上で簡単にライブのリアルタイム投票アプリを構築することができ、ユーザーが投票し、リアルタイムで更新される結果を見ることができます。これは、リアルタイム投票システムの機能を取り入れたWebアプリケーションです。このチュートリアルではC# 9、ASP.NET 5.0、PubNub C# SDKバージョン4.4.0を使用します。

このチュートリアルでは、[C# PubNub APIと](https://github.com/pubnub/c-sharp)MicrosoftのASP.NET Core Web APIの一部であるASP.NET MCV4を使って、Webベースのリアルタイム投票アプリケーションを作成する方法を紹介します。PubNub C# SDKを使用することで、ユーザーが投票し、その結果が自動的に集計され、リアルタイムで表示されます。特に \`publish()\`、\`Subscribe()\`、\`DetailedHistory\` メソッドを活用してリアルタイム投票アプリを実現します。ソースコードはGitHubにある。

どのようなリアルタイムアプリケーションでも、質問と答え/回答の選択はエンティティフレームワークを使用してSQLサーバーデータベースのようなバックエンドから発信されることを想定しています。このチュートリアルでは、質問と回答の選択肢を \`SampleData\` クラスの \`GetActivePollQuestion()\` メソッドでハードコーディングし、xml 文字列としてレンダリングします。実際のシナリオでは、動的なデータをxml文字列として返したいでしょう。

### リアルタイム投票アプリのためのスキーマ

この文脈では、スキーマは組織化され構造化されたデータ・ストレージへの道を開き、効率的なデータ処理操作を可能にする。我々の目的を達成するために、PollQuestion.xsdとPollUserAnswer.xsdの2つの[スキーマを](https://gist.github.com/stephenlb/a3fce3a43e1fba4564b6#schemas)作成した。これらはデータの青写真を提供し、格納される情報の構造とタイプを概説する。

対応するクラスファイル、PollQuestion.csとPollUserAnswer.csは、Visual Studioのターミナルでxsd.exeツールを介して以下のコマンドを使用して生成されました：

```js
XSD.EXE PollQuestion.xsd /c /l:cs /n:ePoll.Types

XSD.EXE PollUserAnswer.xsd /c /l:cs /n:ePoll.Types
```

これらのスキーマのフォーマットを見てみよう：

```js
<xs:schema id="PollQuestion"
    targetNamespace="pubnub-csharp-demo-epoll-1.0"
    elementFormDefault="qualified"
    xmlns="pubnub-csharp-demo-epoll-1.0"
    xmlns:mstns="pubnub-csharp-demo-epoll-1.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="PollQuestion">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ID" type="xs:string"></xs:element>
        <xs:element name="Question" type="xs:string"></xs:element>
        <xs:element name="Active" type="xs:boolean"></xs:element>
        <xs:element name="AnswerGroup">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Answer" type="xs:string" maxOccurs="unbounded" minOccurs="2"></xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
```

```js
<xs:schema id="PollUserAnswer"
    targetNamespace="pubnub-csharp-demo-epoll-1.0"
    elementFormDefault="qualified"
    xmlns="pubnub-csharp-demo-epoll-1.0"
    xmlns:mstns="pubnub-csharp-demo-epoll-1.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="PollUserAnswer">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="QuestionID" type="xs:string"></xs:element>
        <xs:element name="Question" type="xs:string"></xs:element>
        <xs:element name="UserAnswer" type="xs:string"></xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>
```

### リアルタイム投票のためのWebSocketによるメッセージの発行

Publish()\`メソッドは投票の回答を指定のPubNubチャネルに送信するために使用され、リアルタイム投票アプリケーションで重要な役割を果たします。このメッセージはそのチャネルに登録されているすべてのインスタンスによってリアルタイムに受信され、インタラクティブな投票体験を促進します。この操作は次のC#コードセグメントで簡単に設定できます。

```js
public bool SaveAnswer(PollUserAnswer answer)
{
    bool ret = false;

    string pubnubChannel = answer.QuestionID;
    mrePublish.AddOrUpdate(pubnubChannel, new ManualResetEvent(false), (key, oldState) => new ManualResetEvent(false));
    messagePublished[pubnubChannel] = false;

    pubnub.Publish().Channel(pubnubChannel).Message(answer.UserAnswer)
        .Execute(new PNPublishResultExt(
            (result, status) => {
                if (!status.Error && result != null)
                {
                    messagePublished[pubnubChannel] = true;
                    mrePublish[pubnubChannel].Set();
                }
            }));

    mrePublish[pubnubChannel].WaitOne(TimeSpan.FromSeconds(10));

    return messagePublished[pubnubChannel];
}
```

### WebSocket を介したリアルタイムの投票ユーザー投稿へのサブスクライブ

反対側では、\`Subscribe()\` メソッドはリアルタイムで投票の回答を受信するために使用されます。これにより、私たちのアプリケーションはリアルタイムの更新を提供できるようになります。PubNub SDKは他のプロトコルの中でも特に長いポーリングを使用してドロップされたメッセージ/リンクを自動回復することができます。あなたのC#コードでこの機能を取得するには、次のコードスニペットを追加することができます。

```js
pubnub.Subscribe<string>()
    .Channels(new List<string> { pubnubChannel })
    .WithPresence() // If you need presence feature
    .Execute();

// Handling messages, presence, and status within the subscription listener
pubnub.AddListener(new SubscribeCallbackExt(
    (pubnubObj, message) => {
        if (message != null)
        {
            Console.WriteLine("VOTE RECEIVED!");
            Console.WriteLine(message.Message);
            Console.WriteLine();
        }
    },
    (pubnubObj, presence) => {
        // Handle presence event if needed
    },
    (pubnubObj, status) => {
        if (status != null)
        {
            if (status.Category == PNStatusCategory.PNConnectedCategory)
            {
                Console.WriteLine("SUBSCRIBE CONNECT CALLBACK:");
                Console.WriteLine(status.Category.ToString());
                Console.WriteLine();
            }
            else if (status.Error)
            {
                Console.WriteLine();
                Console.WriteLine(status.ErrorData.Information);
                Console.WriteLine();
            }
        }
    }
));
```

### リアルタイム投票ダッシュボードのための WebSocket を介したメッセージ履歴のロード

DetailedHistory\` メソッドはチャネルから履歴メッセージをフェッチします。このメソッドはこれらのメッセージを非同期でフェッチし、指定したPubNubチャネルからの投票データの履歴を見ることができます。以下はそのコードです：

```js
public async Task<List<string>> GetPollResultsAsync(string questionID)
{
    List<string> ret = new List<string>();

    string pubnubChannel = questionID;
    long startTimetoken = 0; // For fetching all messages. Adjust as needed.

    try
    {
        PNHistoryResult result = await pubnub.History()
            .Channel(pubnubChannel)
            .Start(startTimetoken)
            .Count(100) // Adjust based on how many messages you expect to fetch. Max usually 100.
            .IncludeTimetoken(true)
            .ExecuteAsync();

        if (result != null && result.Messages != null)
        {
            foreach (var message in result.Messages)
            {
                // Assuming the messages are strings. Adjust as necessary for your data format.
                ret.Add(message.Entry.ToString());
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"An error occurred: {ex.Message}");
        // Handle errors or exceptions as necessary.
    }

    return ret;
}
```

まとめ
---

ここまでで、C#、.NET、PubNub C# SDKを使用してリアルタイム投票アプリケーションを構築する方法について十分理解できたはずです。このチュートリアルを完全に理解したなら、PubNubを使用してアプリケーションにリアルタイム機能を統合するのがいかに簡単であるかに気づいたことでしょう。

次回のブログ記事では、フロントエンドにAngularなどの追加機能を組み込んだり、ユーザー認証を追加したり、データの暗号化を設定したりするなど、さらに一歩踏み込んだ内容を紹介します。ウェブ開発チュートリアルのプレイリストにご期待ください！

はじめに
----

当社のプラットフォームは、開発者がウェブアプリ、モバイルアプリ、IoTデバイス向けにリアルタイムのインタラクティブ機能を構築、提供、管理できるよう支援します。特に、このチュートリアルで説明するようなリアルタイム投票アプリケーションを構築するのに便利です。

私たちのプラットフォームの基盤は、業界最大かつ最もスケーラブルなリアルタイム・エッジ・メッセージング・ネットワークです。そして、堅牢で高性能なソリューションについては、弊社にお任せください。

### PubNubを体験する

[ライブツアー](https://www.pubnub.com/tour/introduction/)

### セットアップ

独自のリアルタイムアプリケーションの作成を開始するには、[PubNubアカウントに](https://admin.pubnub.com/#/login)サインアップしてください。

### 始める

[PubNubのドキュメントは](https://www.pubnub.com/docs)、あなたが何を構築しているかにかかわらず、あなたを助けるためにあります。私たちは、このチュートリアルで使用した[C＃を](https://www.pubnub.com/docs/sdks/c-sharp)含む、さまざまなユースケースとSDKのための広範なガイドを提供しています。

#### 目次

[リアルタイム投票アプリのスキーマ](#h-0)[リアルタイム投票のためのWebSocket経由のメッセージの](#h-1)[公開](#h-0)[WebSocket経由のリアルタイム投票ユーザー投稿への](#h-2)[登録](#h-1)[WebSocket経由のリアルタイム投票ダッシュボードのためのWebSocket経由のメッセージの履歴の](#h-3)読み込み[まとめ](#h-4)はじめに[PubNubを](#h-6)[体験する](#h-5)[セットアップを](#h-7)[入手](#h-6)する[スタート](#h-8)アップ[を入手する](#h-7)

PubNubはどのようにお役に立ちますか？
=====================

この記事は[PubNub.comに](https://www.pubnub.com/blog/how-to-build-a-realtime-voting-app-with-net-and-c/)掲載されたものです。

PubNubのプラットフォームは、開発者がWebアプリ、モバイルアプリ、IoTデバイス向けにリアルタイムのインタラクティブ機能を構築、提供、管理できるように支援します。

私たちのプラットフォームの基盤は、業界最大かつ最もスケーラブルなリアルタイムエッジメッセージングネットワークです。世界15か所以上で8億人の月間アクティブユーザーをサポートし、99.999%の信頼性を誇るため、停電や同時実行数の制限、トラフィックの急増による遅延の問題を心配する必要はありません。

PubNubを体験
---------

[ライブツアーを](https://www.pubnub.com/tour/introduction/)チェックして、5分以内にすべてのPubNub搭載アプリの背後にある本質的な概念を理解する

セットアップ
------

[PubNubアカウントに](https://admin.pubnub.com/signup/)サインアップすると、PubNubキーに無料ですぐにアクセスできます。

始める
---

[PubNubのドキュメントは](https://www.pubnub.com/docs)、ユースケースや[SDKに](https://www.pubnub.com/docs)関係なく、あなたを立ち上げ、実行することができます。