2016-12-08 2 views
3

.net 코어를 테스트하고 .net 코어 + 웹 소켓을 사용하여 작은 샘플 응용 프로그램을 만들어 내 응용 프로그램에 일부 데이터를 푸시합니다. dbcontext를 사용하여이 데이터를 데이터베이스에 저장하려고합니다..net core websockets는 DbContext를 얻습니다.

그러나 내 websocket 처리기에서 dbcontext를 가져 오는 데 문제가 있습니다. 그렇다면 어떻게 dbcontext를 만들어 사용할 수 있습니까?

내 시작 구성 방법이 포함되어 있습니다

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

이 실제로 들어오는 연결에서 내 WSHandler 클래스 읽기 구현합니다됩니다. 여기에 데이터베이스에서 읽고 쓸 수있는 DbContext가 필요합니다.

/// <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

안녕하세요, @ 존 스미스. 이 문제를 해결 했습니까? 지금 솔루션을 찾고 있어요 – Mergasov

+0

@Mergasov 예 코드로 이동하게하고 대답을 게시 할 것입니다. –

답변

2

이 게시물에 관심이 있기 때문에 제가 사용한 솔루션을 추가했습니다.

HttpContext을 통해 모든 서비스에 액세스 할 수 있습니다. 그래서 내가 한 것은이 서비스에서 컨텍스트 옵션을 얻은 다음 필요할 때 컨텍스트를 만드는 것입니다. 긴 수명 컨텍스트는 권장되지 않지만 오류가 발생하면 DbContext는 더 이상 사용할 수 없습니다. 결국 나는 다른 데이터베이스 캐싱 레이어를 구현하고 websocket 핸들러에서 DbContext 자체를 사용하는 대신 쓰기 작업을 수행했습니다.

위 코드는 DbContext를 생성하기 위해 확장 된 코드입니다. 지금부터는 비주얼 스튜디오를 사용할 수 없으므로 테스트하지 않았습니다 ...

<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

감사합니다, 내 밤 저장됩니다) – Mergasov