2016-12-08 3 views
3

Ich testet .net Kern und eine kleine Beispiel-App mit .net Core + Websockets, um einige Daten in meine App zu schieben. Ich möchte diese Daten in der Datenbank mit einem dbcontext speichern..net Kern Websockets erhalten DbContext

Ich habe jedoch Probleme beim Abrufen der dbcontext in meinem Websocket-Handler. Also, wie kann ich einen dbcontext erstellen, um zu verwenden.

Mein Start Configure-Methode enthält diese:

... 
app.Map("/ws", WSHandler.Map); 
... 

Das ist mein WSHandler Klasse, die tatsächlich Geräte aus der eingehenden Verbindung zu lesen. Ich brauche hier einen DbContext, mit dem ich aus der Datenbank lesen/schreiben kann.

/// <summary> 
/// Handler for an incoming websocket client 
/// </summary> 
public class WSHandler { 
    /// <summary> 
    /// Max size in bytes of an incoming/outgoing message 
    /// </summary> 
    public const int BufferSize = 4096; 

    /// <summary> 
    /// The socket of the current connection 
    /// </summary> 
    WebSocket socket; 

    /// <summary> 
    /// Constructor, assign socket to current instance and adds socket to ConnectedClients. 
    /// </summary> 
    /// <param name="socket"></param> 
    WSHandler(WebSocket socket) { 
     this.socket = socket; 
    } 

    /// <summary> 
    /// Configure app to use websockets and register handler. 
    /// </summary> 
    /// <param name="app"></param> 
    public static void Map(IApplicationBuilder app) { 
     app.UseWebSockets(); 
     app.Use((WSHandler.Acceptor); 
    } 

    /// <summary> 
    /// Accept HttpContext and handles constructs instance of WSHandler. 
    /// </summary> 
    /// <param name="hc">The HttpContext</param> 
    /// <param name="n">Task n</param> 
    /// <returns></returns> 
    static async Task Acceptor(HttpContext hc, Func<Task> n) { 
     if (hc.WebSockets.IsWebSocketRequest == false) { 
      return; 
     } 

     var socket = await hc.WebSockets.AcceptWebSocketAsync(); 
     var h = new WSHandler(socket); 
     await h.Loop(); 
    } 

    /// <summary> 
    /// Wait's for incoming messages 
    /// </summary> 
    /// <returns></returns> 
    async Task Loop() { 
     var buffer = new Byte[BufferSize]; 
     ArraySegment<Byte> segment = new ArraySegment<byte>(buffer); 
     while (this.socket.State == WebSocketState.Open) { 
      WebSocketReceiveResult result = null; 
      do { 
       result = await socket.ReceiveAsync(segment, CancellationToken.None); 
      } while (result.EndOfMessage == false); 

      // do something with message here. I want to save parse and save to database 
     } 

    } 
} 
+0

Hallo, @John Smith. Hast du dieses Problem gelöst? Ich bin jetzt auf der Suche nach der Lösung – Mergasov

+0

@Mergasov ja lassen Sie mich auf den Code gehen, und ich werde die Antwort posten. –

Antwort

2

Da es einige Interessen in diesem Beitrag gibt, habe ich die Lösung hinzugefügt, die ich verwendete.

Sie haben Zugriff auf alle Dienste über die HttpContext. Also habe ich die Kontextoptionen von diesem Dienst abgerufen und dann Kontext erstellt, wenn ich sie brauche. Seien Sie sich jedoch bewusst, dass langlebige Kontexte nicht empfohlen werden und wenn ein Fehler auftritt, ist ein DbContext nicht mehr verwendbar. Am Ende habe ich einen anderen Cache-Layer für die Datenbank implementiert und schreibe in diesen, anstatt DbContext selbst im Websocket-Handler zu verwenden.

Hier ist der obige Code erweitert, um DbContexts zu erstellen. Ich habe es nicht getestet, da ich momentan kein Visual Studio zur Verfügung habe ...

<summary> 
/// Handler for an incoming websocket client 
/// </summary> 
public class WSHandler { 
    /// <summary> 
    /// Max size in bytes of an incoming/outgoing message 
    /// </summary> 
    public const int BufferSize = 4096; 

    /// <summary> 
    /// The socket of the current connection 
    /// </summary> 
    WebSocket socket; 

    /// <summary> 
    /// The options to create DbContexts with. 
    /// </summary> 
    DbContextOptions<AssemblyServerContext> ctxOpts; 

    /// <summary> 
    /// Constructor, assign socket to current instance and adds socket to ConnectedClients. 
    /// </summary> 
    /// <param name="socket"></param> 
    /// <param name="ctxOpts"></param> 
    WSHandler(WebSocket socket, DbContextOptions<AssemblyServerContext> ctxOpts) { 
     this.ctxOpts = ctxOpts; 
     this.socket = socket; 
    } 

    /// <summary> 
    /// Configure app to use websockets and register handler. 
    /// </summary> 
    /// <param name="app"></param> 
    public static void Map(IApplicationBuilder app) { 
     app.UseWebSockets(); 
     app.Use((WSHandler.Acceptor); 
    } 

    /// <summary> 
    /// Accept HttpContext and handles constructs instance of WSHandler. 
    /// </summary> 
    /// <param name="hc">The HttpContext</param> 
    /// <param name="n">Task n</param> 
    /// <returns></returns> 
    static async Task Acceptor(HttpContext hc, Func<Task> n) { 
     if (hc.WebSockets.IsWebSocketRequest == false) { 
      return; 
     } 

     var socket = await hc.WebSockets.AcceptWebSocketAsync(); 
     var ctxOptions = hc.RequestServices.GetService<DbContextOptions<AssemblyServerContext>>(); 
     var h = new WSHandler(socket, ctxOptions); 
     await h.Loop(); 
    } 

    /// <summary> 
    /// Wait's for incoming messages 
    /// </summary> 
    /// <returns></returns> 
    async Task Loop() { 
     var buffer = new Byte[BufferSize]; 
     ArraySegment<Byte> segment = new ArraySegment<byte>(buffer); 
     while (this.socket.State == WebSocketState.Open) { 
      WebSocketReceiveResult result = null; 
      do { 
       result = await socket.ReceiveAsync(segment, CancellationToken.None); 
      } while (result.EndOfMessage == false); 

      // do something with message here. I want to save parse and save to database 
      using (var ctx = new AssemblyServerContext(ctxOpts)) { 

      } 
     } 

    } 
} 
+0

danke dafür, meine Nacht ist gerettet) – Mergasov