ホームページ  >  記事  >  バックエンド開発  >  Asp.net は SignalR を使用して画像を送信します

Asp.net は SignalR を使用して画像を送信します

高洛峰
高洛峰オリジナル
2018-05-28 16:22:203204ブラウズ

1.はじめに
前回の記事では、SignalRを使ってチャットルーム機能を実装する方法を紹介しました。

2.写真送信機能の実装の考え方
今回も前回と同様にお伝えしていきますが、まずは写真送信機能の実装の考え方を明確にしておきます。

画像のパスを直接指定する(この実装方法は http URI スキーマとも呼ばれます)以外に、Data Uri スキーマを介して画像を表示することもできます。この方法を使用すると、画像を文字列の形式で Web ページに直接埋め込むことができます。形式は次のとおりです:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA 
7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC" />

上記のコードは、Data Url Schemaを使用して画像を表示します。 Data Uri スキーマの長所と短所は次のとおりです:

利点:
http Uri スキーマを使用して画像アドレスを指定する場合、クライアントは Data Uri This を使用して画像ごとに Http リクエストを発行する必要があるため、HTTP リクエストを減らすことができます。このメソッドは帯域幅と HTTP リクエストを節約できます

欠点:

IE8 以降でのみサポートされており、サイズ制限は 32KB を超えることはできません。
さらに、Base64 コンテンツにより画像のコンテンツが 33% 増加しますが、サーバー上で GZIP 圧縮を有効にしてコンテンツの増加を減らすことができます。それにもかかわらず、HTTP リクエストの送信には多くの追加情報 (HTTP ヘッダーなど) が添付されるため、累積コンテンツ サイズは Base64 エンコーディングを使用して増加したコンテンツよりも依然として大きくなります。

SignalRはテキスト送信を基本としているため、画像を送信する必要があります。

画像の Base64 でエンコードされた文字列のみ SignalR サーバーに送信できます。その後、サーバーは画像を受信する必要があるクライアントに Base64 文字列をプッシュし、クライアントは Data Uri メソッドを使用して画像を表示しますページ上の写真を選択して、写真の転送を完了します。
もちろん、Jabbr (SignalR を使用してインスタント チャットを実装するオープン ソース プロジェクト) のように Azure Bob Table に写真をアップロードし、Blob の URI をすべてのクライアントに返して写真を表示することもできます。実際、この実装はここでの実装と似ています。クライアントは、BLOB の URI を通じてイメージを読み取って表示できます。つまり、実装のアイデアは、画像バイナリ ファイルの内容を間接的にテキストに変換して送信することです。

3. SignalR を使用して画像を送信するための実装コード
具体的な実装の前に、ここではファイル アップロード プラグイン - boostrap-fileinput を導入する必要があります。画像プレビュー機能を提供するプラグインです。プラグインの具体的な使用方法については、github サイトまたはこの記事の実装コードを参照してください。

1. ハブを実装します

public class ChatHub : Hub
  {
    /// <summary>
    /// 供客户端调用的服务器端代码
    /// </summary>
    /// <param name="name"></param>
    /// <param name="message"></param>
    public void Send(string name,string message)
    {
      // 调用所有客户端的sendMessage方法
      Clients.All.sendMessage(name, message);
    }
 
    // 发送图片
    public void SendImage(string name,IEnumerable<ImageData> images)
    {
      foreach (var item in images ?? Enumerable.Empty<ImageData>())
      {
        if(String.IsNullOrEmpty(item.Image)) continue;
        Clients.All.receiveImage(name, item.Image); // 调用客户端receiveImage方法将图片进行显示
      }
    }
 
    /// <summary>
    /// 客户端连接的时候调用
    /// </summary>
    /// <returns></returns>
    public override Task OnConnected()
    {
      Trace.WriteLine("客户端连接成功");
      return base.OnConnected();
    }
  }

2. HomeController の実装コードは主にクライアントごとにランダムなユーザー名を生成し、そのユーザー名をセッションに保存します。

