Должна быть возможность обрабатывать подключение к веб-сокету в классическом приложении ASP.NET Forms. Инструменты доступны на HttpContext
, и у вас в основном есть правильное представление.
Я думаю, проблема в том, что вы пытаетесь вызвать его со страницы aspx, а не просто используете общий файл IHttpHandler
. IIS запускает определенные конвейеры обработки на основе расширения файла. Aspx скорее специализируется на попытках отобразить HTML-страницу, поэтому, хотя можно перенастроить IIS, чтобы позволить веб-сокетам взаимодействовать со страницами ASPX, гораздо проще просто использовать общий ashx обработчик.
Вы можете создать обработчик, перейдя в диалоговое окно «Добавить элемент» в Visual Studio
На этом этапе вы просто реализуете логику веб-сокета в коде обработчика. Я добавляю простое эхо из этот пример aspnet просто для демонстрации.
public class MyHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(EchoWebSocket);
}
}
private async Task EchoWebSocket(AspNetWebSocketContext socketContext)
{
var buffer = new byte[1024 * 4];
var result = await socketContext.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
await socketContext.WebSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await socketContext.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await socketContext.WebSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
public bool IsReusable
{
get
{
return false;
}
}
}
Теперь вы должны иметь возможность подключиться к веб-сокету. Обратите внимание на использование wss
вместо ws
. Для настройки, которую я тестировал, требуется безопасная версия (wss). Используйте все, что имеет отношение к приложению, над которым вы работаете.
// Replace with port/path to your handler.
var ws = new WebSocket("wss://localhost:44336/MyHandler.ashx");
ws.onmessage = function(evt) {
console.log(evt);
};
ws.send("Hello, World!");
Вы должны увидеть примерно такой вывод: а>
Примечание. Обычно я не рекомендую пытаться получить доступ к данным сеанса из обработчика веб-сокетов. Срок действия вашего сеанса может истечь за пределами срока действия веб-сокета. Вы, вероятно, захотите использовать какой-то другой механизм для сохранения состояния между сокетом и остальными страницами (возможно, базу данных или кеш уровня приложения, к которому вы можете получить доступ из socketContext.Cache
в приведенном выше примере.
Изменить: добавлен пример использования значения сеанса при инициализации сокета. Согласно вашему комментарию, если вы хотите использовать значения сеанса во время инициализации веб-сокета (что должно быть безопасным операции), тогда ваш обработчик просто должен реализовать IRequiresSessionState
и добавить немного дополнительного синтаксиса для передачи значения сеанса в обработчик принятия.
public class MyHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
var sessionValue = context.Session["session_key"] as string;
context.AcceptWebSocketRequest(async (socketContext) =>
{
await SetupWebSocket(socketContext, sessionValue);
});
}
}
private async Task SetupWebSocket(AspNetWebSocketContext socketContext, string sessionValue)
{
// Handle socket as before, but 'sessionValue' is now available for use.
}
public bool IsReusable
{
get
{
return false;
}
}
}
person
cmcquillan
schedule
14.10.2020