Использование sse вместо websockets для однонаправленного потока данных через http / 2
Содержание:
Реализация WebSocket в браузерах
Для установки соединения клиентский скрипт создает объект WebSocket, в конструктор которого передает параметр WebSocket URI, и определяет функции обратного вызова при соединении, получении сообщения и разрыве соединения.
<html> <head> <script> const webSocket = new WebSocket('ws://localhost/echo'); webSocket.onopen = event => { alert('onopen'); webSocket.send("Hello Web Socket!"); }; webSocket.onmessage = event => { alert('onmessage, ' + event.data); }; webSocket.onclose = event => { alert('onclose'); }; </script> </head> <body> </body> </html>
В настоящее время WebSocket поддерживается в следующих браузерах:
- Google Chrome (начиная с версии 4.0.249.0);
- Apple Safari (начиная с версии 5.0.7533.16);
- Mozilla Firefox (начиная с версии 4);
- Opera (начиная с версии 10.70 9067);
- Internet Explorer (начиная с версии 10);
Резюме файла WSS
У нас есть четыре существующие программные обеспечения, связанные с файлами WSS (как правило это программное обеспечение от Microsoft Corporation, известное как Microsoft Windows), и их можно отнести к категории основных типов файлов четыре. Традиционно эти файлы имеют формат Microsoft Windows Sound System File .
Основная часть файлов WSS относится к System Files, однако они также могут относится к Game Files или Data Files.
Файлы WSS можно просматривать с помощью операционной системы Windows. Они обычно находятся на настольных компьютерах (и ряде мобильных устройств) и позволяют просматривать и иногда редактировать эти файлы.
Рейтинг популярности основного типа файла WSS составляет «Низкий», что означает, что эти файлы встречаются на стандартных настольных комьютерах или мобильных устройствах достаточно редко.
Установление WebSocket-соединения
Протокол работает над TCP.
Это означает, что при соединении браузер отправляет по HTTP специальные заголовки, спрашивая: «поддерживает ли сервер WebSocket?».
Если сервер в ответных заголовках отвечает «да, поддерживаю», то дальше HTTP прекращается и общение идёт на специальном протоколе WebSocket, который уже не имеет с HTTP ничего общего.
Пример запроса от браузера при создании нового объекта :
Описания заголовков:
- GET, Host
- Стандартные HTTP-заголовки из URL запроса
- Upgrade, Connection
- Указывают, что браузер хочет перейти на websocket.
- Origin
- Протокол, домен и порт, откуда отправлен запрос.
- Sec-WebSocket-Key
- Случайный ключ, который генерируется браузером: 16 байт в кодировке Base64.
- Sec-WebSocket-Version
- Версия протокола. Текущая версия: 13.
Все заголовки, кроме и , браузер генерирует сам, без возможности вмешательства JavaScript.
Такой XMLHttpRequest создать нельзя
Создать подобный XMLHttpRequest-запрос (подделать ) невозможно, по одной простой причине: указанные выше заголовки запрещены к установке методом .
Сервер может проанализировать эти заголовки и решить, разрешает ли он с данного домена .
Ответ сервера, если он понимает и разрешает -подключение:
Здесь строка представляет собой перекодированный по специальному алгоритму ключ . Браузер использует её для проверки, что ответ предназначается именно ему.
Затем данные передаются по специальному протоколу, структура которого («фреймы») изложена далее. И это уже совсем не HTTP.
Также возможны дополнительные заголовки и , описывающие расширения и подпротоколы (subprotocol), которые поддерживает данный клиент.
Посмотрим разницу между ними на двух примерах:
-
Заголовок означает, что браузер поддерживает модификацию протокола, обеспечивающую сжатие данных.
Это говорит не о самих данных, а об улучшении способа их передачи. Браузер сам формирует этот заголовок.
-
Заголовок говорит о том, что по WebSocket браузер собирается передавать не просто какие-то данные, а данные в протоколах SOAP или WAMP («The WebSocket Application Messaging Protocol»). Стандартные подпротоколы регистрируются в специальном каталоге IANA.
Этот заголовок браузер поставит, если указать второй необязательный параметр :
При наличии таких заголовков сервер может выбрать расширения и подпротоколы, которые он поддерживает, и ответить с ними.
Например, запрос:
Ответ:
В ответе выше сервер указывает, что поддерживает расширение , а из запрошенных подпротоколов – только SOAP.
Соединение можно открывать как или как . Протокол представляет собой WebSocket над HTTPS.
Кроме большей безопасности, у есть важное преимущество перед обычным – большая вероятность соединения. Дело в том, что HTTPS шифрует трафик от клиента к серверу, а HTTP – нет
Дело в том, что HTTPS шифрует трафик от клиента к серверу, а HTTP – нет.
Если между клиентом и сервером есть прокси, то в случае с HTTP все WebSocket-заголовки и данные передаются через него. Прокси имеет к ним доступ, ведь они никак не шифруются, и может расценить происходящее как нарушение протокола HTTP, обрезать заголовки или оборвать передачу.
А в случае с весь трафик сразу кодируется и через прокси проходит уже в закодированном виде. Поэтому заголовки гарантированно пройдут, и общая вероятность соединения через выше, чем через .
Пример чата
Давайте рассмотрим пример чата с использованием WebSocket API и модуля WebSocket сервера Node.js https://github.com/websockets/ws
Основное внимание мы, конечно, уделим клиентской части, но и серверная весьма проста
HTML: нам нужна форма для отправки данных и для отображения сообщений:
От JavaScript мы хотим 3 вещи:
- Открыть соединение.
- При отправке формы пользователем – вызвать для сообщения.
- При получении входящего сообщения – добавить его в .
Вот код:
Серверный код выходит за рамки этой главы. Здесь мы будем использовать Node.js, но вы не обязаны это делать. Другие платформы также поддерживают средства для работы с WebSocket.
Серверный алгоритм действий будет таким:
- Создать – набор сокетов.
- Для каждого принятого веб-сокета – добавить его в набор и поставить ему обработчик события для приёма сообщений.
- Когда сообщение получено: перебрать клиентов и отправить его всем.
- Когда подключение закрыто: .
Вот рабочий пример:
Вы также можете скачать его (верхняя правая кнопка в ифрейме) и запустить локально. Только не забудьте установить Node.js и выполнить команду до запуска.
Opening a websocket
When is created, it starts connecting immediately.
During the connection the browser (using headers) asks the server: “Do you support Websocket?” And if the server replies “yes”, then the talk continues in WebSocket protocol, which is not HTTP at all.
Here’s an example of browser headers for request made by .
- – the origin of the client page, e.g. . WebSocket objects are cross-origin by nature. There are no special headers or other limitations. Old servers are unable to handle WebSocket anyway, so there are no compabitility issues. But header is important, as it allows the server to decide whether or not to talk WebSocket with this website.
- – signals that the client would like to change the protocol.
- – the requested protocol is “websocket”.
- – a random browser-generated key for security.
- – WebSocket protocol version, 13 is the current one.
WebSocket handshake can’t be emulated
We can’t use or to make this kind of HTTP-request, because JavaScript is not allowed to set these headers.
If the server agrees to switch to WebSocket, it should send code 101 response:
Here is , recoded using a special algorithm. The browser uses it to make sure that the response corresponds to the request.
Afterwards, the data is transfered using WebSocket protocol, we’ll see its structure (“frames”) soon. And that’s not HTTP at all.
There may be additional headers and that describe extensions and subprotocols.
For instance:
-
means that the browser supports data compression. An extension is something related to transferring the data, functionality that extends WebSocket protocol. The header is sent automatically by the browser, with the list of all extensions it supports.
-
means that we’d like to transfer not just any data, but the data in SOAP or WAMP (“The WebSocket Application Messaging Protocol”) protocols. WebSocket subprotocols are registered in the IANA catalogue. So, this header describes data formats that we’re going to use.
This optional header is set using the second parameter of . That’s the array of subprotocols, e.g. if we’d like to use SOAP or WAMP:
The server should respond with a list of protocols and extensions that it agrees to use.
For example, the request:
Response:
Here the server responds that it supports the extension “deflate-frame”, and only SOAP of the requested subprotocols.
Реализуем часть протокола
Что бы в реализации сервера была какая то цель, нужно эту цель придумать. Целью кода данной статьи будет написание WebSocket сервера, который реализует часть протокола сокетов и позволяет переписываться нескольким клиентам из консоли браузера. Для начала нужно реализовать функционал опроса клиента с помощью управляющих фреймов Ping. Нам нужно знать, что клиент еще жив и готов принимать данные с сервера. Фрейм Ping, управляющий фрейм, но он так же может содержать данные. Когда клиент получит такое сообщение по сокету, он должен отправить на сервер фрейм Pong с теми данными, которые были во фрейме Ping. До реализации этого функционала, давайте пропишем в класс сервера необходимые константы
Далее реализуем наш метод по формированию фрейма Ping
По большому счету, в данном случае, это не требуется. Нам совершенно не обязательно пересылать какие-то данные клиенту вместе с управляющим фреймом Ping. Поэтому этот метод можно удалить, а вместо него в класс добавить еще одну константу. Также для того, чтобы реализовать функционал чата, нам потребуется хранить объекты подключений. Заведем под это отдельную коллекцию в классе сервера.
Модицифируем конструктор, добавим отправку фрейма Ping подключившимся клиентам с интервалом в 5 секунд, а также добавляем новых клиентов в коллекцию.
Теперь мы можем принимать соединения по сокетам и поддерживать его с помощью пингов. Осталось научить наш сервер маршрутизировать сообщения от клиентов. В спецификации к протоколу написано, что клиенты всегда должны отправлять сообщения на сервер в маскированном виде, а сообщения сервера всегда без маски. Из этого следует, что нам нужно раскодировать сообщение, а для этого нужно понять, что за сообщение пришло на сервер, получить маску, длину сообщения и сами данные. Напишем для этого метод
- В этой строке нам нужно получить длину данных внутри фрейма. Мы делаем это с помощью операции XOR и констранты, которая представляет число 128 в двоичном виде, которое выглядит как 10000000. В данном случае мы это делаем, исходя из того, что данные от клиента всегда приходят в маскированном виде, а значит первый бит этого байта всегда будет 1.
- Согласно спецификации для фреймов с длиной 126, длина сообщения передаётся в двух следующих байтах
- Согласно спецификации для фреймов с длиной 127, длина сообщения передаётся в восьми следующих байтах
С помощью этой функции мы можем получать всю необходимую информацию для обмена сообщениями между клиентами. Напишем метод, который будет демаскировать данные
Демаскирование происходит путем применения функции XOR к каждому байту данных и соответствующему ему байту маски. Длина маски указана в спецификации и составляет 4 байта. Теперь можно написать метод для отправки коротких сообщений по сокету клиенту.
Нам осталось финализировать конструктор класса. Добавим туда рассылку полученных сообщений от клиента всем активным клиентам, а также добавим отправку всем клиентам сообщения при подключении нового клиента.
Теперь можно запустить сервер. Для проверки работоспособности можно открыть две вкладки браузера и в консоли каждой вклдаки написать следующий код.
Затем отправить сообщение в одной из вкладок
Приостановка долгоживущих запросов
С Comet возникает еще одна проблема. Как серверу приостановить долгоживущий запрос без снижения производительности, а затем восстановить и выполнить его, как только на сервере произойдет событие?
Очевидно, нельзя просто задерживать запрос и ответ – это может привести к дефициту потоков и высокому потреблению памяти. Для приостановки запроса при ждущем опросе в среде неблокирующего ввода/вывода требуется специальный API. В Java такой API обеспечивает спецификация Servlet 3.0 (см. часть 1 этого цикла). Пример приведен в листинге 9.
Листинг 9. Определение асинхронного сервлета с помощью Servlet 3.0
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:j2ee="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml /ns/j2ee/web-app_3.0.xsd"> <servlet> <servlet-name>events</servlet-name> <servlet-class>ReverseAjaxServlet</servlet-class> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>events</servlet-name> <url-pattern>/ajax</url-pattern> </servlet-mapping> </web-app>
Определив асинхронный сервлет, можно использовать API Servlet 3.0 для приостановки и возобновления запроса, как показано в листинге 10.
Листинг 10. Приостановка и возобновление действия запроса
AsyncContext asyncContext = req.startAsync(); // Ссылка asyncContext где-то запоминается, // а затем, при необходимости, ее можно продолжить или завершить в другом потоке HttpServletResponse req = (HttpServletResponse) asyncContext.getResponse(); req.getWriter().write("data"); req.setContentType(); asyncContext.complete();
До появления Servlet 3.0 каждый контейнер должен был иметь (и до сих пор имеет) свой собственный механизм. Хорошо известным примером является Jetty Continuations; на Jetty Continuations опираются многие библиотеки Reverse Ajax в Java. При этом не обязательно запускать приложение в контейнере Jetty. API достаточно «умен», чтобы определить контейнер, с которым вы работаете, и вернуться к Servlet 3.0 API, если он есть, при запуске в другом контейнере, таком как Tomcat или Grizzly. Это справедливо для Comet, но если вы хотите воспользоваться преимуществами WebSockets, другого выбора, кроме использования функций, зависящих от контейнера, пока нет.
Спецификация Servlet 3.0 еще не вышла, но многие контейнеры уже реализуют этот API, так как это стандартный способ работы с Reverse Ajax.
Using the HTML5 WebSocket API
With the introduction of one succinct interface (see the following listing), developers can replace techniques such as long-polling and «forever frames,» and as a result further reduce latency.
interface WebSocket { readonly attribute DOMString URL; // ready state const unsigned short CONNECTING = 0; const unsigned short OPEN = 1; const unsigned short CLOSED = 2; readonly attribute unsigned short readyState; readonly attribute unsigned long bufferedAmount; // networking attribute Function onopen; attribute Function onmessage; attribute Function onclose; boolean send(in DOMString data); void close(); }; WebSocket implements EventTarget;
Utilizing the WebSocket interface couldn’t be simpler. To connect to an end-point, just create a new WebSocket instance, providing the new object with a URL that represents the end-point to which you wish to connect, as shown in the following example. Note that a ws:// and wss:// prefix are proposed to indicate a WebSocket and a secure WebSocket connection, respectively.
var myWebSocket = new WebSocket("ws://www.websockets.org");
A WebSocket connection is established by upgrading from the HTTP protocol to the WebSockets protocol during the initial handshake between the client and the server. The connection itself is exposed via the «onmessage» and «send» functions defined by the WebSocket interface.
Before connecting to an end-point and sending a message, you can associate a series of event listeners to handle each phase of the connection life-cycle as shown in the following example.
myWebSocket.onopen = function(evt) { alert("Connection open ..."); }; myWebSocket.onmessage = function(evt) { alert( "Received Message: " + evt.data); }; myWebSocket.onclose = function(evt) { alert("Connection closed."); };
To send a message to the server, simply call «send» and provide the content you wish to deliver. After sending the message, call «close» to terminate the connection, as shown in the following example. As you can see, it really couldn’t be much easier.
myWebSocket.send("Hello WebSockets!"); myWebSocket.close();
Low-level API¶
Exceptions
- exception
-
Exception raised when a handshake request or response is invalid.
- exception
-
Exception raised when an operation is forbidden in the current state.
- exception
-
Exception raised when an URI is invalid.
Opening handshake
The module deals with the WebSocket opening
handshake according to .
It provides functions to implement the handshake with any existing HTTP
library. You must pass to these functions:
- A set_header function accepting a header name and a header value,
- A get_header function accepting a header name and returning the header
value.
The inputs and outputs of get_header and set_header are
objects containing only ASCII characters.
Some checks cannot be performed because they depend too much on the
context; instead, they’re documented below.
To accept a connection, a server must:
- Read the request, check that the method is GET, and check the headers with
, - Send a 101 response to the client with the headers created by
if the request is valid; otherwise, send a 400.
To open a connection, a client must:
- Send a GET request to the server with the headers created by
, - Read the response, check that the status code is 101, and check the headers
with .
- (set_header)
-
Build a handshake request to send to the server.
Return the key which must be passed to .
- (get_header)
-
Check a handshake request received from the client.
If the handshake is valid, this function returns the key which must be
passed to .Otherwise, it raises an exception and the server
must return an error, usually 400 Bad Request.This function doesn’t verify that the request is an HTTP/1.1 or higher GET
request and doesn’t perform Host and Origin checks. These controls are
usually performed earlier in the HTTP request handling code. They’re the
responsibility of the caller.
- (set_header, key)
-
Build a handshake response to send to the client.
key comes from .
- (get_header, key)
-
Check a handshake response received from the server.
key comes from .
If the handshake is valid, this function returns .
Otherwise, it raises an exception.
This function doesn’t verify that the response is an HTTP/1.1 or higher
response with a 101 status code. These controls are the responsibility of
the caller.
Data transfer
The module implements data framing as specified in
.
It deals with a single frame at a time. Anything that depends on the sequence
of frames is implemented in .
- class (fin, opcode, data)
-
-
Alias for field number 2
-
Alias for field number 0
-
Alias for field number 1
-
- (reader, mask, *, max_size=None)
-
Read a WebSocket frame and return a object.
reader is a coroutine taking an integer argument and reading exactly this
number of bytes, unless the end of file is reached.mask is a telling whether the frame should be masked, ie.
whether the read happens on the server side.If max_size is set and the payload exceeds this size in bytes,
is raised.This function validates the frame before returning it and raises
if it contains incorrect values.
- (frame, writer, mask)
-
Write a WebSocket frame.
frame is the object to write.
writer is a function accepting bytes.
mask is a telling whether the frame should be masked, ie.
whether the write happens on the client side.This function validates the frame before sending it and raises
if it contains incorrect values.
- (data)
-
Parse the data in a close frame.
Return (code, reason) when code is an and reason a
.Raise or if the
data is invalid.
- (code, reason)
-
Serialize the data for a close frame.
This is the reverse of .
URI parser
The module implements parsing of WebSocket URIs
according to .
- (uri)
-
This function parses and validates a WebSocket URI.
If the URI is valid, it returns a namedtuple (secure, host, port,
resource_name)Otherwise, it raises an exception.
2013
WSS Docs 4.3
1 ноября 2013 года компания WSS-Consulting анонсировала версию WSS Docs 4.3. Обновленное решение обеспечивает, по сравнению с предыдущей версией системы, оптимизированную обработку документов.
Новшества
Сокращено время ожидания ответа от системы при работе с 50 млн. документов до 1,5 секунд.
В новой версии WSS Docs реализованы все типовые бизнес-процессы, которые часто действуют в компании. электронный документооборот включает в себя работу с договорами и дополнительными соглашениями, приказами и распоряжениями, служебными записками, счетами на оплату, входящими/исходящими документами, протоколами совещаний, поручениями, нормативными документами или документами со свободной маршрутизацией.
Система помогает пользователям в разработке и настройке любых бизнес-процессов без использования программирования, используя только возможности настройки. Помимо этого, для удобства пользователей была произведена интеграция системы с Outlook, вследствие чего появилась возможность принятия решений «прямо из письма», что сильно упростило процедуру работы с документами.
В WSS Docs 4.3 предусмотрена возможность объединения филиалов компании или компаний холдинга в рамках единой СЭД. В обновленном решении доступен режим «Федерация», в котором серверы могут быть установлены в различных компаниях холдинга, однако благодаря прозрачной синхронизации всех документов компании, будут работать в едином информационном пространстве СЭД.
Доступность
Представление продукта ожидается в конце ноября 2013 года.
https://youtube.com/watch?v=DFFbta0a2NQ
Функциональность и особенности WSS Docs 4.0
Система электронного документооборота WSS Docs 4.0, в коробочном варианте, автоматизирует процессы делопроизводства и документооборота:
- Регистрация входящих документов
- Подготовка и регистрация исходящих документов
- Согласование и регистрация приказов и распоряжений
- Контроль поручений по документам
- Регистрация протоколов совещаний
- Подготовка и регистрация служебных и объяснительных записок
- Согласование договоров
- Согласование заявок на оплату
- Архив нормативно-справочной информации
Основа системы — WSS Workflow for SharePoint, она позволяет:
- Изменять и создавать новые процессы обработки документов
- Создавать жесткие и гибкие маршруты движения документов
- Существенно изменять функционал системы, не прибегая к программированию
Система электронного документооборота WSS Docs — «коробочное» решение, с базовым набором функциональных возможностей и процессов, необходимых для организации электронного делопроизводства и документооборота.
Среди особенностей продукта:
Автоматизация документооборота в территориально-распределенных компаниях и холдингах
- Возможность настройки различных процессов документооборота в компаниях холдинга
- Модули СЭД различных компаний тесно интегрируются в рамках единой системы
- Типовые процессы движения документов учитывают холдинговую структуру
Функционирование в гибкой среде
- Функционал, позволяющий решению функционировать в ситуации изменения структуры компании и штатного расписания
- Динамическая система заместителей
- Возможность изменения маршрута документа «на лету»
Быстродействие и масштабирование
- Функционирование на типовом сервере позволяет проводить 4 тыс. документов в день
- При подключении дополнительного сервера производительность системы возрастает на 3 тыс. документов в день
Гибкость, открытость и расширяемость
- Возможности изменения процессов обработки документов для соответствия потребностям бизнеса
- Расширяемость системы благодаря открытой архитектуре и возможностям SharePoint
Технические требования
Microsoft Windows Server 2008/Windows Server 2012
- SharePoint
- Microsoft SharePoint Server 2010/2013
- SharePoint Foundation 2010 (бесплатная платформа, входит в состав Windows Server 2008)
- SQL Server
- SQL Server 2005/2008 (Standard или Enterprise)
- либо SQL Server 2012 (для высоконагруженных решений)
About HTML5 WebSocket
The HTML5 WebSockets specification defines an API that enables web pages to use the WebSockets protocol for two-way communication with a remote host. It introduces the WebSocket interface and defines a full-duplex communication channel that operates through
a single socket over the Web. HTML5 WebSockets provide an enormous reduction in unnecessary network traffic and latency compared to the unscalable polling and long-polling solutions that were used to simulate a full-duplex connection by maintaining
two connections.
HTML5 WebSockets account for network hazards such as proxies and firewalls, making streaming possible over any connection, and with the ability to support upstream and downstream communications over a single connection, HTML5 WebSockets-based applications
place less burden on servers, allowing existing machines to support more concurrent connections. The following figure shows a basic WebSocket-based architecture in which browsers use a WebSocket connection for full-duplex, direct communication
with remote hosts.
One of the more unique features WebSockets provide is its ability to traverse firewalls and proxies, a problem area for many applications. Comet-style applications typically employ long-polling as a rudimentary line of defense against firewalls and proxies.
The technique is effective, but is not well suited for applications that have sub-500 millisecond latency or high throughput requirements. Plugin-based technologies such as Adobe Flash, also provide some level of socket support, but have long
been burdened with the very proxy and firewall traversal problems that WebSockets now resolve.
A WebSocket detects the presence of a proxy server and automatically sets up a tunnel to pass through the proxy. The tunnel is established by issuing an HTTP CONNECT statement to the proxy server, which requests for the proxy server to open a TCP/IP connection
to a specific host and port. Once the tunnel is set up, communication can flow unimpeded through the proxy. Since HTTP/S works in a similar fashion, secure WebSockets over SSL can leverage the same HTTP CONNECT technique. Note that WebSockets
are just beginning to be supported by modern browsers (Chrome now supports WebSockets natively). However, backward-compatible implementations that enable today’s browsers to take advantage of this emerging technology are available.
WebSockets—like other pieces of the HTML5 effort such as Local Storage and Geolocation—was originally part of the HTML5 specification, but was moved to a separate standards document to keep the specification focused. WebSockets has been submitted to the
Internet Engineering Task Force (IETF) by its creators, the Web Hypertext Application Technology Working Group (WHATWG). Authors, evangelists, and companies involved in the standardization still refer to the original set of features, including
WebSockets, as «HTML5.»
HTTP Streaming
HTTP Streaming — provides a long-lived connection for instant and continuous data push (Image from realtimeapi.io)
The client makes an HTTP request, and the server trickles out a response of indefinite length (it’s like polling infinitely).HTTP streaming is performant, easy to consume and can be an alternative to WebSockets.
Issue: Intermediaries can interrupt the connection (e.g. timeout, intermediaries serving other requests in a round-robin manner). In such cases, it cannot guarantee the complete realtimeness.
00:00:00 CLIENT-> I need cakes 00:00:01 SERVER-> Wait for a moment.00:00:01 SERVER-> Cake-1 is in process.00:00:02 SERVER-> Have cake-1.00:00:02 SERVER-> Wait for cake-2.00:00:03 SERVER-> Cake-2 is in process.00:00:03 SERVER-> You must be enjoying cake-1.00:00:04 SERVER-> Have cake-2.00:00:04 SERVER-> Wait for cake-3.00:00:05 CLIENT-> Enough, I'm full.
История
Первая версия, названная SharePoint Team Services (обычно сокращается до аббревиатуры STS), была выпущена в одно время с Office XP и была доступна как часть Microsoft FrontPage. STS могла работать под Windows 2000 Server или Windows XP.
Windows SharePoint Services 2.0 была выпущена как обновление SharePoint Team Services, но фактически являлось полностью переработанным приложением [источник не указан 3252 дня]. SharePoint Team Services хранит документы как обычное файловое хранилище, сохраняя метаданные документа в базе данных. Причем Windows SharePoint Services 2.0 хранит как документы, так и метаданные в БД, а также поддерживает базовый документный контроль версий для элементов в библиотеке документов. Service Pack 2 для WSS добавлял поддержку SQL Server 2005 и использование .NET Framework 2.0.
Windows SharePoint Services 3.0 было выпущено 16 ноября 2006 года как часть комплекта Microsoft Office 2007 и Windows Server 2008. WSS 3.0 был создан с использованием .NET Framework 2.0 и .NET Framework 3.0 Windows Workflow Foundation для добавления возможностей контроля последовательности выполняемых действий в базовый пакет. В начале 2007 года WSS 3.0 стало доступно для общественности. Windows 2000 Server уже не поддерживается WSS 3.0.
WSS версии 3 означает значительное «взросление» продукта. Версия 3 поддерживает больше возможностей, наиболее используемых в решениях Web 2.0, как например, блоги, вики и RSS-потоки.
Microsoft начиная с версии 4.0 изменила название на SharePoint Foundation 2010.