ASP.NET MVC Websocket 服务器 (WebAPI) 握手完成,但 OnOpen 和其他事件函数未被服务器端访问

ASP.NET MVC Websocket server (WebAPI) handshake completing, but OnOpen and other event functions are not getting hit server side

注意: 我用 C# 标记它,因为我相信它会在 ASP.NET 社区中吸引更广泛的受众。如果这是一个问题让我知道,我可以删除它(C# 是我的首选语言,但对于这个项目,我不得不用 VB 编写)。正在使用 VB.NET ASP.NET WebApi 编写 websocket 服务器。任何帮助将不胜感激。

我只想打开连接,保持打开状态,并从客户端向服务器发送快速字符串消息。我已将我的服务器代码缩减到尽可能简单的程度,并在下面 post 进行了完整介绍。


以下是我的服务器代码: 注意:我将注释从 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

握手成功:

When run, the handshake appears to be successful as this line is hit (as well as the constructor) and does not error:

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

The client side onOpen() function is hit, writing out the readystate which is 1. However the websocket immediately closes for some reason when the second line is hit in onOpen() (it jumps to the onClose() handler)

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

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

问题:

ChatWebSocketHandler.OnOpen() (see Server code at bottom) is never hit. In fact, none of the methods in that class (OnClose(), OnError(), etc) are ever hit except the constructor during the handshake. Why are these not hit?

请注意,如果我在 websocket.send() 行上放置断点,则在执行该行之前 readystate 仍为 1,并且 NOT 该行的错误,它只是跳转到 websocket.onClose() 事件...

提前感谢您的帮助!如果需要,我可以 post 更多客户端。

好吧,我终于想通了,当然这很愚蠢:)

显然,我在 SignalR 中引用 WebSocketHandler class 时犯了错误 - 它看起来不像是要在 SignalR 的内部操作之外使用的。

我的新代码非常相似,真正唯一的区别是继承的 websockethandler class 在 Microsoft.Web.Websockets 命名空间中。

另一个区别是这一行:

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

现在只是:

HttpContext.Current.AcceptWebSocketRequest(New ChatWebSocketHandler)

花了 2 天时间才到达那里,现在我和 PM 团队在狗窝里,因为我们很匆忙,但是嘿,终于到了那里。希望如果其他人点击了这个,他们不会像我一样被困在上面!