Что такое код asp serverlistentimeout


Содержание

Серверные события

Объект XMLHttpRequest позволяет веб-странице задать серверу вопрос и получить на него немедленный ответ. Но это обмен типа «один к одному» — после предоставления сервером ответа данный сеанс взаимодействия завершается. Веб-сервер не может повременить несколько минут и отправить странице другое сообщение с обновленной информацией.

Но некоторые типы веб-страницы могли бы извлечь пользу из более длительных сеансов взаимодействия с сервером. Возьмем, например, страницу биржевых котировок на Google Finance. Если оставить это страницу открытой, то периодически мы будем видеть автоматическое обновление котировок. Подобным образом доставляются новые сообщения в ящик поступающих сообщений любой программы электронной почты с веб-интерфейсом.

Во всех этих примерах применяется метод, называющийся опросом (polling). Суть его состоит в том, что веб-страница периодически (например, каждые несколько минут) запрашивает у веб-сервера новые данные. Для реализации этого механизма обновления веб-страницы используется функция JavaScript setInterval() или setTimeout(), которая активирует код по истечении установленного периода времени.

Метод опроса является разумным решением, но иногда неэффективным. Во многих случаях это означает, что нужно вызывать веб-сервер и устанавливать новое подключение только для того, чтобы узнать, что ничего нового нет. Умножьте это на сотни или тысячи посетителей, обращающихся к веб-странице одновременно, и это может вылиться в ненужную нагрузку на ваш веб-сервер.

Одно из возможных решений этой проблемы — это использование , что позволяет удерживать открытым подключение к веб-серверу. Веб-сервер может отправлять странице сообщения в любое время, и при этом отсутствует необходимость постоянно отключаться и подключаться к серверу и исполнять один и тот же сценарий. (Но если в этом есть необходимость, то можно использовать и опрос, т.к. отправляемые сервером события поддерживают эту возможность.)

Лучшее этой технологии в том, с какой легкостью используется система отправляемых сервером событий, а также в том, что она работает на большинстве веб-хостов и исключительно надежная. Но это сравнительно новая система с соответствующим уровнем поддержки в браузерах:

Поддержка браузерами системы отправляемых сервером событий

Браузер IE Firefox Chrome Safari Opera Safari iOS Android
Минимальная версия 6 5 5 11 4 4

В последующих разделах мы создадим простой пример, демонстрирующий использование отправляемых сервером событий.

Формат сообщений

В отличие от объекта XMLHttpRequest, система отправляемых сервером событий не разрешает передавать данные в произвольном формате, а требует придерживаться простого, но установленного формата. Каждое сообщение должно начинаться текстом data:, за которым следует собственно текст сообщения, а в заключение — последовательность символов перехода на новую строку, которая во многих языках программирования состоит из символов \n\n.

Вот пример текста сообщения:

Сообщение разрешается разбить на несколько частей. Для этого используется последовательность символов окончания строки, которая часто состоит из одной пары \n. Это облегчает отправку сложных данных, наподобие следующих:

Обратите внимание, что каждую часть сообщения нужно начинать текстом data:, а все сообщение завершать признаком перехода на новую строку \n\n.

Этот метод можно использовать даже для отправки данных в формате JSON, что позволяет преобразовать текст в объект в один прием:

Вместе с данными сообщения веб-сервер может отправить однозначное идентифицирующее значение (используя префикс id:) и время тайм-аута для подключения (используя префикс retry:):

Веб-страница обращает внимание только на данные сообщения и игнорирует идентификатор сообщения и время тайм-аута. Этими подробностями занимается браузер. Например, прочитав предыдущее сообщение, браузер знает, если он потеряет подключение к веб-серверу, то должен попытаться подключиться повторно после 15 000 мс (т.е. 15 секунд). При повторном подключении браузер также должен отправить номер идентификатора 495, чтобы сервер мог его распознать.

Веб-страница может потерять подключение к веб-серверу по множеству разных причин, включая кратковременный сетевой сбой или истечение времени ожидания данных прокси-сервером. Если возможно, браузер будет пытаться восстановить подключение автоматически, выждав по умолчанию 3 секунды.

Отправка сообщений с помощью серверного сценария

Зная формат сообщений, мы можем с легкостью создать серверный код для их отправки. Опять же, для создания простого примера, который будет поддерживаться практически всеми веб-хостами, удобно использовать язык серверных сценариев PHP. На рисунке ниже показана страница, которая получает регулярные сообщения от сервера. В данном случае сообщения предназначены просто для демонстрационных целей и содержат лишь текущее время на веб-сервере:

Когда эта страница находится в режиме прослушивания, она получает постоянный поток сообщений от веб-сервера — приблизительно одно сообщение каждую секунду. Каждое сообщение добавляется в верх прокручиваемого списка, а табло внизу отображает время получения последнего сообщения.

Серверная часть этого примера просто информирует о текущем времени по регулярным интервалам. Весь код PHP для этого выглядит так:

В начале этого сценария устанавливаются два важных заголовка. Сначала MIME-типу присваивается значение text/event-stream, что требуется стандартом для отправляемых сервером событий. Потом веб-серверу (а также прокси-серверам) дается указание отключить кэширование. Если этого не сделать, то сообщения могут прибывать в пакетах по нерегулярным интервалам.

Обратите внимание, что в этом коде сообщение завершается константой PHP_EOL, которая представляет комбинацию символов \n, обозначающих конец строки.

Функция flush() обеспечивает немедленную отправку данных, а не помещение в буфер для отправки после завершения выполнения кода PHP. Функция sleep() приостанавливает исполнение кода на секунду, после чего начинает исполнение новой итерации цикла.

Обработка сообщений в веб-странице

Создание веб-страницы для обработки отправляемых сообщений даже проще, чем кода для отправки этих сообщений. Блок страницы разделяется на три блока

При загрузке страница находит элементы messageLog и timeDisplay и сохраняет их в глобальных переменных, что обеспечивает всем нашим функциям легкий доступ к ним:

Процесс отправки сообщений веб-сервером и получения их страницей начинается нажатием кнопки «Начать прослушивание». В это время код создает новый объект EventSource, предоставляя URL серверного ресурса, который будет отправлять сообщения. (В данном примере это PHP-сценарий server_events.php.) Потом к событию onMessage подключается функция receiveMessage, которая срабатывает при каждом получении сообщения страницей:

Обратите внимание, что из сообщения удалена вся служебная информация (текст data: и признак перехода на новую строку \n\n), и отображается только требуемое содержимое.

Наконец, прослушивание событий сервера страницей можно прекратить в любое время, вызвав метод close() объекта EventSource. Делается это так:

Опрос посредством серверных событий

В предыдущем примере мы рассмотрели наиболее простое использование системы серверных событий, которое, по большому счету, сводится к следующему: страница отправляет запрос, подключение остается открытым, и сервер периодически отправляет странице информацию. Браузеру может потребоваться выполнить повторное подключение (что он делает автоматически), но только в случае проблемы с подключением или же если оно было временно прервано по другим причинам (например, с целью экономии заряда батареи на мобильном устройстве).

Но что произойдет, если прекратится исполнение сценария на веб-сервере, и последний закроет подключение? Довольно интересно, хотя отключение выполняется не вследствие неполадок, а в результате целенаправленных действий веб-сервера, веб-страница автоматически возобновляет подключение (после ожидания, по умолчанию равному 3 секундам) и снова запрашивает данный сценарий, начиная его исполнение с самого начала.

Это поведение можно обернуть в свою пользу. Допустим, что мы создали сравнительно небольшой серверный сценарий, который отправляет только одно сообщение. Теперь действия веб-страницы похожи на действия при опросе в том, что она периодически восстанавливает подключение. Разница состоит лишь в том, что период между подключениями устанавливается веб-сервером, а не JavaScript-кодом страницы, как делается при использовании традиционного опроса.

В следующем примере используется комбинированный подход. Серверный сценарий удерживает подключение открытым и периодически отправляет сообщения в течение 1 минуты. Потом сценарий дает указание браузеру подключиться через 2 минуты и закрывает подключение:

Теперь при просмотре страницы мы будем получать регулярные сообщения в течение 1 минуты, после чего следует перерыв в 2 минуты, после чего процесс повторяется. В настоящем приложении при закрытии подключения веб-сервер может отправить браузеру специальное сообщение, информирующее, что больше нет причин ожидать обновленные данные (например, потому что фондовые биржи закрылись). Тогда веб-страница могла бы прекратить процесс, вызвав метод close() объекта EventSource.

В случае сложных серверных сценариев автоматическое повторное подключение браузера может работать не совсем так, как ожидалось. Например, подключение может быть прервано посредине исполнения веб-сервером какой-либо задачи. В таком случае серверный сценарий может отправить всем клиентам идентификатор, который браузер вернет серверу при повторном подключении. Но ответственность за создание подходящего идентификатора, отслеживание соответствия каждого идентификатора с его задачей (например, сохраняя определенную информацию в базе данных), а потом попытку возобновить процесс с того момента, когда он был прерван, лежит на серверном коде.

Server Sent Events

Спецификация Server-Sent Events описывает встроенный класс EventSource , который позволяет поддерживать соединение с сервером и получать от него события.

Как и в случае с WebSocket , соединение постоянно.

Но есть несколько важных различий:

WebSocket EventSource
Двунаправленность: и сервер, и клиент могут обмениваться сообщениями Однонаправленность: данные посылает только сервер
Бинарные и текстовые данные Только текст
Протокол WebSocket Обычный HTTP

EventSource не настолько мощный способ коммуникации с сервером, как WebSocket .

Зачем нам его использовать?

Основная причина: он проще. Многим приложениям не требуется вся мощь WebSocket .

Если нам нужно получать поток данных с сервера: неважно, сообщения в чате или же цены для магазина – с этим легко справится EventSource . К тому же, он поддерживает автоматическое переподключение при потере соединения, которое, используя WebSocket , нам бы пришлось реализовывать самим. Кроме того, используется старый добрый HTTP, а не новый протокол.

Получение сообщений

Чтобы начать получать данные, нам нужно просто создать new EventSource(url) .

Браузер установит соединение с url и будет поддерживать его открытым, ожидая события.

Сервер должен ответить со статусом 200 и заголовком Content-Type: text/event-stream , затем он должен поддерживать соединение открытым и отправлять сообщения в особом формате:

  • Текст сообщения указывается после data: , пробел после двоеточия необязателен.
  • Сообщения разделяются двойным переносом строки \n\n .
  • Чтобы разделить сообщение на несколько строк, мы можем отправить несколько data: подряд (третье сообщение).

На практике сложные сообщения обычно отправляются в формате JSON, в котором перевод строки кодируется как \n , так что в разделении сообщения на несколько строк обычно нет нужды.

…Так что можно считать, что в каждом data: содержится ровно одно сообщение.

Для каждого сообщения генерируется событие message :

Кросс-доменные запросы

EventSource , как и fetch , поддерживает кросс-доменные запросы. Мы можем использовать любой URL:

Сервер получит заголовок Origin и должен будет ответить с заголовком Access-Control-Allow-Origin .

Чтобы послать авторизационные данные, следует установить дополнительную опцию withCredentials :

Более подробное описание кросс-доменных заголовков вы можете прочитать в главе Fetch: запросы на другие сайты.

Переподключение

После создания new EventSource подключается к серверу и, если соединение обрывается, – переподключается.

Это очень удобно, так как нам не приходится беспокоиться об этом.

По умолчанию между попытками возобновить соединение будет небольшая пауза в несколько секунд.

Сервер может выставить рекомендуемую задержку, указав в ответе retry: (в миллисекундах):

Поле retry: может посылаться как вместе с данными, так и отдельным сообщением.

Браузеру следует ждать именно столько миллисекунд перед новой попыткой подключения. Или дольше, например, если браузер знает (от операционной системы) что соединения с сетью нет, то он может осуществить переподключение только когда оно появится.

  • Если сервер хочет остановить попытки переподключения, он должен ответить со статусом 204.
  • Если браузер хочет прекратить соединение, он может вызвать eventSource.close() :

Также переподключение не произойдёт, если в ответе указан неверный Content-Type или его статус отличается от 301, 307, 200 и 204. Браузер создаст событие «error» и не будет восстанавливать соединение.

После того как соединение окончательно закрыто, «переоткрыть» его уже нельзя. Если необходимо снова подключиться, просто создайте новый EventSource .

Идентификатор сообщения

Когда соединение прерывается из-за проблем с сетью, ни сервер, ни клиент не могут быть уверены в том, какие сообщения были доставлены, а какие – нет.

Чтобы правильно возобновить подключение, каждое сообщение должно иметь поле id :

Получая сообщение с указанным id: , браузер:

  • Установит его значение свойству eventSource.lastEventId .
  • При переподключении отправит заголовок Last-Event-ID с этим id , чтобы сервер мог переслать последующие сообщения.

Обратите внимание: id указывается сервером после данных data сообщения, чтобы обновление lastEventId произошло после того, как сообщение будет получено.

Статус подключения: readyState

У объекта EventSource есть свойство readyState , имеющее одно из трёх значений:

