LoginSignup
5
5

More than 3 years have passed since last update.

WebSocketでブラウザにプッシュ通知するサーバをC#で実装

Posted at

はじめに

  • C#を使用してWebSocketサーバを実装しクライアントであるブラウザにプッシュ通知を行うのを試しました
  • IISは使用せずSystem.Net.WebSocketsを使って自前で実装を行っています
  • MSDNの記事を参考に実装しました

サンプルのイメージ

  • サーバ側からWebSocketで値がとんできたらポップアップ表示する

サーバ側の実装

  • 全体はこんな感じです
  • 以下で詳細を説明します
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WebSocketServerSample02
{
    class Program
    {
        static void Main(string[] args)
        {
            Run();
            Console.ReadKey();
        }

        static async Task Run()
        {
            HttpListener s = new HttpListener();
            s.Prefixes.Add("http://IPアドレス:ポート番号/");
            s.Start();
            Console.WriteLine("サーバ起動");

            var hc = await s.GetContextAsync();
            if (!hc.Request.IsWebSocketRequest)
            {
                hc.Response.StatusCode = 400;
                hc.Response.Close();
                return;
            }
            var wsc = await hc.AcceptWebSocketAsync(null);
            var ws = wsc.WebSocket;
            for (int i = 0; i != 5; ++i)
            {
                await Task.Delay(2000);
                var response = "push_event " + DateTime.Now.ToLongTimeString();
                var buffer = Encoding.UTF8.GetBytes(response);
                var segment = new ArraySegment<byte>(buffer);
                await ws.SendAsync(segment, WebSocketMessageType.Text, true, CancellationToken.None);
            }
            await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Done", CancellationToken.None);
        }
    }
}

WebSocketの通信を受付してるところ

            HttpListener s = new HttpListener();
            s.Prefixes.Add("http://IPアドレス:ポート番号/");
            s.Start();
            Console.WriteLine("サーバ起動");

            var hc = await s.GetContextAsync();
            if (!hc.Request.IsWebSocketRequest)
            {
                hc.Response.StatusCode = 400;
                hc.Response.Close();
                return;
            }
            var wsc = await hc.AcceptWebSocketAsync(null);
  • HttpListenerを使用してHTTPサーバとしての処理を起動
  • GetContextAsync()でHttpListenerでのWebSocket接続の受信要求を待ち状態にする
  • Request.IsWebSocketRequestを参照してWebSocket接続でない場合はステータスコード400を返却
  • AcceptWebSocketAsync(null)でWebSocket接続を受入可能状態にする

定期的にクライアントに通信しているところ

            var ws = wsc.WebSocket;
            for (int i = 0; i != 5; ++i)
            {
                await Task.Delay(2000);
                var response = "push_event " + DateTime.Now.ToLongTimeString();
                var buffer = Encoding.UTF8.GetBytes(response);
                var segment = new ArraySegment<byte>(buffer);
                await ws.SendAsync(segment, WebSocketMessageType.Text, true, CancellationToken.None);
            }
            await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Done", CancellationToken.None);
  • 「push_event 現在時刻」をクライアント側に送信する値をresponseに格納
  • SendAsyncでクライアントに送信

クライアント側の実装

  • サーバ側からの通信が来た場合、webSocket.onmessageに記載された処理が動作
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocketClient</title>
<script src="js/jquery-1.11.3.js"></script>
<script type="text/javascript">
    var webSocket;
    window.onload = function() {
        url = "http://IPアドレス:ポート番号/";
        webSocket = new WebSocket(url.replace("http://", "ws://").replace("https://", "wss://"));
        var messageArea = document.getElementById("messageArea");
        var appendMessage = function(value, color) {
            var messageElement = document.createElement("div");
            messageElement.style.color = color;
            messageElement.innerText = value;
            messageArea.insertBefore(messageElement, messageArea.firstChild);
        }
        webSocket.onopen = function() {
            appendMessage("Opened", "blue");
        }
        webSocket.onclose = function() {
            appendMessage("Closed", "red");
        }
        webSocket.onmessage = function(message) {
            var data = message.data;
            alert(data);
            appendMessage(data, "black");
        }
        webSocket.onerror = function(message) {
            appendMessage(message, "red");
        }
    }
</script>
</head>
<body>
    <div id="messageArea"></div>
</body>
</html
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5