Maison  >  Article  >  développement back-end  >  Asp.net utilise SignalR pour envoyer des images

Asp.net utilise SignalR pour envoyer des images

高洛峰
高洛峰original
2018-05-28 16:22:203204parcourir

1. Introduction
Dans l'article précédent, nous avons présenté comment utiliser SignalR pour implémenter la fonction de salle de discussion. Dans cet article, nous allons implémenter comment utiliser SignalR pour implémenter la fonction d'envoi d'images.

2. L'idée de​​implémenter la fonction d'envoi de photos
Je vais raconter cet article de la même manière que précédemment, clarifions l'idée de​​mettre en œuvre la. fonction d'envoi de photos.

En plus de spécifier directement le chemin de l'image (cette méthode d'implémentation est également appelée : schéma URI http), l'image peut également être affichée via le schéma Data Uri. Cette méthode permet d'incorporer des images directement dans la page Web sous forme de chaînes. Le formulaire est le suivant :

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

Le code ci-dessus utilise Data Url Schema pour afficher les images. Les avantages et les inconvénients du schéma Uri de données sont :

Avantages :
Il peut réduire les requêtes Http, car si vous utilisez le schéma Uri http pour spécifier l'adresse de l'image, le client doit émettre des requêtes Http pour chaque image , vous pouvez économiser de la bande passante et des requêtes HTTP en utilisant Data Uri

Inconvénients :

Uniquement pris en charge par IE8 et supérieur, et la limite de taille ne peut pas dépasser 32 Ko.
De plus, le contenu Base64 augmentera la taille de l'image de 33%, mais la compression GZIP peut être activée sur le serveur pour réduire la taille du contenu. Malgré cela, étant donné que l'envoi d'une requête Http joindra de nombreuses informations supplémentaires (telles que l'en-tête Http, etc.), la taille cumulée du contenu est généralement plus grande que le contenu augmenté en utilisant l'encodage Base64.

Parce que SignalR est basé sur la transmission de texte, il est nécessaire d'envoyer des images.

Vous pouvez uniquement envoyer la chaîne codée en Base64 de l'image au serveur SignalR, puis le serveur transmettra la chaîne Base64 au client qui a besoin de recevoir l'image, et le client utilisera l'Uri de données pour afficher l'image dans la page pour terminer le transfert d'image.
Bien sûr, vous pouvez également télécharger des images sur Azure Bob Table comme Jabbr (un projet open source qui utilise SignalR pour implémenter le chat instantané), puis renvoyer l'Uri du Blob à tous les clients pour afficher les images. En fait, cette implémentation est similaire à notre implémentation ici. Le client peut lire l'image et l'afficher via l'Uri du blob. En bref, l'idée de mise en œuvre est de convertir indirectement le contenu du fichier binaire image en texte à transmettre.

3. Code d'implémentation pour l'envoi d'images à l'aide de SignalR
Avant l'implémentation spécifique, nous devons ici introduire un plug-in de téléchargement de fichiers - boostrap-fileinput. Ce plug-in est utilisé pour fournir une fonction de prévisualisation d'image. Pour une utilisation spécifique du plug-in, veuillez vous référer au site github ou au code d'implémentation de cet article.

1. Implémentez notre hub

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. Le code d'implémentation de HomeController génère principalement un nom d'utilisateur aléatoire pour chaque client, puis stocke le nom d'utilisateur dans la session.

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. L'étape suivante consiste à implémenter la page frontale.

<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. Effet de fonctionnement
Après les trois étapes ci-dessus, la fonction d'envoi d'images à l'aide de SignalR peut déjà être utilisée. Examinons ensuite l'effet opérationnel spécifique.

Asp.net utilise SignalR pour envoyer des images

À ce stade, l'introduction de tout le contenu de cet article est terminée. Ensuite, nous présenterons comment utiliser l'API de notification Html5 pour implémenter la fonction de rappel des nouveaux. messages.

Pour plus d'articles liés à Asp.net utilisant SignalR pour envoyer des images, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn