1

注: ASP.NET コミュニティのより幅広い聴衆にヒットすると信じているため、これに C# のタグを付けています。これが問題である場合はお知らせください。削除できます (C# は私の優先言語ですが、このプロジェクトでは私がVBで書くことを余儀なくされています)。websocket サーバーは VB.NET ASP.NET WebApi で作成されています。どんな助けでもいただければ幸いです。

接続を開いたままにし、クライアントからサーバーに簡単な文字列メッセージを送信したいだけです。サーバー コードをできる限り単純化して、以下に全文を掲載しました。


以下は私のサーバー コードです: 注: スタック オーバーフローのコード ブロックで文字列として表示されていたため、コメントを VB の "'" から C# の "//" に変更しました。

Public Class ChatController
  Inherits ApiController

  //This is getting hit no problem
  Public Function [Get](username As String) As HttpResponseMessage

    If HttpContext.Current.IsWebSocketRequest Then
      Debug.WriteLine("Starting...") //This is successfully written out

      //Websocket request is accepted and no exceptions are raised..
      HttpContext.Current.AcceptWebSocketRequest(Function() Tasks.Task.FromResult(New ChatWebSocketHandler()))

      //Let the client know we're upgrading...
      Return Request.CreateResponse(HttpStatusCode.SwitchingProtocols)

    Else
      //Handle any bad requests
      Return Request.CreateResponse(HttpStatusCode.BadRequest)

    End If    
  End Function

  //This is my websocket handler - using the Microsoft Websockets class.
  Public Class ChatWebSocketHandler
    Inherits Microsoft.AspNet.SignalR.WebSockets.WebSocketHandler

    //This constructor is hit when the handshake happens, as expected.
    Public Sub New()
      MyBase.New(20000)
    End Sub

    //Everything from here down never gets hit, despite the client 
    //side onOpen/onClose event handlers being raised and readyState being 1.
    Public Overrides Sub OnOpen()
      //Breakpoints on either line below are not hit
      MyBase.OnOpen()

      Debug.WriteLine("Websocket is open")
    End Sub

    //I would expect this to get hit when websocket.send is called, 
    //no such luck.
    Public Overrides Sub OnMessage(message As String)
      Debug.WriteLine("Message Received: " & message)
    End Sub

    //never hit
    Public Overrides Sub OnError()
      MyBase.OnError()
      Debug.WriteLine("Websocket is open")
    End Sub

    //never hit
    Public Overrides Sub OnClose()
      Debug.WriteLine("Websocket Closed")

      MyBase.OnClose()

    End Sub
  End Class
End Class

成功した握手:

実行すると、この行が (コンストラクターと同様に) ヒットし、エラーが発生しないため、ハンドシェイクは成功したように見えます。

//Server Side portion of handshake:
HttpContext.Current.AcceptWebSocketRequest(Function() 
               Tasks.Task.FromResult(New ChatWebSocketHandler()))

//Finish the handshake, let the browser know we're upgrading
Return Request.CreateResponse(HttpStatusCode.SwitchingProtocols)

クライアント側のonOpen()関数がヒットし、1 であるreadystateが書き出されます。ただし、onOpen() で 2 行目がヒットすると、何らかの理由で websocket がすぐに閉じます ( onClose()ハンドラーにジャンプします) 。

//Client side handlers:
function onOpen(evt) {
   writeToScreen("ONOPEN READYSTATE: " + websocket.readyState);
   websocket.send("Websocket's open!")
}

function onClose(evt) {
  writeToScreen("Socket closed");
}

質問:

ChatWebSocketHandler.OnOpen() (下部のサーバー コードを参照) はヒットしません。実際、ハンドシェイク中にコンストラクターを除いて、そのクラスのメソッド ( OnClose() OnError()など) がヒットすることはありません。なぜこれらはヒットしないのですか?

websocket.send()行にブレークポイントを設定すると、その行が実行される前の readystate はまだ 1 であり、その行でエラーにはならず、単純にwebsocket.onClose()イベントにジャンプすることに注意してください。 .

助けてくれてありがとう!必要に応じて、クライアント側の詳細を投稿できます。

4

1 に答える 1

2

まあ、私はついにこれを理解しました、そしてもちろんそれはばかげたことでした:)

どうやら、SignalR で WebSocketHandler クラスを参照するのを間違えたようです。SignalR の内部操作以外で使用することを意図していたようには見えません。

私の新しいコードは非常に似ています。実際の唯一の違いは、継承された websockethandler クラスが Microsoft.Web.Websockets 名前空間にあることです。

もう1つの違いは、次の行です。

HttpContext.Current.AcceptWebSocketRequest(Function() Tasks.Task.FromResult(New ChatWebSocketHandler()))

今はただ:

HttpContext.Current.AcceptWebSocketRequest(New ChatWebSocketHandler)

そこに着くまでに2日かかりましたが、急いでいたのでPMチームと一緒に犬小屋にいますが、やっとそこに着きました. うまくいけば、他の誰かがこれを打ったとしても、私がそうであった限り、彼らはそれに固執することはありません!

于 2016-10-14T17:36:00.063 に答える