>  기사  >  백엔드 개발  >  Asp.net은 SignalR을 사용하여 사진을 보냅니다.

Asp.net은 SignalR을 사용하여 사진을 보냅니다.

高洛峰
高洛峰원래의
2018-05-28 16:22:203203검색

1. 소개
이전 글에서는 SignalR을 사용하여 채팅방 기능을 구현하는 방법을 소개했습니다. 이번 글에서는 SignalR을 사용하여 사진 전송 기능을 구현하는 방법을 구현해 보겠습니다.

2. 사진 전송 기능 구현 아이디어
이번 글에서도 이전과 마찬가지로 구현 아이디어를 명확히 하겠습니다. 사진을 보내는 기능.

이미지의 경로를 직접 지정하는 것(이 구현 방법은 http URI 스키마라고도 함) 외에도 Data Uri Schema를 통해 이미지를 표시할 수도 있습니다. 이 방법을 사용하면 이미지를 문자열 형식으로 웹 페이지에 직접 삽입할 수 있습니다. 형식은 다음과 같습니다.

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

위 코드는 Data Url Schema를 사용하여 이미지를 표시합니다. Data Uri Schema의 장점과 단점은 다음과 같습니다.

장점:
http Uri Schema를 사용하여 이미지 주소를 지정하면 클라이언트가 각 이미지에 대해 Http 요청을 실행해야 하기 때문에 Http 요청을 줄일 수 있습니다. . , 데이터 Uri를 사용하여 대역폭 및 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. 작동 효과
위의 세 단계를 마치면 SignalR을 사용하여 사진을 보내는 기능이 이미 작동될 수 있습니다. 다음으로 구체적인 운용효과를 살펴보겠습니다.

Asp.net은 SignalR을 사용하여 사진을 보냅니다.

이 시점에서 이 글의 모든 내용에 대한 소개가 끝났습니다. 다음으로, Html5 알림 API를 사용하여 new의 알림 기능을 구현하는 방법을 소개하겠습니다. 메시지.

SignalR을 사용하여 사진을 보내는 Asp.net과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.