Reputation: 226
NOTE: I am tagging this with C# as I believe it will hit a wider audience in the ASP.NET community.. If this is an issue let me know and I can remove it (C# is my preferred language, but for this project I'm forced to write in VB). The websocket server is being written with VB.NET ASP.NET WebApi. Any help whatsoever would be appreciated.
I simply want to get the connection to open, remain open, and send a quick string message to the server from the client. I've reduced my server code to be as simple as possible, and posted in full below.
The following is my server code : NOTE: I changed comments from VB's "'" to C#'s "//", as it was displaying as strings in stack overflow's code blocks.
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
Successful Handshake:
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");
}
The Question:
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?
Note that, if I put a breakpoint on the websocket.send() line, the readystate is still 1 before the line is executed, and it does NOT error at that line, it simply jumps to the websocket.onClose() event...
Thank you in advance for the help! I can post more of the client side if needed.
Upvotes: 1
Views: 2099
Reputation: 226
Well I finally figured this out, and of course it was something stupid :)
Apparently, I made the mistake of referencing the WebSocketHandler class in SignalR - it does not look like that was meant to be used outside of SignalR's internal operations.
My new code is extremely similar, really the only difference is the websockethandler class inherited is in the Microsoft.Web.Websockets namespace.
One other difference, is this line:
HttpContext.Current.AcceptWebSocketRequest(Function() Tasks.Task.FromResult(New ChatWebSocketHandler()))
Now is just:
HttpContext.Current.AcceptWebSocketRequest(New ChatWebSocketHandler)
Took 2 days to get there and now I'm in the dog house with the PM team since we were in a hurry, but hey, got there finally. Hopefully if someone else hits this they wont be stuck on it as long as I was!
Upvotes: 2