При создании объекта и разрыве соединения оно автоматически устанавливается в значение EventSource.CONNECTING (равно 0 ).

Мы можем обратиться к этому свойству, чтобы узнать текущее состояние EventSource .

Типы событий

По умолчанию объект EventSource генерирует 3 события:

  • message – получено сообщение, доступно как event.data .
  • open – соединение открыто.
  • error – не удалось установить соединение, например, сервер вернул статус 500.

Сервер может указать другой тип события с помощью event: . в начале сообщения.

Чтобы начать слушать пользователькие события, нужно использовать addEventListener , а не onmessage :

Полный пример

В этом примере сервер посылает сообщения 1 , 2 , 3 , затем пока-пока и разрывает соединение.

После этого браузер автоматически переподключается.

Учебник. Начало работы с Entity Framework 6 Code First с помощью MVC 5 Tutorial: Get Started with Entity Framework 6 Code First using MVC 5

Для разработки новых приложений мы рекомендуем ASP.NET Core Razor Pages по ASP.NET MVC контроллеры и представления. For new development, we recommend ASP.NET Core Razor Pages over ASP.NET MVC controllers and views. Для следующего вида серии руководств см. в разделе с помощью Razor Pages, руководства: Начало работы с Razor Pages в ASP.NET Core. For a tutorial series similar to this one using Razor Pages, see Tutorial: Get started with Razor Pages in ASP.NET Core. Новый учебник. The new tutorial:

  • проще для выполнения; Is easier to follow.
  • содержит больше рекомендаций по EF Core; Provides more EF Core best practices.
  • использует более эффективные запросы; Uses more efficient queries.
  • более актуально, так как используются новейшие API; Is more current with the latest API.
  • охватывает дополнительные возможности; Covers more features.
  • является предпочтительным подходом для разработки новых приложений. Is the preferred approach for new application development.

В этой серии руководств вы узнаете, как создать приложение ASP.NET MVC 5, использующий Entity Framework 6 для доступа к данным. In this series of tutorials, you learn how to build an ASP.NET MVC 5 application that uses Entity Framework 6 for data access. В этом учебнике используется Code First рабочего процесса. This tutorial uses the Code First workflow. Сведения о том, как выбрать Code First, Database First или Model First, см. в разделе создать модель. For information about how to choose between Code First, Database First, and Model First, see Create a model.

В этой серии руководств описывается построение примера приложения университета Contoso. This tutorial series explains how to build the Contoso University sample application. Пример приложения веб-сайт простой университета. The sample application is a simple university website. С ним вы можете просматривать и обновлять учащихся, курсах и сведения о преподавателе. With it, you can view and update student, course, and instructor information. Ниже приведены два созданных экранов. Here are two of the screens you create:

В этом учебнике рассмотрены следующие задачи. In this tutorial, you:

  • Создать веб-приложение MVC Create an MVC web app
  • Настройка стиля сайта Set up the site style
  • Установка Entity Framework 6 Install Entity Framework 6
  • Создание модели данных Create the data model
  • Создание контекста базы данных Create the database context
  • Инициализация базы данных с тестовыми данными Initialize DB with test data
  • Настройка EF 6 для использования LocalDB Set up EF 6 to use LocalDB
  • Создание контроллера и представлений Create controller and views
  • Просмотр базы данных View the database

Предварительные требования Prerequisites

Создать веб-приложение MVC Create an MVC web app

Откройте Visual Studio и создайте C# веб-проекта с помощью веб-приложение ASP.NET (.NET Framework) шаблона. Open Visual Studio and create a C# web project using the ASP.NET Web Application (.NET Framework) template. Назовите проект ContosoUniversity и выберите ОК. Name the project ContosoUniversity and select OK.

В новый веб-приложение ASP.NET — ContosoUniversityвыберите MVC. In New ASP.NET Web Application — ContosoUniversity, select MVC.

По умолчанию проверки подлинности параметру присваивается без проверки подлинности. By default, the Authentication option is set to No Authentication. В этом учебнике веб-приложение не требует пользователи выполняли вход. For this tutorial, the web app doesn’t require users to sign in. Кроме того он не ограничивает доступ, в зависимости от того, кто выполнил вход. Also, it doesn’t restrict access based on who’s signed in.

Нажмите кнопку ОК, чтобы создать проект. Select OK to create the project.

Настройка стиля сайта Set up the site style

Выполните незначительную настройку меню, макета и домашней страницы сайта. A few simple changes will set up the site menu, layout, and home page.

Откройте Views\Shared\_Layout.cshtmlи внесите следующие изменения: Open Views\Shared\_Layout.cshtml, and make the following changes:

  • Замените все вхождения «My ASP.NET Application» и «Имя приложения» на «Contoso University». Change each occurrence of «My ASP.NET Application» and «Application name» to «Contoso University».
  • Добавление пунктов меню для учащихся, курсов, преподавателей и отделов и удалите запись контакта. Add menu entries for Students, Courses, Instructors, and Departments, and delete the Contact entry.

Изменения выделены в следующем фрагменте кода: The changes are highlighted in the following code snippet:

В Views\Home\Index.cshtml, замените содержимое файла следующим кодом, который заменяет текст о ASP.NET и MVC об этом приложении: In Views\Home\Index.cshtml, replace the contents of the file with the following code to replace the text about ASP.NET and MVC with text about this application:

Нажмите клавиши Ctrl + F5 для запуска веб-сайта. Press Ctrl+F5 to run the web site. Появится домашняя страница с меню. You see the home page with the main menu.

Установка Entity Framework 6 Install Entity Framework 6

Из средства меню, выберите диспетчер пакетов NuGet, а затем выберите консоль диспетчера пакетов. From the Tools menu, choose NuGet Package Manager, and then choose Package Manager Console.

В консоль диспетчера пакетов окно, введите следующую команду: In the Package Manager Console window, enter the following command:

Этот шаг является одним из нескольких шагов с учебником можно сделать вручную, но, могло быть сделано автоматически с помощью функции формирования шаблонов ASP.NET MVC. This step is one of a few steps that this tutorial has you do manually, but that could have been done automatically by the ASP.NET MVC scaffolding feature. Вы выполняете их вручную, чтобы вы могли видеть шаги, необходимые для использования Entity Framework (EF). You’re doing them manually so that you can see the steps required to use Entity Framework (EF). Вы воспользуетесь формирования шаблонов позже для создания контроллера и представлений MVC. You’ll use scaffolding later to create the MVC controller and views. Альтернативным вариантом является для формирования шаблонов автоматически установить пакет EF NuGet создать класс контекста базы данных и создания строки подключения. An alternative is to let scaffolding automatically install the EF NuGet package, create the database context class, and create the connection string. Когда вы будете готовы сделать это таким образом, что необходимо сделать всего лишь пропустить эти шаги и сформировать шаблон контроллера MVC после создания классов сущностей. When you’re ready to do it that way, all you have to do is skip those steps and scaffold your MVC controller after you create your entity classes.

Создание модели данных Create the data model

Теперь необходимо создать классы сущностей для приложения университета Contoso. Next you’ll create entity classes for the Contoso University application. Сначала вы возьмете следующих трех сущностей: You’ll start with the following three entities:

Курс регистрации учащегося Course Enrollment Student

Сущности Entities Relationship Relationship
Курс для регистрации Course to Enrollment один ко многим One-to-many
Учащегося для регистрации Student to Enrollment один ко многим One-to-many

Между сущностями Student и Enrollment , а также между сущностями Course и Enrollment существует отношение «один ко многим». There’s a one-to-many relationship between Student and Enrollment entities, and there’s a one-to-many relationship between Course and Enrollment entities. Другими словами, учащийся может быть зарегистрирован в любом количестве курсов, а в отдельном курсе может быть зарегистрировано любое количество учащихся. In other words, a student can be enrolled in any number of courses, and a course can have any number of students enrolled in it.

В следующих разделах вы создадите класс для каждого из этих сущностей. In the following sections, you’ll create a class for each one of these entities.

При попытке компиляции проекта до завершения создания всех этих классов сущностей, вы получите ошибки компилятора. If you try to compile the project before you finish creating all of these entity classes, you’ll get compiler errors.

Сущность Student The Student entity

В моделей папке создайте файл класса с именем Student.cs щелкнув правой кнопкой папку, в обозревателе решений и выбрав добавить > Класс. In the Models folder, create a class file named Student.cs by right-clicking on the folder in Solution Explorer and choosing Add > Class. Замените код шаблона следующим кодом: Replace the template code with the following code:

Свойство ID будет использоваться в качестве столбца первичного ключа в таблице базы данных, соответствующей этому классу. The ID property will become the primary key column of the database table that corresponds to this class. По умолчанию Entity Framework интерпретирует свойство с именем ID или classname ID как первичный ключ. By default, Entity Framework interprets a property that’s named ID or classname ID as the primary key.

Свойство Enrollments является свойством навигации. The Enrollments property is a navigation property. Свойства навигации содержат другие сущности, связанные с этой сущностью. Navigation properties hold other entities that are related to this entity. В этом случае Enrollments свойство Student сущность будет содержать все Enrollment сущностей, которые связаны Student сущности. In this case, the Enrollments property of a Student entity will hold all of the Enrollment entities that are related to that Student entity. Другими словами если заданный Student строк в базе данных имеет два связанных Enrollment строк (значение строки, которые содержат первичный ключ этого учащегося в их StudentID внешний ключевой столбец), в котором Student сущности Enrollments свойство навигации будет содержать две этих Enrollment сущностей. In other words, if a given Student row in the database has two related Enrollment rows (rows that contain that student’s primary key value in their StudentID foreign key column), that Student entity’s Enrollments navigation property will contain those two Enrollment entities.

Свойства навигации, обычно определяются как virtual таким образом, чтобы они можно воспользоваться преимуществами определенные функциональные возможности Entity Framework, такие как отложенная загрузка. Navigation properties are typically defined as virtual so that they can take advantage of certain Entity Framework functionality such as lazy loading. (Отложенная загрузка, будет рассматриваться далее в чтение связанных данных далее в этой серии руководств.) (Lazy loading will be explained later, in the Reading Related Data tutorial later in this series.)

Если свойство навигации может содержать несколько сущностей (как в отношениях «многие ко многим» или «один ко многим»), оно должно иметь тип списка, допускающий добавление, удаление и обновление записей, такой как ICollection . If a navigation property can hold multiple entities (as in many-to-many or one-to-many relationships), its type must be a list in which entries can be added, deleted, and updated, such as ICollection .

Сущность Enrollment The Enrollment entity

В папке Models создайте файл Enrollment.cs и замените существующий код следующим кодом: In the Models folder, create Enrollment.cs and replace the existing code with the following code:

EnrollmentID Свойство будет иметь первичный ключ; эта сущность использует classname ID шаблонов вместо ID , как вы видели в Student сущности. The EnrollmentID property will be the primary key; this entity uses the classname ID pattern instead of ID by itself as you saw in the Student entity. Как правило, следует выбирать один шаблон, который будет использоваться в рамках всей модели данных. Ordinarily you would choose one pattern and use it throughout your data model. В этом случае демонстрируется возможность использования любого из шаблонов. Here, the variation illustrates that you can use either pattern. В этом руководстве, вы увидите как с помощью ID без classname позволяет упростить реализацию наследования в модели данных. In a later tutorial, you’ll see how using ID without classname makes it easier to implement inheritance in the data model.

Grade Свойство перечисления. The Grade property is an enum. Знак вопроса после Grade объявление типа указывает, что Grade свойство допускает значения NULL. The question mark after the Grade type declaration indicates that the Grade property is nullable. Корпоративного класса, который имеет значение null отличается от нулевой оценки тем — значение null означает, что это оценка не известна или еще не назначена. A grade that’s null is different from a zero grade — null means a grade isn’t known or hasn’t been assigned yet.

Свойство StudentID представляет собой внешний ключ. Ему соответствует свойство навигации Student . The StudentID property is a foreign key, and the corresponding navigation property is Student . Сущность Enrollment связана с одной сущностью Student , поэтому это свойство может содержать одну сущность Student (в отличие от представленного ранее свойства навигации Student.Enrollments , которое может содержать несколько сущностей Enrollment ). An Enrollment entity is associated with one Student entity, so the property can only hold a single Student entity (unlike the Student.Enrollments navigation property you saw earlier, which can hold multiple Enrollment entities).

Свойство CourseID представляет собой внешний ключ. Ему соответствует свойство навигации Course . The CourseID property is a foreign key, and the corresponding navigation property is Course . Сущность Enrollment связана с одной сущностью Course . An Enrollment entity is associated with one Course entity.

Платформа Entity Framework интерпретирует свойство как свойство внешнего ключа, если оно имеет имя (например, StudentID для Student свойство навигации с момента Student — первичный ключ сущности ID ). Entity Framework interprets a property as a foreign key property if it’s named

Server-Sent Events — сервер тебя не оставит

В этом отношении новая технология Server-Sent Events, с одной стороны, является логическим развитием схемы Long Polling, с другой — эта схема организована принципиально по-другому.