public class HomeController : Controller
  {
    private static readonly char[] Constant =
    {
      &#39;0&#39;, &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;, &#39;6&#39;, &#39;7&#39;, &#39;8&#39;, &#39;9&#39;,
      &#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;, &#39;f&#39;, &#39;g&#39;, &#39;h&#39;, &#39;i&#39;, &#39;j&#39;, &#39;k&#39;, &#39;l&#39;, &#39;m&#39;, &#39;n&#39;, &#39;o&#39;, &#39;p&#39;, &#39;q&#39;, &#39;r&#39;, &#39;s&#39;, &#39;t&#39;, &#39;u&#39;, &#39;v&#39;,
      &#39;w&#39;, &#39;x&#39;, &#39;y&#39;, &#39;z&#39;,
      &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39;, &#39;H&#39;, &#39;I&#39;, &#39;J&#39;, &#39;K&#39;, &#39;L&#39;, &#39;M&#39;, &#39;N&#39;, &#39;O&#39;, &#39;P&#39;, &#39;Q&#39;, &#39;R&#39;, &#39;S&#39;, &#39;T&#39;, &#39;U&#39;, &#39;V&#39;,
      &#39;W&#39;, &#39;X&#39;, &#39;Y&#39;, &#39;Z&#39;
    };
 
    // GET: Home
    public ActionResult Index()
    {
      Session["username"] = GenerateRandomName(4);
      return View();
    }
 
    /// <summary>
    /// 产生随机用户名函数
    /// </summary>
    /// <param name="length">用户名长度</param>
    /// <returns></returns>
    private static string GenerateRandomName(int length)
    {
      var newRandom = new System.Text.StringBuilder(62);
      var rd = new Random(DateTime.Now.Millisecond);
      for (var i = 0; i < length; i++)
      {
        newRandom.Append(Constant[rd.Next(62)]);
      }
 
      return newRandom.ToString();
    }
}

3. 次のステップは、フロントエンド ページを実装することです。

<html>
<head>
  <meta name="viewport" content="width=device-width" />
  <title>使用SignalR实现发送图片</title>
  <link href="/Content/bootstrap.min.css" rel="stylesheet">
  <link href="/Content/bootstrap-fileinput/css/fileinput.min.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
  <p class="container">
    <p>用户名:<p id="username"></p></p>
    <input type="text" id="message" />
    <br/>
    <br />
    <input id="fileinput" type="file">
    <br />
    <input type="button" id="sendmessage" value="Send" />
    <input type="hidden" id="displayname" />
    <ul id="discussion"></ul>
  </p>
  <script type="text/javascript" src="~/Scripts/jquery-2.2.2.min.js"></script>
  <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
  <script src="~/signalr/hubs"></script>
  <script src="/Scripts/fileinput.js" type="text/javascript"></script>
  <script src="/Scripts/bootstrap.min.js" type="text/javascript"></script>
  <script>
    $(function () {
      var userName = &#39;@Session["username"]&#39;;
      $(&#39;#username&#39;).html(userName);
      // 引用自动生成的集线器代理
      var chat = $.connection.chatHub;
      // 定义服务器端调用的客户端sendMessage来显示新消息
 
      chat.client.sendMessage = function (name, message) {
        // 向页面添加消息
        $(&#39;#discussion&#39;).append(&#39;<li><strong>&#39; + htmlEncode(name)
          + &#39;</strong>: &#39; + htmlEncode(message) + &#39;</li>&#39;);
      };
 
      chat.client.receiveImage = function (name, base64) {
        // 向页面添加消息
        $(&#39;#discussion&#39;).append(&#39;<image class = "file-preview-image" style="width:auto;height:100px;" src=&#39; + base64
          + &#39;/>&#39;);
      };
 
      // 设置焦点到输入框
      $(&#39;#message&#39;).focus();
      // 开始连接服务器
      $.connection.hub.start().done(function () {
        $(&#39;#sendmessage&#39;).click(function () {
          // 调用服务器端集线器的Send方法
          chat.server.send(userName, $(&#39;#message&#39;).val());
          // 清空输入框信息并获取焦点
          $(&#39;#message&#39;).val(&#39;&#39;).focus();
        });
      });
 
      $("#fileinput").fileinput({
        allowedFileExtensions: ["jpg", "png", "gif", "jpeg"],
        maxImageWidth: 700,
        maxImageHeight: 700,
        resizePreference: &#39;height&#39;,
        maxFileCount: 1,
        resizeImage: true
      });
 
      $("#fileinput").on(&#39;fileloaded&#39;, function (event, file, previewId, index, reader) {
        var readers = new FileReader();
        readers.onloadend = function () {
          $(".file-preview-image").attr(&#39;src&#39;, readers.result);
        };
        readers.readAsDataURL(file);
      });
 
      $(&#39;#sendmessage&#39;).click(function() {
        var imagesJson = $(&#39;.file-preview-image&#39;).map(function() {
          var $this = $(this);
          return {
            image: $this.attr(&#39;src&#39;),
            filename: $this.attr(&#39;data-filename&#39;)
          };
        }).toArray();
 
        chat.server.sendImage(userName, imagesJson);
      });
    });
 
  // 为显示的消息进行Html编码
  function htmlEncode(value) {
    var encodedValue = $(&#39;<p />&#39;).text(value).html();
    return encodedValue;
  }
  </script>
   
</body>
</html>

4. 運用効果
上記 3 つの手順を完了すると、SignalR を使用した画像送信機能が運用可能になります。次に、具体的な運用効果を見てみましょう。

Asp.net は SignalR を使用して画像を送信します

ここで、この記事の内容の全ての紹介は終わりです。次に、Html5のNotification APIを使って新着メッセージのリマインダー機能を実装する方法を紹介します。

SignalR を使用して画像を送信する Asp.net に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。