OWIN

2017-01-25 10 views
14

का उपयोग कर वेबकॉकेट्स वेब-एपीआई पर माइक्रोसॉफ्ट वेबसाकेट्स का उपयोग करने वाले सभी उदाहरण जिन्हें मैंने अब तक आईआईएस का उपयोग किया है, कार्यान्वयन HTTP विधि को वेबसाकेट में अपग्रेड किया गया है और वेबसाइकिल हैंडलर का एक उदाहरण पास किया गया है HTTPContextOWIN

public HttpResponseMessage Get() { 
    if (HttpContext.Current.IsWebSocketRequest) { 
    var noteHandler = new NoteSocketHandler(); 
    HttpContext.Current.AcceptWebSocketRequest(noteHandler); 
    } 
    return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols); 
} 

ओवीआईएन पाइपलाइन पर ऐसा करने की कोशिश कर रहा है। समस्या का सामना करना पड़ रहा है यह है कि कनेक्शन को वेबकॉकेट्स का उपयोग करने के लिए अपग्रेड किया जा रहा है लेकिन यह मेरे वेबसाइकिल हैंडलर का उपयोग नहीं कर रहा है। मुझसे कहां गलती हो रही है? कृपया सुझाव दे।

नियंत्रक का उपयोग OwinContext,

public HttpResponseMessage Get() { 
    IOwinContext owinContext = Request.GetOwinContext(); 

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

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

     acceptToken(acceptOptions, async wsEnv => { 
     var wsSendAsync = (WebSocketSendAsync)wsEnv["websocket.SendAsync"]; 
     var wsRecieveAsync = (WebSocketReceiveAsync)wsEnv["websocket.ReceiveAsync"]; 
     var wsCloseAsync = (WebSocketCloseAsync)wsEnv["websocket.CloseAsync"]; 
     var wsCallCancelled = (CancellationToken)wsEnv["websocket.CallCancelled"]; 

     //should I pass the handler to an event? 
     var handler = new NoteSocketHAndler();    
     }); 

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

हैंडलर कोड (उदाहरण WebSockets in Nancy using OWIN बाद):

using System; 
using Socket = Microsoft.Web.WebSockets; 
using Newtonsoft.Json; 

public class NoteSocketHandler : Socket.WebSocketHandler { 
    private static Socket.WebSocketCollection connections = new Socket.WebSocketCollection(); 

    public NoteSocketHandler() { 
    } 

    public override void OnOpen() { 
     connections.Add(this); 
    } 

    public override void OnClose() { 
     connections.Remove(this); 
    } 

    public override void OnMessage(string message) { 
     ChatMessage chatMessage = JsonConvert.DeserializeObject<ChatMessage>(message); 
     foreach (var connection in connections) { 
     connection.Send(message); 
     } 
    } 
} 
+0

हमें यहां थोड़ा और कोड चाहिए। आप ओविन ऐप कॉन्फ़िगरेशन/पाइपलाइन कहां स्थापित कर रहे हैं? देरी से प्रतिक्रिया के लिए – Brannon

+0

@ ब्रैनन माफी। उत्तर में मैंने लिखा है कि मैंने प्रोजेक्ट के लिए एक लिंक संलग्न किया है जहां Startup.cs में आप ओविन ऐप कॉन्फ़िगरेशन देख सकते हैं। एफवाईआई मैंने यह पता लगाया कि समस्या क्या थी। – LearnCode

उत्तर

5

मैं अंत में समस्या का समाधान कैसे पता लगा। आप नीचे दिए गए कोड को पा सकते हैं, मैंने एक मूल ऐप लिखा है जो websockets on OWIN का उपयोग करता है।

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<string, object>, // WebSocket Accept parameters 
           System.Func< // WebSocketFunc callback 
            System.Collections.Generic.IDictionary<string, object>, // 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<byte>, // data 
        System.Threading.CancellationToken, // cancel 
        System.Threading.Tasks.Task< 
         System.Tuple< // WebSocketReceiveTuple 
          int, // messageType 
          bool, // endOfMessage 
          int>>>; // count 
    // closeStatusDescription 
    using WebSocketReceiveResult = System.Tuple<int, bool, int>; 
    using WebSocketSendAsync = System.Func< 
             System.ArraySegment<byte>, // 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<WebSocketAccept>("websocket.Accept"); 
     if (acceptToken != null) { 
      var requestHeaders = GetValue<IDictionary<string, string[]>>(owinContext.Environment, "owin.RequestHeaders"); 

      Dictionary<string, object> acceptOptions = null; 
      string[] subProtocols; 
      if (requestHeaders.TryGetValue("Sec-WebSocket-Protocol", out subProtocols) && subProtocols.Length > 0) { 
       acceptOptions = new Dictionary<string, object>(); 
       // 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<string, object> 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<byte>(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<T>(IDictionary<string, object> env, string key) { 
     object value; 
     return env.TryGetValue(key, out value) && value is T ? (T)value : default(T); 
     } 


    } 
} 
संबंधित मुद्दे