В основе идеи Server-Sent Events лежит очень простая модель взаимодействия. Клиент, воплощенный веб-страницей, открытой в браузере, подписывается на определенные события сервера и, как только таковые случаются, сразу же получает данные, сгенерированные этим событием. Все и вправду настолько просто, что странно, что этого не придумали раньше. Впрочем, саму идею Server-Sent Events выдвинул девять лет назад Йен Хиксон (Ian Hickson, разработчик синтетического теста браузеров на соответствие веб-стандартам Acid, сейчас в Google), но воплощение в браузерах она нашла относительно недавно (в Firefox начиная с 6-й версии, Opera — с 10.6, Chrome — с 5-й, Safari — с 4-й).

Для реализации Server-Sent Events на стороне клиента необходимо задействовать новый объект — EventSource — и привязать к нему обработку ответа. Делается это следующим образом:

В данном случае события должны происходить в серверном сценарии test_sse. php, лежащем в корне нашего веб-сервера. Согласно спецификации Server-Sent Events, данные от сервера должны поступать с особым значением Content-type — text/event-stream.

Разумеется, просто указать Content-type мало, неплохо было бы, чтобы и данные этому типу соответствовали. Для этого сервер должен посылать их в следующем виде:

Id: 12345n retry: 100n data: first linen data: second linen data: last linen n

Поле id не является обязательным. Оно идентифицирует сообщение на случай сбоя связи. В случае подобной неприятности клиент вышлет специальный заголовок — Last-Event-ID, для возобновления взаимодействия с последнего доставленного сообщения. Поле retry содержит время переподключения (retry) в случае ошибок. Оно тоже не является обязательным. Сейчас мы напишем минимальную реальную реализацию скрипта test_sse. php для приведенного ранее клиентского кода:

Открытие соединения с БД SQL выдает ошибку

Товарищи, помогите плиз!

Попробовал в АСП сделать то же что я делаю в Винформс, но увы не получается, выдает следующее исключение

Вкратце разъясню.
Я пытаюсь выполнить событие повешенное на клик кнопки (асп контрола).
Схема проста, на странице находиться 2 текстбокса с именами txbx_login и txbx_pass а так же кнопка и 3-й тексарея (text_rezultat), который должен отражать события при правильном или неправильном доступе.
Далее нижеследующий код на событие КЛИКА кнопки

Не могу понять что происходит, и базу подцепил в SQL data source и менял разные базы.
Выдает эту ошибку на строке

Комментарий модератора
Большие участки кода и текста желательно сворачивать в елемент вставки
15.01.2012, 17:56

