ASP.NET MVC Websocket服务器(WebAPI)握手完成,但是OnOpen和其他事件函数没有被命中服务器端

时间:2016-10-12 20:14:50

标签: c# vb.net asp.net-web-api websocket system.net.websockets

注意: 我使用C#标记此内容,因为我相信它会在ASP.NET社区中吸引更广泛的受众。如果这是一个问题,请告诉我,我可以删除它(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()函数被命中,写出 readystate ,这是1.然而,当第二行被击中时,websocket会因某种原因立即关闭onOpen()(它跳转到 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()行放置一个断点,那么在执行该行之前,就绪状态仍为1,并且 NOT 错误在那一行,它只是跳转到 websocket.onClose()事件......

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

1 个答案:

答案 0 :(得分:2)

好吧,我终于弄明白了,当然这是愚蠢的事情:)。

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

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

另一个区别是,这一行:

HttpContext.Current.AcceptWebSocketRequest(New ChatWebSocketHandler)

现在只是:

{{1}}

花了2天时间到达那里,现在我和PM团队在狗屋里,因为我们很匆忙,但是,嘿,最后到了那里。希望如果有其他人点击它,他们就不会被卡在上面了!