当前位置:  开发笔记 > 编程语言 > 正文

使用OWIN的Websockets

如何解决《使用OWIN的Websockets》经验,为你挑选了1个好方法。



1> LearnCode..:

我终于想出了如何解决这个问题.你可以在下面找到代码,我也写了一个在OWIN上使用websockets的基本应用程序.

using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Microsoft.Owin;

namespace NoteApp.WebService.Controller {
   using System;
   using System.Net.WebSockets;
   using System.Text;
   using System.Threading;
   using System.Threading.Tasks;
   using NoteApp.WebService.Handler;
   using WebSocketAccept = System.Action<
                                System.Collections.Generic.IDictionary, // WebSocket Accept parameters
                                System.Func< // WebSocketFunc callback
                                    System.Collections.Generic.IDictionary, // WebSocket environment
                                    System.Threading.Tasks.Task>>;
   using WebSocketCloseAsync = System.Func<
                                    int, // closeStatus
                                    string, // closeDescription
                                    System.Threading.CancellationToken, // cancel
                                    System.Threading.Tasks.Task>;
   using WebSocketReceiveAsync = System.Func<
                  System.ArraySegment, // data
                  System.Threading.CancellationToken, // cancel
                  System.Threading.Tasks.Task<
                      System.Tuple< // WebSocketReceiveTuple
                          int, // messageType
                          bool, // endOfMessage
                          int>>>; // count
   // closeStatusDescription
   using WebSocketReceiveResult = System.Tuple;
   using WebSocketSendAsync = System.Func<
                                       System.ArraySegment, // data
                                       int, // message type
                                       bool, // end of message
                                       System.Threading.CancellationToken, // cancel
                                       System.Threading.Tasks.Task>;

   public class NoteController : ApiController {
      public HttpResponseMessage Get() {
         IOwinContext owinContext = Request.GetOwinContext();

         WebSocketAccept acceptToken = owinContext.Get("websocket.Accept");
         if (acceptToken != null) {
            var requestHeaders = GetValue>(owinContext.Environment, "owin.RequestHeaders");

            Dictionary acceptOptions = null;
            string[] subProtocols;
            if (requestHeaders.TryGetValue("Sec-WebSocket-Protocol", out subProtocols) && subProtocols.Length > 0) {
               acceptOptions = new Dictionary();
               // Select the first one from the client
               acceptOptions.Add("websocket.SubProtocol", subProtocols[0].Split(',').First().Trim());
            }
            acceptToken(acceptOptions, ProcessSocketConnection);


         } else {
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
         }
         return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
      }

      private async Task ProcessSocketConnection(IDictionary wsEnv) {
         var wsSendAsync = (WebSocketSendAsync)wsEnv["websocket.SendAsync"];
         var wsCloseAsync = (WebSocketCloseAsync)wsEnv["websocket.CloseAsync"];
         var wsCallCancelled = (CancellationToken)wsEnv["websocket.CallCancelled"];
         var wsRecieveAsync = (WebSocketReceiveAsync)wsEnv["websocket.ReceiveAsync"];

         //pass the sendasync tuple and the cancellation token to the handler. The handler uses the sendasync method to send message. Each connected client has access to this
         var handler = new NoteSocketHandler(wsSendAsync, CancellationToken.None);
         handler.OnOpen();
         var buffer = new ArraySegment(new byte[100]);
         try {
            object status;
            while (!wsEnv.TryGetValue("websocket.ClientCloseStatus", out status) || (int)status == 0) {
               WebSocketReceiveResult webSocketResultTuple = await wsRecieveAsync(buffer, CancellationToken.None);                   
               int count = webSocketResultTuple.Item3;

               handler.OnMessage(Encoding.UTF8.GetString(buffer.Array, 0, count));
            }
         } catch (Exception ex) {
            Console.WriteLine(ex.Message);
            throw ex;
         }
         handler.OnClose();
         await wsCloseAsync((int)WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
      }

      T GetValue(IDictionary env, string key) {
         object value;
         return env.TryGetValue(key, out value) && value is T ? (T)value : default(T);
      }


   }
}

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有