Проблема сервера Websocket: onOpen ударил по стороне клиента, но обработчик веб-сокета сервера OnOpen и другие события не произошли

Я очень плохо знаком с веб-сокетами и WebAPI (наша система была полностью.NET MVC, но не WebAPI), поэтому я вполне могу просто упустить что-то очевидное (надеюсь).

Я пытаюсь реализовать простой клиент для игры. Я работаю в.NET в (к сожалению) VB, и я пытаюсь заставить веб-сокет работать, и поражать сервер событий OnOpen/Message/Close и клиентскую сторону.

Мой код ниже, но, короче говоря, рукопожатие websocket, кажется, происходит без каких-либо проблем, так как мое событие onOpen() в javascript получает удар, и когда я выводю readyState его 1. Однако OnOpen НЕ получает попадание на стороне сервера

Результат в конечном итоге выглядит так:

НЕМЕДЛЕННАЯ ГОТОВНОСТЬ: 0

ONOPEN READYSTATE: 1

Гнездо закрыто

В конструктор моего WebSocketHandler обращаются (например, если я выбрасываю точку останова в строке MyBase.New(), она попадает в нее). Однако OnOpen никогда не срабатывает, и сокет немедленно попадает в событие onclose в js. Что я должен сделать, чтобы оставить сокет открытым? Почему бы OnOpen не получить удар?

Мой код ниже:

Javascript:

var wsUri = 'ws://' + window.location.hostname + '/api/Chat?username=hello';
var output;

$(document).ready(function () {

  //setup and fire
  output = document.getElementById("output");
  testWebSocket();
})

function testWebSocket() {
  //Instantiate the websocket, hopefully opening it
  websocket = new WebSocket(wsUri);
  writeToScreen("IMMEDIATE READYSTATE: " + websocket.readyState);

  //bind event handlers
  websocket.onopen = function (evt) { onOpen(evt) };
  websocket.onclose = function (evt) { onClose(evt) };
  websocket.onmessage = function (evt) { onMessage(evt) };
  websocket.onerror = function (evt) { onError(evt) };
}

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

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

function onMessage(evt) {
  writeToScreen('RECEIVED: ' + evt.data);
}

function onError(evt) {
  writeToScreen('ERROR:' + evt.data);
}


function writeToScreen(message) {
  var messageToAppend = document.createElement("p");
  messageToAppend.style.wordWrap = "break-word";
  messageToAppend.innerHTML = '<span>' + message + '</span>';
  output.appendChild(messageToAppend);
}

Сервер:

Public Class ChatController
  Inherits ApiController

  Public Function [Get](username As String) As HttpResponseMessage

    If HttpContext.Current.IsWebSocketRequest Then
      HttpContext.Current.AcceptWebSocketRequest(Function() Tasks.Task.FromResult(New ChatWebSocketHandler(username)))
      Return Request.CreateResponse(HttpStatusCode.SwitchingProtocols)
    Else
      Return Request.CreateResponse(HttpStatusCode.BadRequest)
    End If
  End Function


  Private Class ChatWebSocketHandler
    Inherits Microsoft.Web.WebSockets.WebSocketHandler

    Public Sub New(username As String)

      MyBase.New()

      'Do stuff with username eventually.

    End Sub

    Public Overrides Sub OnOpen()
      Debug.WriteLine("Websocket is open")
    End Sub

    Public Overrides Sub OnMessage(message As String)
      Debug.WriteLine("Message Received: " & message)
    End Sub

    Public Overrides Sub OnClose()

      Debug.WriteLine("Websocket Closed")

      MyBase.OnClose()

    End Sub
  End Class

End Class

1 ответ

Решение

Если честно, я не могу сказать со 100% уверенностью, что это исправило, но у меня очень сильное подозрение.

Я включил слишком много пространств имен в свой код, и я считаю, что в компиляторе и т. Д. Была некоторая путаница, когда он действительно работал. Очевидно, и Microsoft.Web.Websockets, и пространства имен SignalR ОБА содержат WebSocketHandler. Хотя я не знаю всех входов и выходов SignalR, похоже, что WebSocketHandler в пространстве имен TH не предназначен для использования вне SignalR. Я полагаю, что на класс ссылались вместо того, что есть в Microsoft.Web.Websockets, как это работает сейчас, но я действительно не слишком изменился. Это также позволило мне напрямую вызвать конструктор, создав новый экземпляр обработчика, вместо того, чтобы вызывать его в лямбда-функции.

В любом случае, если у кого-то еще есть подобные проблемы, убедитесь, что вы ссылаетесь на правильный!

Другие вопросы по тегам