SQL запрос выдает ошибку: Неправильный синтаксис около конструкции «=»
SqlDataAdapter DBCommand; DBCommand = new SqlDataAdapter(«Select ItemName, MinimumBld, OpenDate.

Повторное открытие формы выдает ошибку доступа к ликвидированному объекту
Добрый вечер всем! Раньше я работал в C++ Builder и использовал метод Close() для своих форм.

SQL ошибку выдает
Dim strSql As String strSql = «update request set = » & numberOfRequest & «#» &.

SQL.Delphi. Выдает ошибку
procedure TForm1.Button17Click(Sender: TObject); begin frmdm.ADOQuery1.SQL.Text:=’Insert Into.

Подключение к SQL Server выдает ошибку
Раньше все хранилось в бд Access, работало идеально. теперь переходим на SQL Server и сразу.

21.01.2012, 14:29 [ТС] 41 21.01.2012, 14:56 42

Если используете Win авторизацию, попробуйте добавить с троку:

21.01.2012, 15:07 [ТС] 43

Спасибо господа! трастед конекшен реально помогло.

Все вношу всю инфу в эвринот, от греха подальше.

07.02.2012, 13:09 [ТС] 44

ребят, вы меня конечно простите, «инвалида ума», но я так больше не могу!

Я вынужден вернуться к данной теме в связи с тем что она не является для меня закрытой на сегодняшний день!
Точнее закрыта она частично как-то, а по большому счету нифига не закрыта.

Как вы помните, ранее я отписал, что при ручном прописывании в строку подключения предложенную господином slawek фразы Trusted_Connection=True; соединение не артачилось и выполняло поставленную в выше описываемом коде задачу.

Однако тупость заключается в том, что при попытке наладить аутентификацию по средствам АСП.НЕТ, я столкнулся таки с этой проблемой опять. И столкнулся уже в aspnet_regsql.exe, он напрочь отказывался соединяться с любой предложенной ему БД, созданной в режиме SQL менеджмент студии или VS 2010.
При этом выдавая ту же проблему — ссылается на отсутствующий экземпляр или подключение.

Меня это взбесило жутко, я пошел и установил на второй комп XP и заново поставил MS SQL 2008 Express и Вижуал Студию 2010. В итоге получил тоже самое.
При этом галочка «разрешить удаленные подключения» в свойствах сервера установлена.

Я как-то понять не могу, неужели я сталкиваюсь с такими проблемами по умолчанию. Я что установку СКУЛ не так делаю, хотя вроде с этого форума взята из FAQa Бурундука.

Почему эта дура не хочет дружить со мной или может моя голова не хочет дружить со мной. В общем в том или другом случае надо разобраться, где источник проблем и избавиться от него раз и навсегда.

Может мне кто-то перечислит свои рабочие настройки, во всевозможных местах настройки SQL Express и IIS.
Я реально стою на месте. решения так и нет. Все книги, и мануалы прокурены до дыр.

Создание серверных компонентов для ASP-приложений

ASP (Active Server Pages) — технология создания Web-страниц, содержащих код, выполняемый Web-сервером (подробнее об истории и современном состоянии этой технологии см. в статье Алексея Федорова «Технология ASP+», № 9’2000, а о практических вопросах применения ASP см. в цикле статей Рубена Садояна , № 9-11’2000. — Прим. ред.). Современная версия данной технологии позволяет использовать в ASP-страницах сторонние серверные компоненты, созданию которых и посвящена данная статья.

В качестве средства разработки ASP-объектов будет использоваться Borland Delphi 5, Enterprise-версия которого позволяет это делать. К сожалению, в документации, поставляемой с Delphi 5, крайне скупо сказано о назначении, последовательности создания и тестирования серверных объектов ASP; кроме того в комплекте поставки Delphi 5 отсутствуют примеры работающих ASP-объектов. Настоящая публикация частично восполняет эти пробелы.

Клиентское приложение, использующее ASP-объекты, представляет собой HTML-документ (этот документ может также включать клиентский и серверный коды на скриптовых языках. — Прим. ред.), который в принципе можно прочесть с помощью любого Web-браузера. Обычно такие HTML-документы размещаются на каком-либо Web-сервере (как правило, это Microsoft Internet Information Server версии 3.0 и выше). Web-сервер, получив требование о предоставлении документа, считывает его из локального хранилища и передает клиенту, при этом часть информации вносится в документ Web-сервером динамически; сам же Web-сервер может обращаться к ASP-объектам, входящим в комплект поставки Internet Information Server или созданным сторонними разработчиками. Обычно Web-документы, содержащие обращения к ASP-объектам, имеют расширение *.asp. Примеры подобных документов можно найти в каталогах, создаваемых при установке Internet Information Server.

Некоторые Web-дизайнеры полагают, что технология ASP заключается, грубо говоря, в замене расширения *.htm в HTML-файле на расширение *.asp. Действительно, при работе с Internet Information Server изменение расширения файла позволит корректно отображать находящийся в нем HTML-документ. Однако на самом деле технология ASP — это обращение к методам специальных объектов, называемых ASP-объектами и представляющих собой COM-серверы. Типичный пример обращения к ASP-серверу из HTML-документа, представляющий собой фрагмент кода на языке VBScript, выглядит следующим образом:

Несмотря на наличие кода на скриптовых языках (VBScript или JavaScript), ASP-страница может быть доступна клиентам, работающим в других операционных системах, например в UNIX. На первый взгляд это может показаться странным, поскольку UNIX-компьютеры не используют ни Basic, ни тем более VBScript. Но дело в том, что скрипты, содержащиеся в ASP-документах, выполняются на сервере, а клиент получает HTML-документ, который является результатом выполнения этого скрипта.

Серверные объекты ASP выполняются в адресном пространстве Internet Information Server (Internet Information Services), работающего под управлением операционной системы Windows NT (Windows 2000) либо Windows 98.

По существу ASP-сервер представляет собой сервер автоматизации, в котором предопределено несколько интерфейсов; среди них — IRequest и IResponse. Интерфейс IRequest содержит методы, вызов которых позволяет передать параметры, введенные пользователем и заполненные на клиенте (об этом будет рассказано ниже). IResponse содержит методы, вызов которых приводит к формированию HTML-документа и передаче данного документа пользователю. Наличие этих признаков делает ASP-сервер похожим на CGI-приложения и ISAPI/NSAPI DLLl (далее — Web-приложения). Идеология выполнения методов в ASP-объекте и Web-приложениях также аналогична: сначала анализируется запрос клиента, затем динамически формируется отклик. Различие заключается в том, что Web-приложения формируют HTML-документ целиком, в то время как отклик ASP-объекта вставляется в исходную HTML-страницу. Например, если документ ASP представлен в виде:

и результат выполнения метода ScriptContent возвращает строку ‘First call to ASP server’, то пользователь, получивший данный документ, увидит следующее (рис. 1).

Иными словами, отклик ASP-объекта добавляется к HTML-документу. В одном документе допустимо обращение к нескольким ASP-объектам, и результат их отклика формируется в единый документ — этого невозможно достичь при использовании Web-приложений. Впрочем, имеется одно ограничение: набор ASP-серверов, к которым производится обращение из одного документа, должен быть зарегистрирован на одном и том же Internet Information Server — нельзя обращаться по различным адресам для формирования одного HTML-документа.

Как было сказано выше, Enterprise-версия Delphi 5 содержит эксперт для создания ASP-объектов. Для запуска этого эксперта следует выбрать пункт главного меню File|New среды разработки Delphi, а затем со страницы ActiveX репозитария объектов — пиктограмму Active Server Object.

ASP-сервер, содержащий ASP-объекты, реализуется в виде как исполняемых файлов *.exe, так и библиотек *.dll — это разрешается при создании серверов автоматизации. ASP-сервер, реализованный в виде исполняемого файла, запускается каждый раз в ответ на запрос клиента. При использовании внутренних (in-process) ASP-серверов, выполненных в виде динамически загружаемых библиотек, один экземпляр DLL, загруженный в адресное пространство Internet Information Server, способен обслуживать одновременно нескольких клиентов. При этом возможно либо создание отдельного экземпляра COM-объекта для каждого клиента, либо обслуживание нескольких клиентов единственным экземпляром COM-объекта. Это зависит от модели работы в потоках (Threading Model), выбранной при заполнении диалога, который появляется при запуске эксперта создания ASP-объектов.

Рассмотрим теперь, каким образом работает ASP-сервер на конкретном примере создания внутреннего (in-process) ASP-сервера. Для простоты ограничимся сервером, который выполняет один запрос. Итак, выберем пункт главного меню File|New среды разработки Delphi, со страницы ActiveX репозитария объектов — пиктограмму ActiveX Library и нажмем кнопку OK. В итоге получим новый проект, который сохраним, например, под именем ASP01. Теперь снова выберем пункт главного меню File|New среды разработки Delphi, со страницы ActiveX репозитария объектов — пиктограмму Active Server Object. В появившемся диалоге определим имя будущего COM-класса, например Test.

Поскольку мы создаем in-process-сервер, параметр Instancing не имеет значения — он важен только для исполняемых файлов. Зато в данном случае серьезную роль играет параметр Threading Model. При значении этого параметра равным Single работа сервера неэффективна, поскольку при одновременном обращении к нему нескольких клиентов сервер выполняет запросы последовательно, и если один из клиентов обращается с длительным запросом, то остальные вынуждены ожидать его окончания, даже если их запросы не требуют большого количества времени для выполнения. При этом у пользователей создается впечатление «зависания» браузера, что зачастую приводит к попыткам разными методами прервать задачу. Значение Apartment приводит к разделению запросов клиентов по потокам, причем для каждого клиента будет создан свой экземпляр COM-объекта, в данном примере — класса TTest. При этом при написании методов COM-класса не требуется защиты переменных класса внутри потоков — клиент может свободно модифицировать их, что упрощает разработку кода приложения. Недостаток данной модели состоит в следующем: проект оказывается ресурсоемким и переменные класса инициализируются при каждом обращении, что увеличивает время отклика на запрос. Этих недостатков лишена модель Free, в которой единственный экземпляр COM-объекта обслуживает нескольких клиентов. Однако возможность изменения данных внутри COM-объекта влечет за собой необходимость защиты общих переменных от их изменений из разных потоков, что существенно усложняет процедуру реализации кода приложения и является потенциальным источником трудноуловимых ошибок. Как правило, эту модель используют в ASP-серверах, которые только предоставляют данные, но не позволяют клиенту их модифицировать.

Группа элементов управления Active Server Type дает возможность выбрать назначение ASP-сервера. Если сервер планируется использовать под управлением Internet Information Server версий 3 или 4, то выбирается опция Page Level Events Methods. Объекты, созданные с применением этой опции, можно будет использовать и с Internet Information Services 5.0, но в этом случае опция Object Context позволит создать объект, работающий более эффективно. Эту же опцию следует выбирать, если работой ASP-сервера управляет Microsoft Transaction Server (Windows NT) или Component Services (Windows 2000). Фактически Internet Information Services 5.0 также управляет этим сервером при помощи Component Services, так как оба этих продукта тесно интегрированы.

Опцию Generate a Template Test Script for this object следует оставлять всегда включенной. В этом случае Delphi создаст небольшой HTML-документ, который можно использовать для тестирования ASP-сервера.

Заполнив опции диалога, необходимо нажать кнопку OK, после чего будет создан файл реализации интерфейсов Unit1.pas, который следует сохранить (например, под именем U1_01). Кроме того, будет создана библиотека типов, появятся ее редактор и файл, описывающий библиотеку типов, в данном примере — TEST_TLB.pas.

Если была выбрана опция Page Level Events Methods (как в нашем примере), то библиотека типов будет содержать два предопределенных метода — OnStartPage и OnEndPage. Также будет создан файл Test.asp, который содержит HTML-документ с заготовками на языке VBScript для тестирования сервера. Если заглянуть в файл реализации (U1_01.pas) , то можно увидеть, что класс ТТest является потомком класса TASPObject.

Если была выбрана опция Object Context, библиотека типов не будет содержать предопределенных методов, а сам класс Ttest будет являться потомком класса TASPMTSObject. Оба класса-предка TTest содержат абсолютно одинаковые методы и свойства, но класс TASPObject дополнительно содержит пару методов интерфейса IASPObject — OnStartPage и OnEndPage.

Далее создадим метод, который будет заполнять HTML-документ. Для этого в редакторе библиотеки типов (рис. 2) отметим интерфейс ITest и вызовем команду New Method нажатием кнопки 1.

Назовем вновь созданный метод ScriptContent, отредактировав его название, заданное по умолчанию. Данный метод не должен иметь параметров. Затем вызовем команду Refresh нажатием кнопки 2. После этого в модуле реализации (U1_01.pas) появится заготовка, где следует описать реализацию. Метод реализуем следующим образом:

В данном примере происходит обращение к методу Write интерфейса IResponse. Проверка Assigned(Response) гарантирует, что в момент записи сообщений имеется ссылка на интерфейс.

После этого следует модифицировать созданный Delphi HTML-документ для тестирования сервера, хранящегося в файле Test.asp. В этом документе имеется следующий фрагмент кода на языке VBScript:

В таком виде этот скрипт работать не будет. Необходимо заменить фразу в фигурных скобках на имя метода ASP-сервера, который генерирует отклик. В нашем примере это имя ScriptContent. Исправленный фрагмент выглядит следующим образом:

Теперь наш проект необходимо скомпилировать, после чего можно приступить к тестированию созданного ASP-объекта. Для этого необходимо создать виртуальную директорию Internet Information Server, которая обязана иметь разрешение как на чтение (из нее будут читаться данные), так и на выполнениe (из нее будет загружена и запущена библиотека ASP01.dll). Альтернатива — разместить эти файлы в разных директориях, одна из которых имеет доступ Read, а вторая — Execute. Однако в любом случае выбранные директории должны быть доступны с помощью протокола HTTP. Поэтому в первую очередь необходимо обратиться к WWW-сервису Internet Information Server, посмотреть список доступных директорий и при необходимости создать новые с соответствующими правами доступа.

В нашем примере на компьютере, который имеет IP-адрес 10.10.10.65, была создана виртуальная директория /Test, имеющая права доступа Read и Execute и соответствующая физическому адресу на компьютере C:\ASPTest. В эту директорию были скопированы оба файла. Далее в Microsoft Internet Explorer в поле Address был введен следующий URL: HTTP://10.10.10.65/Test/Test.asp. Результат выполнения этого запроса показан на рис. 1. Видно, что скрипт (текст между ) был замещен результатом выполнения метода ScriptContent созданного нами ASP-объекта.

Теперь подробнее рассмотрим, каким образом выполняется скрипт на странице Test.asp. Internet Information Server, получающий запрос о показе этой страницы, считывает ее содержимое, находит скрипт и выполняет его. При этом запускается интерпретатор VBScript и вызывается команда CreateObject. В случае если ASP01.dll ранее не была загружена, происходит ее загрузка. Для данного запроса создается COM-объект — экземпляр класса TTest (он описан в модуле реализации, для данного примера — U1_01.pas). Ссылка на интерфейс IDispatch (он поддерживается в классе TTest) сохраняется в переменной DelphiASPObj.

При последующем написании кода после имени переменной, хранящей ссылку на интерфейс IDispatch, можно набирать практически любой текст. Интерпретатор VBScript использует текст, который содержится в скрипте и следует после имени переменной (в нашем примере: переменная — DelphiASPObj, метод — .ScriptContent), для того чтобы передать его ASP-серверу. Если ASP-сервер найдет метод с данным именем, он его выполнит. В противном случае генерируется исключение. Поэтому при написании скриптов для ASP-сервера следует быть внимательным в названиях методов и при наличии исключений в первую очередь проверить корректность имен методов. При вызове какого-либо метода ASP-серверу становятся доступными интерфейсы IRequest и IResponse.

А теперь рассмотрим пример создания более сложного ASP-сервера, где запрос клиента анализируется при помощи методов интерфейса IRequest. Задачу поставим следующим образом: дадим возможность клиенту найти запись по фрагменту поля ENAME таблицы EMP в базе данных ORCL, сгенерированной Oracle 8.0.4 при его установке. Для этого в каком-либо редакторе форм создадим форму, содержащую однострочный редактор текста и кнопку Submit. HTML-документ с такой формой выглядит следующим образом:

При реализации этой формы вместо IP-адреса 10.10.10.65 следует указать IP-адрес компьютера, на котором установлен ASP-сервер.

Поместим этот документ в директорию C:\ASPTest, которая имеет доступ на чтение и выполнение (см. выше) под именем Name.htm. Но прежде чем создавать модуль данных и обращаться к серверу баз данных, необходимо выяснить, каким образом анализируется запрос клиента в ASP-объекте.

Запрос клиента можно анализировать при помощи вызова методов интерфейса IRequest, ссылка на который находится в свойстве Request класса TASPObject — предка класса, где реализуется ASP-объект. Интерфейс IRequest предоставляет три свойства: QueryString, Form и Body, в которых находятся ссылки на интерфейс IRequestDictionary. QueryString содержит параметры запроса, Form — список элементов управления, предоставляемых клиенту, а Body — данные, которые клиент ввел в эти элементы управления. Нам потребуются данные, поэтому мы будем анализировать свойство Body, однако все сказанное ниже о методах IRequestDisctionary применимо и к любому другому свойству типа ICustomDictionary — QueryString и Form.

IRequestDictionary определен в модуле ASPTlb.pas следующим образом:

Документация о свойствах этого интерфейса в Delphi отсутствует, и остается только догадываться, каким образом из него можно извлечь параметры запроса, введенные пользователем. Привлекая документацию по компоненту TWebDispatcher, который используется при создании CGI-приложений и ISAPI DLL, где также можно анализировать параметры запроса пользователя, можно понять, что свойство Count содержит число элементов управления на форме — для формы, содержащейся в документе Name.htm, оно равно 2. Свойство Key содержит имена элементов управления; для формы, содержащейся в документе Name.htm, это имена T1 (текстовое поле) и B1 (кнопка). И наконец, свойство Item содержит введенные пользователем значения.

Свойство Count работает как положено, то есть возвращает двойку для примера, приведенного выше. При попытке же извлечь имена элементов управления обнаруживается неприятная особенность: в коллекции Key[] индексы начинаются с единицы, а не с нуля, как это принято в приложениях подобного типа. Но все же, обращаясь к коллекции Key с соответствующим индексом — 1 или 2 для нашего примера, можно получить названия элементов управления в виде строковых переменных.

Аналогичная попытка извлечь данные, введенные пользователем в элементы управления, ни к чему хорошему не приводит. Так, при присвоении строковой переменной значения из коллекции Item[] (которая объявлена аналогично коллекции Key[]) происходит исключение. При анализе значения, возвращаемого коллекцией Item[I], обнаруживается, что возвращается интерфейс — потомок IDispatch. Методы и свойства этого интерфейса также не описаны.

Отсутствие описания интерфейса, а также возврат ссылки на него в переменной типа OLEVariant (а не IDispatch) обычно характерно для продуктов, которые находятся в стадии разработки. В этом случае заголовки методов интерфейса, список параметров методов и их число постоянно меняются, а во избежание исключений в клиентских приложениях часто используется позднее связывание. Этот факт настораживает: не исключена возможность изменения методов интерфейса в будущем, что может привести к потере работоспособности созданных ранее ASP-серверов. Однако хочется надеяться, что данный интерфейс устоялся, а в Microsoft по какой-либо причине просто забыли внести изменения в интерфейсный модуль.

Интерфейс — потомок IDispatch имеет два свойства: Count, которое всегда возвращает 1, и Item[]-коллекцию, которая возвращает текст, введенный клиентом в элементах управления. Коллекция Item начинается с индекса 1.

Для понимания и тестирования запроса в ASP-объекте сделаем небольшое дополнение к проекту. Воспользовавшись редактором библиотек типов, создадим новый метод RequestProp, как это было описано ранее (см. рис. 2). Напишем следующий код для метода RequestProp:

Скомпилируем проект и в созданном ранее файле Test.asp изменим код на языке VBScript следующим образом: вместо строки DelphiASPObj.ScriptContent напишем строку DelphiASPObj. RequestProp. После этого в Internet Explorer необходимо обратиться к странице Name.htm командой http://10.10.10.65/Test/Name.htm, где вместо 10.10.10.65 следует набрать IP-адрес сервера.

В полученной форме (рис. 3) введем какое-либо значение в элемент управления для редактирования данных и нажмем кнопку Submit. В итоге имеем результат выполнения приведенного выше кода метода RequestProp:

Итак, для определения параметров, введенных клиентом в какой-либо элемент управления, необходимо просмотреть всю коллекцию Keys, найти индекс интересующего нас элемента управления (в нашем примере — это 1, что соответствует ключу T1) и извлечь значение, введенное клиентом, посредством вызова команды Request.Body.Item[Index].Item[1].

Теперь можно перейти к модификации имеющегося сервера — созданию нового метода для доступа к базам данных.

Модуль данных, в который можно помещать невизуальные компоненты, экспертом создания ASP-объекта не генерируется — его необходимо создавать отдельно. Поэтому выберем пункт File|New главного меню среды разработки и из репозитария объектов выберем пиктограмму Data Module. В результате к проекту будет добавлен модуль данных, который мы сохраним под именем U1_02.pas. В этот модуль данных будут помещены невизуальные компоненты доступа к данным (визуальные компоненты в ASP-объектах использовать нельзя).

Вообще говоря, в Web-приложениях (ASP, ISAPI/NSAPI, CGI) показ модальных форм с элементами управления (а диалоги — частный вид таких форм) ни к чему хорошему не приводит. При попытке показать диалог элементы управления на диалоге будут созданы, и приложение будет ожидать, когда диалог будет закрыт (нажатием кнопки OK или Cancel), чтобы продолжить свою работу. Особенность заключается в том, что диалог невидим. Поэтому его нельзя закрыть ни с помощью нажатия на кнопки (они не получают сообщения OnClick), ни с помощью клавиш-акселераторов (сигналы с клавиатуры не посылаются невидимым элементам управления). Визуально программист наблюдает следующее: приложение «висит», отклика от ASP-объекта клиент не получает, а для повторной компиляции проекта требуется перезапуск Internet Information Server либо перезагрузка операционной системы. Даже если команды показа диалогов в ASP-сервере отсутствуют, они могут быть показаны в процессе работы приложения — например, какая-либо из библиотек, используемых приложением, пришлет сообщение об ошибке. Данный факт надо принимать во внимание при написании кода, в котором следует тщательно проверять данные перед их использованием, чтобы внешние приложения или библиотеки не присылали сообщений об ошибках в виде диалогов.

Традиционно доступ к данным в Delphi оcуществляется с помощью механизма Borland Database Engine (BDE), при этом необходимо использовать компоненты TSession, TDatabase и TQuery. Однако при создании ASP-объектов для доступа к данным выяснилось, что в них нельзя использовать BDE для доступа к SQL-серверам — при попытке соединиться с базой данных после передачи параметров, содержащих имя пользователя и пароль, происходит исключение (данный факт был проверен для Oracle 8.0.4 и IB Database 5.5). Через BDE удалось получить доступ только к базе данных DBDEMOS, которая не требует аутентификации пользователя при обращении к данным. К сказанному следует добавить, что в Windows 2000 нельзя получить доступ к данным через BDE в традиционных Web-серверных приложениях ISAPI DLL и CGI, в отличие от предыдущих версий Windows (95/98/NT).

К счастью, в Delphi 5 имеется альтернативный способ доступа к данным — с помощью ADO (ActiveX Data Objects). Для работы с ADO прежде всего необходимо использовать компонент TADOConnection. Поместим его в модуль данных. В инспекторе объектов выберем свойство ConnectionString и вызовем диалог для создания строки. В предложенном диалоге выберем Microsoft OLE DB Provider for Oracle и нажмем кнопку Next (рис. 4).

На второй странице диалога необходимо указать имя сервера (в данном примере — beq-local) и параметры аутентификации: имя пользователя (SCOTT) и пароль (TIGER). Обязательно следует отметить опцию Allow Saving Password, иначе ASP-объект попытается показать диалог ввода имени пользователя и пароля. Протестировать соединение можно нажатием кнопки Test Connection — должно появиться сообщение об успешном соединении с сервером.

Далее в инспекторе объектов следует установить свойство LoginPromp равным False. При работе с другими примерами нужно также изменять свойство DefaultDatabase — имя базы данных, но для данного примера это не обязательно. Проверить правильность установок можно при помощи установления свойства Connected равным True, при этом не должны появляться ни диалог ввода имени пользователя и пароля, ни информация об исключении.

Поместим компонент TADOQuery в модуль данных и в его свойстве Connection сошлемся на определенный выше компонент ADOConnection1.

Следует учесть, что только что разработанный модуль данных автоматически при загрузке ASP-сервера или при обращении клиента к ASP-объекту создаваться не будет. Поэтому необходимо переписать конструктор и деструктор класса TTest, реализация которого находится в файле U1_01.pas. Сошлемся на модуль U1_02.pas в модуле U1_01.pas. В объявлении класса TTest в секции private определим переменную FData типа TDataModule1. В секции public объявим процедуры AfterConstruction и BeforeDesctruction c обязательной директивой override:

Реализуем процедуры AfterConstruction и BeforeDestruction в секции реализации:

Далее в библиотеке типов (см. рис. 2) следует создать новый метод, который назовем QueryResponse. Реализуем его следующим образом:

В данном методе динамически создается SQL-запрос, при этом используются параметры, введенные клиентом в форму на рис. 3. С этим запросом происходит обращение к серверу баз данных, и возвращаемые данные помещаются в HTML-документ. В созданном ранее файле Test.asp изменим код на VBScript следующим образом: вместо строки DelphiASPObj.ScriptContent напишем строку DelphiASPObj. QueryResponse. После этого запустим Microsoft Internet Explorer и снова обратимся к странице Name.htm. Результат выполнения запроса приведен на рис. 5.

При использовании ASP-объекта необходимые для его работы параметры можно поместить, в HTML-документ. Параметры могут редактироваться в документе, что позволит изменять опции для конкретного сайта. Это удобно при поставке ASP-сервера: купившая его компания может изменить начальные установки так, чтобы они соответствовали требованиям компании. Для этого достаточно отредактировать HTML-документ, что возможно даже силами специалистов низкой квалификации.

Пример проиллюстрируем следующим образом: определим в заголовке класса TTest (U1_01.pas) две переменные: FCompanyName:string и FCopyrightYear:string. Определим в библиотеке типов (см. рис. 2) два новых свойства: CompanyName:string и CopyrightYear:integer. В методах *Read и *Wirte для этих свойств определим чтение и возврат данных из описанных выше переменных. В библиотеку типов добавим новый метод ShowCopyright, который реализуем следующим образом:

В созданном ранее файле Test.asp изменим код на языке VBScript:

Результатом обращения к ASP-объекту при помощи команды http://10.10.10.65/Test/Test.asp (вместо 10.10.10.65 следует ввести IP-адрес вашего сервера) будет генерация следующей страницы (рис. 6).

Если в файле Test.asp изменить имя компании (а это можно сделать при помощи любого текстового редактора), соответствующие изменения отобразятся в HTML-документе.

При помощи ASP-объектов можно передавать не только текстовую информацию, но и двоичную, например графические изображения. Создадим обычную HTML-страницу следующего вида:

Файл Test1.asp выглядит следующим образом:

При создании этого файла следует обратить внимание на отсутствие в нем тэгов , и т.д. а также любых записей, которые могут быть интерпретированы как текст в формате HTML. В нем должно быть только обращение к методу ASP-объекта и больше ничего. В противном случае появится сообщение о недопустимости изменения типа отклика после записи заголовков в HTML-документ.

Метод GetPicture реализуем следующим образом:

Для передачи двоичных данных необходимо указать их тип в свойстве Response.ContentType и воспользоваться методом BinaryWrite объекта Response. В качестве параметра этого метода используется переменная типа OLEVariant. В этой переменной должны находиться двоичные данные в виде массива байтов. Этот массив передается как отклик. В результате обращения к исходному HTML-документу клиент получит отклик (рис. 7).

До сих пор мы рассматривали in-process-серверы, которые работают в адресном пространстве Internet Information Server и реализуются в динамически загружаемых библиотеках — DLL. В заключение следует сказать и о создании out-of-process ASP-серверов. Такие серверы реализуются в виде исполняемых файлов и работают в отдельном адресном пространстве.

Для создания out-of-process-сервера необходимо открыть готовый проект, компиляция которого приводит к созданию исполняемого файла, или создать новый проект с помощью пункта меню File|New Application. После этого следует выбрать пункт главного меню File|New среды разработки Delphi, а затем со страницы ActiveX репозитария объектов — пиктограмму Active Server Object. В результате будет сгенерирована библиотека типов, содержащая методы OnStartPage и OnEndPage. Все, что было сказано выше по поводу in-process-сервера, справедливо и в отношении out-of-process-сервера: разработка ASP-объекта заключается в создании новых методов, которые будут вызываться из VBScript-кода ASP-страницы.

Сложности возникают при попытке протестировать out-of-process-сервер. По умолчанию параметры настройки Internet Information Server таковы, что запуск им приложений запрещен, а разрешена только загрузка DLL. Более того, в администраторе Internet Information Server отсутствует опция, позволяющая разрешить или запретить использование приложений как ASP-серверов. Для разрешения запуска исполняемого файла как ASP-сервера необходимо выполнить следующий код:

Для выполнения данного скрипта необходимо, чтобы пользователь, инициирующий его выполнение, имел статус администратора. По этой причине данный скрипт бесполезно определять в HTML-документе и запускать его с использованием Internet Explorer, так как любой пользователь Internet имеет статус гостя (Guest), а не администратора. Скрипт необходимо поместить в обработчик какого-либо события в среде разработки Visual Basic или VBA и запустить его оттуда (либо использовать Windows Scripting Host. — Прим.ред.).

К сожалению, в Delphi отсутствует метод, аналогичный методу VBScript GetObject. Очевидно, что метод GetObject возвращает ссылку на интерфейс IDispatch Internet Information Server. Однако при этом в качестве параметра он использует строку, которая не является классовой (ее GUID отсутствует в системном реестре). В Delphi аналогичных методов нет, по крайней мере, в виде простых вспомогательных функций. Возможно, подобный метод станет доступным в следующих версиях Delphi.

Server-Sent Events

SSE — технология отправки уведомлений сервера к браузеру. Клиент как-бы подключается к стриму обновлений и автоматически получает оповещения в случае новых событий.

Опрос сервера (polling и long polling)

Идея такова: AJAX-приложение проверяет новые данные на сервере. Клиент создает запрос и ждет ответа. Сервер возвращает ответ, даже если обновлений нет. Так что процесс создает дополнительную нагрузку на канал.

Поэтому вспомогаетельно используются “висячие” запросы — если нет обновлений, сервер поддерживает открытое соединение. Когда появляются новые данные, сервер отправляет их и закрывает соединение. После этого процесс повторяется.

WebSocket или SSE

Технология Server-Sent Events открывает одностороннее соединение между сервером и клиентом, после чего сервер передает данные приложению, когда это потребуется (push notifications). Еще одно отличие — SSE обрабатываются непосредственно на стороне клиента, который только слушает канал.

WebSocket — другая технология обмена сообщениями между клиентом и сервером. Ее главное отличие в том, что связь двусторонняя, клиент принимает и отправляет сообщения.

Она подходит для продвинутых веб-приложений, игр, мессенджеров и т.д, где требуются связь в режиме реального времени.

Server-Sent Events передаются по HTTP, не требуется реализация специального протокола или отдельного сервера. Тогда как для WebSocket требуется полная дуплексная связь и дополнительные сервера с протоколом. Кроме этого SSE поддерживает переподключение, идентификаторы событий и произвольные события.

Реализация на стороне клиента

API Server-Sent Events построен на интерфейсе EventSource . Поэтому для открытия нового соединения с сервером нужно создать объект EventSource. Он задает путь к скрипту, который создает события:

# SSE на стороне клиента реализуется на JavaScript, скрипт сервера — на PHP, ASP, NodeJS или другом удобном языке

После инициализации соединения клиент может принимать сообщения:

# Принимает сообщения от сервера и добавляет текст сообщения в список HTML

А при помощи директивы addEventListener() также можно принимать события:

# Вызывается автоматически, когда сервер отправляет событие ping, клиент парсит JSON и выводит результат

Кроме собственных событий также используются стандартные ивенты:

  • onopen — при успешном открытии соединения;
  • onerror – в случае сбоя соединения;
  • onmessage — новое сообщение.

Простейший пример стандартных событий будет выглядеть так:

# Попытка переподключения в случае ошибки

Учтите, что событий может быть несколько.

Реализация на стороне сервера

Скрипт, который отправляет события, должен использовать MIME-тип text/event-stream . Каждое сообщение — простой текст, разделенный двумя символами новой линии (\n\n)(пустой строкой).

Наш бэкенд на PHP будет иметь вид:

# Рандомно выводит сообщение с временной меткой

Самое главное

Используйте Server-Sent Events если нужна односторонняя связь между сервером и клиентом — вывод уведомлений, обновлений. Для более сложных задач подойдет WebSocket.

Что такое minify и как его использовать

Как работает сжатие gzip и как его включить

Методы оптимизации сайтов на стороне браузеров

Какие преимущества дает CDN и как с ним работать

Минификация (minify) HTML

Accelerated Mobile Pages для ускорения контентных страниц для мобильных устройств

Уменьшение размера картинок при сохранении качества

Как построить мини CDN на основе распределенного Nginx кеша

Анализ скорости сайта с помощью Google Pagespeed

Что такое Etag и как его настроить в Nginx

Основные ньюансы и методы мобильной оптимизации

Как улучшить время получения первого байта и отзывчивость веб-сервера

Анализ работы СУБД при помощи pgFouine

Ускорение PHP приложений на платформе YII в несколько раз

Основы оптимизации работы Web сервера

Главные возможности нового протокола HTTP/2

Ускорение репликации в Mysql 5.6+

Использование партиций для ускорения сложных удалений

Как эффективно решать задачу фильтрации по большому количеству колонок на основе колоночной базы данных

Введение в кэширование данных на примере Memcache

5 методик использования lazy loading для оптимизации

Эффективный механизм записи данных из Nginx’a прямо в Clickhouse минуя промежуточные узлы

Создание приложений реального времени с помощью Server-Sent Events

Буквально недавно стало известно, что Firefox 6 получит SSE (уже есть в Opera 10.6+, Chrome, WebKit 5+, iOS Safari 4+, Opera Mobile 10+) так, что поддержка более половины всех браузеров (охват аудитории пользователей) уже не за горами. Настало время присмотреться к этой технологии. SSE предложил Ian Hickson более 7 лет назад, но только год назад она стала появляться в браузерах. У нас же есть WebSockets зачем нам ещё один какой-то протокол?! Но во всем есть свои плюсы и минусы, давайте посмотрим чем же SSE может быть полезен.

Идея SSE проста — клиент подписывается на события сервера и как только происходит событие — клиент сразу же получает уведомление и некоторые данные, связанные с этим событием. Чтобы понять полезность протокола SSE необходимо сравнить его с привычными методами получения событий, вкратце объясню их суть:

Polling

Самый простой, но самый не эффективный, метод: клиент раз в несколько секунд опрашивает сервер на наличие событий. Даже если ничего нет, то клиент всеравно делает запрос — а мало ли что придет.
Плюсы:
— Просто
— Данные могут быть пожаты
Минусы:
— Очень много лишних запросов
— События всегда приходят с опозданием
— Серверу приходится хранить события пока клиент не заберет их или пока они не устареют

Long Polling

Улучшенный вариант предыдущего метода. Клиент отправляет запрос на сервер, сервер держит открытым соединение пока не придут какие-нибудь данные или клиент не отключится самостоятельно. Как только данные пришли — отправляется ответ и соединение закрывается и открывается следующее и так далее.
Плюсы по сравнению с Polling:
— Минимальное количество запросов
— Высокая временная точность событий
— Сервер хранит события только на время реконнекта
Минусы по сравнению с Polling:
— Более сложная схема

WebSockets

Это бинарный дуплексный протокол, позволяющий клиенту и серверу общаться на равных. Этот протокол можно применять для игр, чатов и всех тех приложений где вам нужны предельно точные события близкие к реальному времени.
Плюсы по сравнению с Long Polling:
— Поднимается одно соединение
— Предельно высокая временная точность событий
— Управление сетевыми сбоями контролирует браузер
Минусы по сравнению с Long Polling:
— HTTP не совместимый протокол, нужен свой сервер, усложняется отладка

Так почему же стоит применять SSE, раз у нас есть такой прекрасный протокол WebSockets?! Во-первых не каждому веб-приложению необходима двусторонняя связь — подойдет и SSE. Во-вторых SSE — HTTP совместимый протокол и вы можете реализовать рассылку событий на любом веб-сервере.

Протокол Server-Sent Events

Клиент отправляет запрос на сервер, сервер в ответ отправляет следующий заголовок:

И не закрывает соединение (на php можно создать бесконечный цикл, как сделать на node.js будет объеснено в примере статьи). Вот и все — SSE работает! Чтобы отправить клиенту какие-то данные сервер просто пишет в сокет строку следующего формата:

Если необходимо отправить несколько строк данных, то формат будет следующим:

Вот, впринципе, и вся база протокола. Кроме этого сервер может отправлять id сообщения это нужно на случай если соединение было разорвано. Если соединение было сброшено, то клиент при попытке подключения отправит специальный заголовок (Last-Event-ID), чтобы восстановить утраченные события:

Время переподключения (retry) в случае ошибок:

Поле id и retry не обязательны.

На клиенте все будет выглядеть следующим образом:

Все предельно просто. Давайте построим приложение на основе протокола SSE. Как водится, это будет чат.

Multipart XMLHTTPRequest

Ещё называют multipart streaming (Поддерживает только Firefox). Очень похожий на SSE протокол.
Его заголовок имеет фомат:

А части отсылаются в таком формате:

В клиенте создается обычный XHR, но перед отправкой запроса необходимо поставить флаг req.multipart = true;
Правда похоже на SSE? Подробнее

Есть ещё один протокол, который можно привести к SSE:

XMLHTTPRequest: Interactive

Для использования его необходима поддержка браузером специального readyState с кодом 3 (interactive) — этот статус сообщает о том, что часть данных пришла, но соединение ещё не закрыто. Для jQuery есть одноименный плагин, использующий readyState с кодом 3. И как всегда не все браузеры поддерживают readyState с кодом 3.

Пример: Чат на Server-Sent Events

Мы будем принимать поток событий по SSE: уход в оффлайн, приход в онлайн, сообщение. Т.к. по SSE нельзя отправлять сообщение, то мы будем отправлять их по HTTP.

Схема работы такая:
— При входе в чат запрашивается имя
— Клиент подключается к серверу чата. Создается поток событий.
— При подключении клиента чат рассылает всем событие: %username% online
— При отключении клиента чат рассылает всем событие: %username% offline
— Клиент может отправлять сообщение по HTTP «POST /message» Cервер принимает это сообщение и рассылает всем клиентам принятое сообщение по SSE

Разберем код клиента. Для того, чтобы у некоторых браузеров не было бесконечной загрузки мы вместо $.ready выполняем setTimeout:

Запрашиваем имя пользователя:

Создаем EventSource и передаем ему имя пользователя (теперь пользователь онлайн) и слушаем необходимые события:

Не буду рассматривать метод renderMessage и разметку страницы. Весь код клиента можно посмотреть тут: index.html

На стороне сервера у нас будет Node.js. Тут все сложнее, но основная сложность в мультикасте сообщений от одного пользователя ко всем, а не в построении коммуникации по SSE.

Подключаем необходимые модули
Роуты

Создаем список роутов Routes, включающий в себя следующие объекты:
1. Статика. Индексная страница, мы просто шлем статику:

2. Поднятие SSE соедиения:

3. Сообщение от клиента:

4. Роут по умолчанию — Страница 404:

Менеджер клиентов — Clients

При добавлении нового клиента (add) менеджер рассылает все сообщение о том, что клиент пришел:

При удалении закрывает соединение и рассылает всем, что клиент оффлайн:

Для отправки сообщений клиентам используется private метод _send:

Метод _send используют public методы broadcast и unicast для рассылки сообщения всем и одному клиенту соответственно.

Создаем и включаем сервер

Наш чат на SSE готов. Запускаем сервер:

Открываем один из браузеров: Firefox 6, Opera 10.6+, Chrome, WebKit 5+, iOS Safari 4+, Opera Mobile 10+. Переходим на http:// localhost/ и чатим!

Заключение

SSE — хорошая технология, которая должна вытеснить Long Poling она проста и не менее эффективна, чем WebSockets. Сейчас SSE поддерживают Opera 10.6+ (Opera 9 поддерживает старый стандарт SSE), Chrome, Safari 5+. Firefox поддерживает Multipart XMLHTTPRequest, для которого можно написать обертку и использовать как интерфейс SSE.

Ссылки

1. Онлайн пример SSE чата можно посмотреть вот тут: sse-chat.nodester.com
Это несколько урезанная версия чата из-за особенностей проксирования Nodester (нет сообщения о количестве пользователей онлайн и нет сообщений о выходе из чата, может быть частый реконнект)
2. Исходник примера: github.com/azproduction/event-source-chat
3. Ещё один туториал по SSE
4. Спецификация

PS Похоже, что чат накрыл хабраэффект, но возможно что-то с nodester(у него часто такое бывает). Если вам интересен результат, то скачайте исходник с GitHub.

UPD Добавил Multipart XMLHTTPRequest, XMLHTTPRequest: Interactive спасибо за дополнение yui_room9

Состояние сеанса

— это самая сложная технология для управления состояниями. Она позволяет сохранять информацию на одной странице и затем получать к ней доступ с другой страницы, а также поддерживает объекты любого типа, включая специальные, создаваемые самим разработчиком типы данных. Лучше всего то, что состояние сеанса использует такой же основанный на коллекциях синтаксис, что и состояние представления. Единственное отличие связано с именем встроенного свойства страницы, которое в данном случае выглядит как Session.

Каждый клиент, который получает доступ к приложению, имеет свой сеанс и отдельную коллекцию данных. Состояние сеанса идеально подходит для сохранения таких данных, как элементы, которые находятся в корзине для покупок пользователя, когда он переходит с одной страницы на другую.

Но за использование состояния сеанса необходимо платить свою цену. Хотя оно решает многие из проблем, которые возникают в случае применения других технологий управления состояниями, его использование вынуждает веб-сервер сохранять дополнительную информацию в памяти. Необходимость в использовании дополнительных ресурсов памяти сервера, пусть даже в небольшом объеме, очень быстро может достичь угрожающего производительности уровня, когда к сайту начнут получать доступ тысячи клиентов.

Архитектура сеанса

Управление сеансом не является частью HTTP-стандарта. Поэтому для отслеживания информации сеанса и ее привязки к соответствующему ответу ASP.NET приходится выполнять дополнительную работу.

ASP.NET отслеживает каждый сеанс с помощью уникального 120-битового идентификатора. Для генерации этого значения ASP.NET использует патентованный алгоритм, что, согласно статистике, обеспечивает гарантию того, что число будет уникальным и достаточно случайным для того, чтобы злоумышленник не смог воссоздать или угадать идентификатор сеанса, которым будет пользоваться данный клиент. Этот идентификатор является единственным фрагментом информации, который передается между вебсервером и клиентом.

Когда клиент предоставляет идентификатор сеанса, ASP.NET отыскивает соответствующий сеанс, извлекает с сервера состояний сериализированные данные, преобразует их в реальные объекты и помещает эти объекты в специальную коллекцию для того, чтобы к ним можно было получить доступ в коде. Весь этот процесс выполняется автоматически.

При каждом новом запросе ASP.NET генерирует новый идентификатор сеанса до тех пор, пока состояние сеанса не будет фактически использовано для сохранения какой-то информации. Такое поведение позволяет немного увеличить производительность. Коротко это можно объяснить так: зачем тратить время на сохранение идентификатора сеанса, если он не используется?

Когда ASP.NET обрабатывает HTTP-запрос, тот проходит через конвейер различных модулей, которые могут реагировать на события приложения. Одним из модулей в этой цепочке является SessionStateModule (который находится в пространстве имен System.Web.SessionState). Этот модуль генерирует идентификатор сеанса, извлекает из внешних поставщиков состояния данные сеанса и затем привязывает эти данные к контексту вызовов запроса. Он также сохраняет данные состояния сеанса, когда обработка страницы завершается.

Однако важно понимать, что модуль SessionStateModule фактически не хранит данные сеанса. Вместо этого состояние сеанса сохраняется во внешних компонентах, которые называются поставщиками состояния:

Состояние сеанса представляет собой еще один пример сменной архитектуры ASP.NET. Поставщиком состояния может быть любой класс, который реализует интерфейс IHttpSessionState, а это значит, что способ работы состояния сеанса можно настроить, просто создав (или купив) новый .NET-компонент. ASP.NET включает три готовых поставщика состояния, которые позволяют сохранять информацию внутри процесса, в отдельной службе и в базе данных SQL Server.

Чтобы механизм состояния сеанса работал, клиент вместе с каждым запросом должен предоставлять соответствующий идентификатор сеанса. Финальным фрагментом данной головоломки является способ отслеживания этого идентификатора сеанса от одного запроса к другому. Это можно делать двумя способами:

С применением cookie-наборов. В этом случае идентификатор сеанса передается в специальном cookie-наборе (по имени ASP.NET_SessionId), который ASP.NET создает автоматически, когда используется коллекция сеанса. Он применяется по умолчанию и соответствует способу из более ранних версий ASP.

С помощью измененных URL-адресов. В этом случае идентификатор сеанса передается в специально измененном URL-адресе. Это дает возможность создавать приложения, которые используют состояние сеанса для клиентов, не поддерживающих cookie-наборы.

Использование состояния сеанса

Взаимодействовать с состоянием сеанса можно с помощью класса System.Web.SessionState.HttpSessionState, который на веб-странице ASP.NET доступен в виде встроенного объекта Session. Синтаксис для добавления элементов в эту коллекцию и их извлечения выглядит практически так же, как и синтаксис, который используется для добавления элементов в состояние представления страницы.

Например, вот как сохранить объект DataSet в памяти сеанса:

После этого его можно извлечь с помощью соответствующей операции преобразования:

Контекст состояния сеанса охватывает все приложение и является глобальным для текущего пользователя. Данные состояния сеанса могут быть утеряны в следующих случаях:

Если пользователь закрывает и заново запускает браузер.

Если пользователь получает доступ к той же странице через другое окно браузера, хотя сеанс будет по-прежнему существовать, если доступ к веб-странице получается из исходного окна браузера. Разные браузеры ведут себя в такой ситуации по-разному.

Если сеанс завершается из-за отсутствия активности со стороны пользователя. По умолчанию сеанс автоматически завершается после 20 минут простоя.

Если программист завершает сеанс вызовом метода Session.Abandon().

В первых двух случаях данные состояния сеанса фактически остаются в памяти сервера, потому что веб-сервер не разбирается в том, закрыл клиент окно браузера или открыл новое. Они будут продолжать находиться там, оставаясь недоступным, до тех пор, пока не истечет срок их хранения.

Вдобавок данные состояния сеанса также будут утеряны и в случае повторного создания домена приложения. Этот процесс происходит автоматически при обновлении веб-приложения либо изменении конфигурационных параметров. Домен приложения также может создаваться заново через определенные промежутки времени для поддержания приложения в нормальном работоспособном состоянии. Если такое поведение приводит к возникновению проблем, данные состояния сеанса можно хранить вне процесса. В таком случае они не потеряются даже в результате завершения домена приложения.

В таблице ниже перечислены основные методы и свойства класса HttpSessionState:

Методы и свойства класса HttpSessionState

Метод или свойство Описание
Count Количество элементов в коллекции текущего сеанса
IsCookieless Указывает, как отслеживается этот сеанс: с помощью cookie-набора или с использованием измененных URL-адресов
IsNewSession Указывает, был ли данный сеанс только что создан для текущего запроса. Если в состоянии сеанса на текущий момент не содержится никакой информации, ASP.NET не будет беспокоиться ни об отслеживании сеанса, ни о создании cookie-набора сеанса. Вместо этого сеанс будет воссоздаваться заново при каждом запросе
Mode Предоставляет перечислимое значение, которое объясняет, как ASP.NET хранит информацию о состоянии сеанса. Этот режим хранения определяется на основе указанных в файле web.config конфигурационных настроек
SessionID Предоставляет строку с уникальным идентификатором сеанса для текущего клиента
StaticObjects Предоставляет коллекцию элементов сеанса, предназначенных только для чтения, которые были объявлены в global.asax с помощью дескрипторов . В основном эта технология не используется и является пережитком ASP-программирования; она поддерживается для обратной совместимости
Timeout Текущее количество минут, которое должно пройти, прежде чем текущий сеанс будет завершен при условии отсутствия запросов от клиента. Это значение может изменяться программно, что дает возможность при необходимости продлевать срок жизни коллекции сеанса для более важных операций
Abandon() Немедленно завершает текущий сеанс и освобождает все занятые им ресурсы памяти. Такая технология полезна на автономных страницах, поскольку позволяет освобождать ресурсы памяти сервера настолько быстро, насколько возможно
Clear() Удаляет все элементы сеанса, но не изменяет идентификатор текущего сеанса

Конфигурирование состояния сеанса

Сконфигурировать состояние сеанса можно с помощью элемента в файле web.config. Ниже показаны все доступные параметры настройки, которые можно применять:

Атрибуты сеанса подробно описаны в последующих разделах.

Параметр настройки состояния сеанса Mode позволяет указать, какой поставщик состояния сеанса должен использоваться для хранения данных состояния сеанса между запросами. Допустимые значения перечислены ниже:

Off

Установка значения Off отключает управление состоянием сеанса для всех страниц в приложении. Это может немного увеличить производительность веб-сайтов, которые не используют состояние сеанса.

InProc

Установка значения InProc напоминает подход, который использовался для хранения состояния сеанса в классической версии ASP. Это значение указывает ASP.NET хранить информацию в текущем домене приложения, что обеспечивает наилучшую производительность, но наименьший срок хранения: если вы перезапустите сервер, данные состояния будут утеряны.

Значение InProc используется по умолчанию и подходит для большинства веб-сайтов небольшого размера. Однако в сценарии веб-фабрики от него не будет никакого толку. Чтобы состояние сеанса совместно использовалось множеством серверов, необходимо применять внепроцессный поставщик или службу состояний SQL Server.

Еще одна причина, по которой установка значения InProc может быть нежелательной, состоит в том, что она приводит к получению более «хрупких» сеансов. В ASP.NET домены приложений создаются заново в ответ на различные действия, включая изменения конфигурационных настроек, обновления страниц, а также достижение определенных пороговых значений (независимо от того, произошла ошибка или нет). Если вы обнаружите, что домен приложения часто перезапускается, что приводит к преждевременному завершению сеансов, можете воспользоваться одним из более надежных поставщиков состояния сеанса.

StateServer

В случае установки этого значения ASP.NET будет использовать для управления состоянием отдельную Windows-службу. Даже при запуске на том же самом веб-сервере эта служба будет загружаться за пределами главного процесса ASP.NET, что обеспечивает для нее базовый уровень защиты, когда возникает необходимость перезапуска процесса ASP.NET. Недостаток такого подхода в том, что из-за передачи данных состояния между двумя процессами увеличивается время задержки. Если доступ к данным сеанса получается часто, и они часто изменяются, работа может существенно замедлиться.

Выбрав режим StateServer, обязательно следует указать значение для параметра stateConnectionString. Эта строка сообщает TCP/IP-адрес компьютера, на котором запускается служба StateServer, и номер его порта (который определяется ASP.NET и который обычно изменять не нужно), что позволяет обслуживать службу StateServer на другом компьютере. Если не изменить значение этого параметра, использоваться будет локальный сервер (с адресом 127.0.0.1).

Разумеется, эта служба должна быть запущена, чтобы приложение могло с ней взаимодействовать. Проще всего это сделать с помощью консоли управления Microsoft (Microsoft Management Console). Выберите в меню Start (Пуск) пункт Programs Administrative Tools Computer Management (Все программы Администрирование Управление компьютером) или же откройте окно панели управления, щелкните на значке Administrative Tools (Администрирование), а затем на значке Computer Management (Управление компьютером). В появившемся диалоговом окне Computer Management (Управление компьютером) разверните узел Services and Applications (Службы и приложения) и щелкните на элементе Services (Службы). В правой части окна появится список служб: отыщите в нем службу по имени ASP.NET State Service:

Отыскав службу в списке, вы можете вручную запустить или остановить ее с помощью щелчка правой кнопкой мыши. Обычно имеет смысл сконфигурировать ОС Windows так, чтобы эта служба запускалась автоматически. Для этого щелкните на имени службы правой кнопкой мыши, в появившемся контекстном меню выберите пункт Properties (Свойства). После этого в списке Startup Type (Тип запуска) выберите значение Automatic (Автоматически), как показано на рисунке ниже. Далее щелкните на кнопке Start (Запустить), чтобы запустить эту службу немедленно.

Используя режим StateServer, можно также установить значение для необязательного атрибута stateNetworkTimeout, задающего максимальное количество секунд, в течение которых должен ожидаться ответ от службы, прежде чем запрос будет отменен. По умолчанию это значение равно 10 секунд.

SQLServer

Это значение заставляет ASP.NET использовать для хранения информации о сеансе базу данных SQL Server, применяя параметры, определенные в атрибуте sqlConnectionString. Такой способ управления состоянием является наиболее удобным, но пока что самым медленным. Чтобы его можно было использовать, на сервере должна быть установлена система SQL Server.

Установка значения для атрибута sqlConnectionString выполняется по схеме, подобной той, что применяется для получения доступа к данным ADO.NET. В целом это подразумевает указание источника данных (адреса сервера), имени пользователя и пароля, если только не используется интегрированная система безопасности SQL.

Вдобавок также должны быть установлены специальные хранимые процедуры и временные базы данных сеансов. Эти хранимые процедуры будут отвечать за сохранение и извлечение данных сеанса. В состав ASP.NET входит утилита командной строки, позволяющая выполнять эту задачу автоматически. Называется она aspnet_regsql.exe и находится в каталоге c:\Windows\Microsoft.NET\Framework\[Версия].

Удобнее всего запускать ее в окне командной строки Visual Studio (выберите в меню Start (Пуск) пункт Programs Microsoft Visual Studio 2012 Visual Studio Tools Visual Studio 2012 Command Prompt. Затем можно сразу же вводить команду aspnet_regsql.exe независимо от того, в каком каталоге она открыта.

Утилита aspnet_regsql.exe может применяться для решения нескольких связанных с базами данных задач. Чтобы использовать ее для создания базы данных с хранилищем сеансов, нужно указать параметр -ssadd. Кроме того, параметр -S позволяет указать имя сервера базы данных, а параметр -Е — что для подключения к этой базе данных должна использоваться учетная запись текущего пользователя Windows.

Ниже показана команда, которая создает базу данных для хранения данных сеанса на текущем компьютере, используя для нее стандартное имя ASPState:

В этой команде используется псевдоним localhost, который указывает aspnet_regsql.exe подключаться к серверу баз данных на текущем компьютере. Но вместо этого псевдонима может использоваться имя любого другого компьютера, на котором находится нужный сервер баз данных.

После создания базы данных состояния сеанса необходимо указать ASP.NET ее использовать, внеся соответствующие изменения в раздел файла web.config. Если для хранения информации о состоянии сеанса была создана база данных ASPState (это принято по умолчанию), тогда предоставлять ее имя в разделе не нужно. Вместо этого следует указать место размещения сервера и тип аутентификации, который ASP.NET должна применять для подключения к этому серверу:

На этом процедура настройки завершена. Однако если нужно использовать постоянные сеансы или специальную базу данных, эти шаги могут быть немного изменены, как будет показано далее.

Для удаления базы данных ASPState используйте параметр -ssremove.

Обычно при управлении состоянием с помощью SQL Server по-прежнему действует стандартный параметр тайм-аута состояния сеанса. Причина в том, что утилита aspnet_regsql.exe также создает для SQL Server новое задание по имени ASPState_Job_DeleteExpiredSessions. До тех пор, пока работает служба SQLServerAgent, это задание будет выполняться каждую минуту.

Кроме того, при каждом перезапуске сервера SQL Server, независимо от значения тайм-аута сеанса, будут удаляться таблицы данных состояния. Дело в том, что таблицы информации о состоянии создаются в базе данных tempdb, которая является всего лишь временным хранилищем. Если такое поведение не подходит, можно указать утилите aspnet_regsql.exe установить в базе данных ASPState постоянные таблицы данных состояния. Для этого понадобится использовать параметр -sstype p (где p означает «persisted» (постоянный)). Ниже показана модифицированная версия предыдущей команды:

Теперь записи сеанса будут оставаться в базе данных даже в случае перезапуска SQL Server.

И, наконец, последний вариант: утилиту aspnet_regsql.exe также можно применять для создания таблиц данных состояния в какой-то другой базе данных (отличной от ASPState). Для этого применяется параметр -sstype c (где c означает «custom» (специальный)) и указывается имя базы данных в параметре -d:

При таком подходе таблицы данных сеанса будут сразу же созданы как постоянные, так что содержащиеся в них записи будут оставаться даже после перезапуска SQL Server.

В случае использования специальной базы данных также потребуется выполнить две конфигурационные настройки в разделе файла web.сonfig. Во-первых, необходимо установить атрибут allowCustomSqlDatabase в true. Во-вторых, понадобится добавить в строку соединения параметр InitialCatalog с именем используемой базы данных. Ниже показан должным образом настроенный элемент :

В случае выбора режима SQLServer также можно устанавливать значение для необязательного атрибута sqlCommandTimeout, который задает максимальное количество секунд на ожидание ответа от базы данных перед отменой запроса. По умолчанию значение равно 30 секундам.

Custom

Выбор специального (Custom) режима требует указания используемого поставщика хранилища данных о состоянии сеанса с помощью атрибута customProvider. В атрибуте customProvider может быть задано как имя класса, являющегося частью веб-приложения и хранящегося в каталоге App_Code, так и имя класса, входящего в состав скомпилированной сборки и хранящегося в каталоге Bin или в глобальном кэше сборок (GAC).

К числу наиболее распространенных причин для применения специального поставщика хранилища данных о состоянии сеанса относится необходимость хранить информацию сеанса в базе данных, отличной от SQL Server, и потребность использовать какую-то существующую таблицу в базе данных, которая имеет определенную схему.

Создание специального поставщика представляет собой низкоуровневую процедуру, которая должна проводиться очень тщательно и осторожно для гарантии безопасности, стабильности и масштабируемости, из-за чего всегда лучше пользоваться готовым поставщиком, который был разработан и протестирован надежной сторонней компанией.

Сжатие

В ASP.NET доступно средство сжатия, которое позволяет сократить размер сериализируемых данных сеанса. Если установить атрибут enableCompression в true, данные сеанса перед отправкой за пределы процесса будут сжиматься (с использованием класса System.IO.Compression.GZipStream). Параметр enableCompression действует только при использовании внепроцессного хранилища состояния сеанса, поскольку только в такой ситуации данные сериализируются.

Для сжатия и восстановления данных сеанса веб-сервер должен выполнять дополнительную работу. Однако обычно это никакой проблемы не представляет, т.к. сжатие применяется лишь в тех сценариях, когда веб-серверы имеют массу лишнего времени ЦП, но ограничены по каким-то другим показателям. Сжатие данных состояния сеанса имеет смысл в описанных двух ключевых ситуациях:

При сохранении больших объемов данных состояния сеанса в памяти. Память вебсервера является очень ценным ресурсом. В идеале состояние сеанса применяется для сохранения относительно небольших фрагментов информации, а для остальных требующих более длительного хранения и больших по объему данных применяется база данных. Но если это не так и внепроцессный сервер состояния требует огромных объемов памяти, сжатие может оказаться подходящим решением.

При сохранении данных состояния сеанса данных на другом компьютере. В некоторых веб-приложениях с высокой степенью масштабируемости состояние сеанса сохраняется за пределами процесса (обычно в базе данных SQL Server) или на отдельном компьютере. Из-за этого среда ASP.NET должна передавать информацию сеанса туда и обратно через сетевое соединение. Очевидно, что при таком проектном решении показатели производительности будут значительно ниже, чем при сохранении состояния сеанса на компьютере веб-сервера. Однако для некоторых веб-приложений, с высоким трафиком и большими потребностями в плане сохранения данных состояния сеанса это решение все равно может быть лучшим компромиссом.

В первом случае сжатие позволяет жертвовать ресурсами ЦП во имя экономии памяти веб-сервера, а во втором — ради сокращения нагрузки на сетевое соединение. Степень сжатия существенно варьируется в зависимости от типа данных, но во время тестирования клиентам Microsoft удавалось достигать сокращения размеров данных на 30-60% , что гарантирует значительный выигрыш в производительности.

Cookieless

Параметр Cookieless может быть установлен в любое из значений перечисления HttpCookieMode. С помощью атрибута cookieName можно указать имя, используемое для cookie-набора. Если оно не указано, для имени cookie-набора принимается значение по умолчанию, которое выглядит как ASP.NET_SessionId.

Значения, доступные в перечислении HttpCookieMode

Значение Описание
UseCookies Cookie-наборы используются всегда, даже если браузер или устройство не поддерживает их или если они были отключены. Это значение устанавливается по умолчанию. Если устройство не поддерживает cookie-наборы, информация сеанса будет утрачиваться при последующих запросах, потому что каждый запрос будет получать новый идентификатор
UseUriCookie Cookie-наборы не используются никогда, независимо от возможностей браузера или устройства. Вместо этого идентификатор сеанса сохраняется в URL-адресе
UseDeviceProfile ASP.NET решает, какие сеансы использовать (с поддержкой cookie-наборов или без), анализируя содержимое объекта BrowserCapabilities. Недостаток такого подхода заключается в том, что этот объект указывает, что устройство должно поддерживать: он не учитывает того факта, что пользователь мог отключить cookie-наборы в браузере, который в принципе их поддерживает
AutoDetect ASP.NET пытается определить, поддерживает ли браузер cookie-наборы, пробуя установить и извлечь cookie-набор. Эта широко используемая технология позволяет точно определить, когда браузер поддерживает cookie-наборы, но это средство было отключено, указывая ASP.NET применять режим без поддержки cookie-наборов

Ниже приведен пример принудительного применения режима без поддержки cookie-наборов (что удобно для целей тестирования):

В режиме без поддержки cookie-наборов идентификатор сеанса будет автоматически вставляться в URL-адрес. Получив запрос, ASP.NET будет удалять идентификатор, извлекать коллекцию сеанса и направлять запрос в соответствующий каталог. Измененный URL-адрес показан ниже:

Поскольку идентификатор сеанса вставляется в текущий URL-адрес, все относительные ссылки также автоматически получают этот идентификатор сеанса. Другими словами, если пользователь на текущий момент находится на странице Page1.aspx и щелкает на относительной ссылке, указывающей на страницу Page2.aspx, эта относительная ссылка будет включать текущий идентификатор сеанса как часть URL-адреса. То же самое произойдет и если вызвать метод Response.Redirect() с относительным URL-адресом.

Единственное реальное ограничение режима без поддержки cookie-наборов состоит в том, что с ним нельзя применять абсолютные ссылки, потому что они не будут содержать идентификатора сеанса. Например, выполнение следующего оператора приведет к утрате пользователем всей информации о сеансе:

По умолчанию ASP.NET допускает повторное использование идентификатора сеанса. Например, если делается запрос и строка запроса содержит просроченный сеанс, ASP.NET создает новый сеанс и использует этот же идентификатор сеанса. Проблема в том, что идентификатор сеанса может случайно появиться в каком-то публичном месте, например, на странице результатов в поисковой службе. Это может привести к тому, что множество пользователей получат доступ к серверу с одним и тем же идентификатором сеанса и затем присоединятся к одному и тому же сеансу с теми же самыми разделяемыми данными.

Во избежание такой потенциальной угрозы безопасности, рекомендуется включать в код необязательный атрибут regenerateExpiredSessionId и устанавливать его в true при использовании сеансов без cookie-наборов. В этом случае при подключении пользователя с просроченным идентификатором сеанса будет генерироваться новый идентификатор сеанса.

Единственный недостаток такого подхода состоит в том, что он подразумевает утерю всех данных состояния представления и формы на текущей странице, т.к. для обеспечения нового идентификатора сеанса ASP.NET выполняет переадресацию браузера.

Чтобы выяснить, используется ли в текущий момент сеанс без cookie-наборов, необходимо проверить свойство IsCookieless объекта Session.

Timeout

Еще одним важным параметром настройки состояния сеанса в файле web.config является Timeout. Он указывает количество минут, в течение которых ASP.NET будет находиться в режиме ожидания (не получая запрос), прежде чем завершит сеанс:

Этот параметр является одним из наиболее важных параметров состояния сеанса. Неправильно выбранное количество минут может значительно увеличить нагрузку на сервер и крайне негативно сказаться на производительности приложения. В идеале выбираемый промежуток времени должен быть достаточно коротким для того, чтобы сервер мог быстро восстанавливать бесценные ресурсы памяти после того, как клиент прекращает использовать приложение, но и достаточно длинным для того, чтобы клиент мог делать паузу и продолжать сеанс, не утратив его.

Значение параметра Timeout можно также изменять в коде. Например, если известно, что сеанс содержит чрезвычайно большое количество информации, время хранения сеанса лучше ограничить. Для этого можно отобразить пользователю соответствующее предупредительное сообщение и затем просто изменить значение свойства Timeout. Следующая строка кода ограничивает время тайм-аута до 10 минут:

Обеспечение безопасности состояния сеанса

Данные в состоянии сеанса хорошо защищены, т.к. они хранятся исключительно на сервере. Однако cookie-набор и идентификатор сеанса крайне уязвимы. Это означает, что злоумышленник может похитить cookie-набор и инициировать сеанс на другом компьютере.

Существует несколько подходов, позволяющих обойти эту проблему. Наиболее распространенный из них — воспользоваться специальным модулем сеанса, выполняющим проверку на наличие изменений в IP-адресе клиента. Однако единственным действительно безопасным подходом является разрешение доступа к cookie-наборам сеанса только из тех разделов веб-сайта, где используется SSL-шифрование. В таком случае cookie-набор сеанса шифруется и, следовательно, становится бесполезным на других компьютерах.

Если решено воспользоваться этим подходом, также имеет смысл пометить cookie-набор как безопасный, чтобы он пересылался только через SSL-соединения. Это не позволит пользователям изменять URL-адрес с https:// на http:// и, следовательно, пересылать cookie-набор без SSL-шифрования. Ниже показан необходимый код:

Как правило, этот код применяется сразу после аутентификации пользователя. Удостоверьтесь, что в состоянии сеанса присутствует, по крайней мере, один фрагмент информации, чтобы сеанс не был завершен (и позже создан заново).

При использовании сеансов без cookie-наборов существует еще одна потенциальная угроза нарушения системы безопасности. Даже если идентификатор сеанса зашифрован, применив прием социальной инженерии, сообразительный пользователь может вынудить другого пользователя подключиться к определенному сеансу. Все, что злоумышленнику понадобится — это подсунуть другому пользователю URL-адрес с действительным идентификатором сеанса. Щелкнув на ссылке, этот пользователь сразу же подключится к такому сеансу. Хотя с этого момента идентификатор сеанса будет защищаться, атакующему уже известно, какой идентификатор сеанса используется, поэтому он сможет позже взломать этот сеанс.

Чтобы снизить возможность такой атаки, необходимо выполнить ряд определенных шагов. Во-первых, при использовании сеансов без cookie-наборов всегда устанавливайте атрибут regenerateExpiredSessionId в true. Это не позволит злоумышленнику предоставлять просроченный идентификатор сеанса. Во-вторых, явно прекращайте текущий сеанс перед входом в систему нового пользователя.

Ошибка 504 Gateway TimeOut (время прохождения через шлюз истекло)

Ошибка 504 Gateway Timeout – это код состояния HTTP , который означает, что один сервер не получил своевременный отклик от другого сервера, к которому он обратился, пытаясь загрузить веб-страницу или выполнить запрос браузера. Она может возникать вместе с 502 Bad Gateway .

Другими словами, ошибка 504 указывает на то, что у сервера, на котором расположен сайт и у компьютера, на котором выскакивает ошибка 504, отсутствует стабильное достаточно быстрое соединение с интернетом.

Как можно увидеть ошибку 504

Отдельным сайтам разрешено настраивать отображение ошибки Gateway Timeout . Вот несколько распространенных способов вывода подобной ошибки:

Ошибка 504 Gateway Timeout появляется внутри окна браузера, как обычная веб-страница. На ней могут быть знакомые верхние и нижние колонтитулы сайта и красивое английское сообщение. Также подобная ошибка может отображаться на полностью белой странице с большой цифрой 504 вверху. Это одно и то же сообщение, независимо от того, как сайт показывает его вам.

Помните, что ошибка 504 Gateway Timeout и 502 Bad Gateway ngin может появиться в любом браузере, операционной системе и на любом устройстве.

Причины возникновения ошибки 504 Gateway Timeout

В большинстве случаев ошибка 504 Gateway Timeout означает, что любой сервер, который выдает « тайм-аут », « упал » или неправильно работает.

Поскольку эта ошибка обычно возникает между серверами в интернете, то, вероятно, она не связана с вашим компьютером, устройством или интернет-соединением.

Как исправить ошибку 504 Gateway Timeout

  1. Перезагрузите веб-страницу, нажав кнопку обновление / перезагрузка, в F5 или повторив URL-адрес из адресной строки.

Несмотря на то, что 504 Gateway Timeout и ошибка 502 Bad Gateway сообщает о неподконтрольной вам ошибке, проблема может быть временной. Просто перезагрузите страницу — это быстро и легко.

  1. Перезапустите все сетевые устройства. Временные проблемы с модемом, маршрутизатором, коммутаторами или другим сетевым оборудованием могут вызывать ошибку 504 Gateway Timeout . Простой перезапуск этих устройств может помочь.

Подсказка : При том, что порядок выключения этих устройств не важен, порядок включения их наоборот очень важен.

  1. Проверьте настройки прокси-сервера в своем браузере или приложении. Убедитесь, что они верны. Неправильные настройки прокси-сервера могут вызвать 504 ошибку.

Подсказка . Смотрите Proxy.org обновленный, проверенный список прокси-серверов, которые можно использовать.

Примечание . Большинство компьютеров не имеют настроек прокси-сервера, поэтому, если ваши настройки пусты, пропустите этот шаг.

  1. Измените DNS-сервер. Возможно, ошибка 504 Gateway Timeout , которую вы видите, вызвана проблемой с DNS-сервером , который вы используете.

Примечание . DNS-сервер , используемый сейчас, вероятно, автоматически назначается вашим провайдером. К счастью, для использования доступны другие DNS-сервера , которые можно выбрать.

Подсказка . Если не все сетевые устройства получают ошибку HTTP 504 или 502 error Bad Gateway , но все они находятся в одной сети, изменение DNS-сервера не сработает. Если это похоже на вашу ситуацию, переходите к следующей идее.

  1. Если изменений не произошло, обратитесь к сайту. Это единственное, что вы можете сделать. Велика вероятность, что администраторы сайта уже работают, чтобы исправить первопричину ошибки 504 Gateway Timeout .

На большинстве сайтов есть учетные записи социальных сетей, которые они используют для поддержки. А некоторые даже имеют номера телефонов и адреса электронной почты.

Подсказка . Если начинает казаться, что сайт выдает 504 ошибку для всех, поищите в Twitter в режиме реального времени информацию о недоступности сайта. Лучший способ сделать это — найти #websitedown в Twitter . Например, если Facebook может быть недоступен, выполните поиск по тегу #facebookdown .

  1. Обратитесь к своему интернет-провайдеру. Вероятнее всего, что после описанного выше устранения неполадок, выскакивающая 504 Gateway Timeout — это проблема, вызванная неполадками в Сети, за которую отвечает ваш провайдер.
  1. Вернуться позже. На данный момент вы исчерпали все варианты, и ошибка 504 Gateway Timeout устраняется администратором сайта или интернет-провайдером.

Регулярно проверяйте сайт. Без сомнения, он снова начнет работать.

Исправление ошибки 504 на вашем собственном сайте

В большинстве случаев это происходит не по вашей вине, но и не по вине пользователей вашего ресурса. Начните с проверки того, что сервер может правильно предоставлять доступ ко всем доменам, к которым требуют доступ ваши приложения.

Большие объемы трафика могут привести к тому, что ваш сервер будет выдавать ошибку 504 . Хотя 503 или ошибка 502 Bad Gateway будет более вероятна.

В частности, в WordPress сообщение 504: Gateway Timeout иногда возникает из-за поврежденных баз данных. Установите WP-DBManager и попробуйте применить функцию « Восстановить БД », а затем « Оптимизировать БД ». Посмотрите, поможет ли это.

Убедитесь, что ваш файл HTACCESS правильный. Особенно если вы только что переустановили WordPress .

Свяжитесь с технической поддержкой хостинга. Возможно, ошибка 504 , возвращаемая вашим сайтом, связана с проблемой на их стороне, которую они должны решить.

Больше способов увидеть ошибку 504

Ошибка Gateway Timeout при получении в Windows Update генерирует код ошибки 0x80244023 или сообщение WU_E_PT_HTTP_STATUS_GATEWAY_TIMEOUT .

В программах на базе Windows , которые изначально обращаются к интернету, ошибка 504 может отображаться в небольшом диалоговом окне или окне с ошибкой HTTP_STATUS_GATEWAY_TIMEOUT и/или сообщение The request was timed out waiting for a gateway ( истекло время ожидания запроса для шлюза ).

Менее распространенная ошибка 504 — это Gateway Time-out: The proxy server did not receive a timely response from the upstream server ( прокси-сервер не получил своевременного ответа от вышестоящего сервера ), но поиск и устранение неисправностей ( указанных выше ) продолжается.

Ошибки похожие на 504 Gateway Timeout

Ряд сообщений об ошибках аналогичен ошибке 504 Gateway Timeout , поскольку все они происходят на стороне сервера. Некоторые включают в себя ошибку 500 Internal Server (« Внутренняя ошибка сервера »), ошибку 502 Bad Gateway ( что это означает — «Неверный шлюз» ), и ошибку 503 Service Unavailable (« Сервис временно недоступен »), среди нескольких других.

Существуют также коды статуса HTTP , которые не являются серверными, а возникают на клиентской стороне. Например, часто встречающаяся ошибка 404 Not Found (« Страница не найдена »).

Данная публикация представляет собой перевод статьи « 504 Gateway Timeout Error » , подготовленной дружной командой проекта Интернет-технологии.ру

Илон Маск рекомендует:  Что такое код hw_docbyanchor
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL