.NET 및 C#으로 실시간 투표 앱을 빌드하는 방법
Published: 2024-03-05 03:57:55

C# 및 .NET을 사용하여 브라우저에서 실시간 실시간 투표 앱을 쉽게 구축하여 사용자가 투표하고 실시간으로 업데이트되는 결과를 확인할 수 있습니다. 실시간 투표 시스템의 기능을 도입한 웹 애플리케이션입니다. 빠른 기술 발전을 고려할 때, 이에 발맞추는 것이 필수적이며 이를 위해 이 튜토리얼에서는 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 웹 API의 일부인 ASP.NET MCV4를 사용하여 웹 기반 실시간 투표 애플리케이션을 만드는 방법을 보여드리겠습니다. 이를 통해 사용자는 투표를 할 수 있고, 그 결과는 PubNub C# SDK를 통해 자동으로 집계되어 실시간으로 표시됩니다. 특히 \`publish()\`, \`Subscribe()\` 및 \`DetailedHistory\` 메서드를 활용하여 실시간 투표 앱을 구동할 것입니다. 소스 코드는 깃허브에서 찾을 수 있습니다.

모든 실시간 애플리케이션에서 질문과 답변/답변의 선택은 엔티티 프레임워크를 사용하는 SQL 서버 데이터베이스와 같은 백엔드에서 시작될 것으로 예상합니다. 이 튜토리얼에서는 초점을 좁히기 위해 \`SampleData\` 클래스의 \`GetActivePollQuestion()\` 메서드에서 질문과 답변 옵션을 하드 코딩하여 이를 xml 문자열로 렌더링해 보겠습니다. 실제 시나리오에서는 동적 데이터를 xml 문자열로 반환하고 싶을 것입니다.

### 실시간 투표 앱을 위한 스키마

이러한 맥락에서 스키마는 체계적이고 구조화된 데이터 저장을 위한 기반을 마련하여 효율적인 데이터 처리 작업을 가능하게 합니다. 이러한 목표를 달성하기 위해 두 개의 [스키마](https://gist.github.com/stephenlb/a3fce3a43e1fba4564b6#schemas), 즉 PollQuestion.xsd와 PollUserAnswer.xsd가 만들어졌습니다. 이 스키마는 데이터의 구조와 저장된 정보의 유형을 설명하는 데이터의 청사진을 제공합니다.

해당 클래스 파일인 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>
```

### 실시간 투표를 위해 웹소켓을 통해 메시지 게시하기

게시()\` 메서드는 실시간 투표 애플리케이션에서 투표 응답을 지정된 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];
}
```

### 웹소켓을 통해 실시간 투표 사용자 제출 구독하기

다른 한편으로, \`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();
            }
        }
    }
));
```

### 실시간 투표 대시보드를 위한 웹소켓을 통한 메시지 이력 불러오기

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 디바이스를 위한 실시간 인터랙티브를 구축, 제공 및 관리할 수 있도록 지원합니다. 특히 이 튜토리얼에서 설명하는 것과 같은 실시간 투표 애플리케이션을 구축하는 데 유용합니다.

Facebook 플랫폼의 기반은 업계에서 가장 크고 확장성이 뛰어난 실시간 에지 메시징 네트워크입니다. 그리고 강력한 고성능 솔루션을 믿고 사용할 수 있습니다.

### 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)[스키마웹소켓을 통한 실시간 투표 메시지](#h-1)[게시하기웹소켓을 통한 실시간 투표 사용자 제출 구독](#h-2)[하기웹소켓을](#h-1) 통한 실시간 투표[메시지 기록 로드하기웹소켓을](#h-3) 통한[실시간 투표 대시보드](#h-3)[마무리하기시작하기펍넙](#h-6)[경험하기설정하기시작하기](#h-8)

펍넙이 어떤 도움을 줄 수 있나요?
===================

이 문서는 원래 [PubNub.com에](https://www.pubnub.com/blog/how-to-build-a-realtime-voting-app-with-net-and-c/) 게시되었습니다.

저희 플랫폼은 개발자가 웹 앱, 모바일 앱 및 IoT 디바이스를 위한 실시간 인터랙티브를 구축, 제공 및 관리할 수 있도록 지원합니다.

저희 플랫폼의 기반은 업계에서 가장 크고 확장성이 뛰어난 실시간 에지 메시징 네트워크입니다. 전 세계 15개 이상의 PoP가 월간 8억 명의 활성 사용자를 지원하고 99.999%의 안정성을 제공하므로 중단, 동시 접속자 수 제한 또는 트래픽 폭증으로 인한 지연 문제를 걱정할 필요가 없습니다.

PubNub 체험하기
-----------

[라이브 투어를](https://www.pubnub.com/tour/introduction/) 통해 5분 이내에 모든 PubNub 기반 앱의 필수 개념을 이해하세요.

설정하기
----

PubNub [계정에](https://admin.pubnub.com/signup/) 가입하여 PubNub 키에 무료로 즉시 액세스하세요.

시작하기
----

사용 사례나 [SDK에](https://www.pubnub.com/docs) 관계없이 [PubNub 문서를](https://www.pubnub.com/docs) 통해 바로 시작하고 실행할 수 있습니다.