Простой websocket-чат на dart

Рукопожатие

Для того, чтобы клиент смог установить соединение с сервером, по протоколу WebSocket, нужно перевести http сервер в этот режим работы. Чтобы это сделать, нужно отправить GET запрос со специальными заголовками. Но чтобы понять, какие заголовки отправляются на сервер из браузера, при попытки установить сокетное соединение, не будем сразу смотреть в спецификацию к протоколу, а начнем писать сервер и увидем эти заголовки в консоли. Для начала напишем http сервер, который будет принимать любой запрос и выводить в консоль заголовки этого запроса. Код я буду писать на typescript и запускать с помощью ts-node.

Сервер будет запущен на порту 8080. Теперь откроем консоль разработчика в браузере и напишем следующий код.

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

  • — установка соединения
  • 1 — соединение установлено. Данные можно передавать
  • 2 — соединение находится в процессе закрытия
  • 3 — соединение закрыто

В консоли с запущенным сервером получим следующее:

  • sec-websocket-version версия проткола. На текущий момент это 13я версия
  • sec-websocket-extensions список расширений протокола, которые хочет использовать клиент. В данном случае, это сжатие сообщений
  • sec-websocket-protocol в этом заголовки клиент может передать список подпротоколов, на которых клиент хочет общаться с сервером. При этом сервер, если поддерживает эти подпротоколы, должен выбрать один из переданных и отправить его название в заголовках ответа. Подпротокол — это формат данных, в котором будут отправляться и приниматься сообщения.
  • sec-websocket-key самый важный заголовок для установки подключения. В нем передаётся случайный ключ. Этот ключ должен быть уникальным для каждого рукопожатия.

Чтобы клиент понял, что сервер успешно перешел на нужный протокол, сервер должен ответить кодом 101, а в ответе должен быть заголовок sec-websocket-accept, значение которого сервер должен сформировать, используя заголовок sec-websocket-key следующим образом:

  1. Добавить к заголовку sec-websocket-key константу 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
  2. Получить хеш sha-1 полученного объединенного значения
  3. Перевести полученный хеш в строку в кодировке base64

Так же сервер должен передать в заголовках ответа заголовки Upgrade: WebSocket и Connection: Upgrade. Звучит не сложно, давайте реализуем. Для генерации загловка sec-websocket-key нам потребуется встроеный в node.js модуль crypto. Необходимо в начале импортировать его.

А затем изменить конструктор класса SocketServer

У http сервера Node.js есть специальное событие на upgrade соединения, используем его. Перезапустив сокет сервер с этими изменениями и снова попытавшись создать соединение в браузере, мы получим объект сокета, который будет в состоянии 1. Мы успешно создали соединение с нашим сервером и завершили первый этап. Переёдем ко второму.

Или getting started with WebSocket PHP без phpDaemon

Здравствуйте! Простите за столь длинный заголовок, но, надеюсь, что новичкам вроде меня будет легче найти эту статью, ведь мне ничего подобного найти не удалось. Несколько недель назад я принял решение переработать игровой клиент и сервер своей игры Growing Crystals с AJAX, на WebSocket, но всё оказалось не просто непросто, а очень сложно. Поэтому я и решил написать статью, которая бы помогла самым что ни на есть начинающим разработчикам на WebSocket + PHP сэкономить несколько дней времени, максимально подробно объясняя каждый свой шаг по настройке и запуску первого WebSocket скрипта на PHP.

Что у меня есть: Денвер на локальной машине, на нём я веду разработку проекта и дешевый PHP хостинг, на котором я публикую свой проект для того, чтобы получить обратную связь от Интернет-пользователей.

Что я хочу: Без установки phpDaemon (phpd), NodeJS и прочих вещей на локальную машину и хостинг, продолжить разработку своего проекта, но теперь с WebSocket, в этой статье разберем простой WebSocket эхо сервер.

Чего я не хочу: Говоря о NodeJS, не хочется переписывать серерную логику с PHP на другой язык, тем более устанавливать NodeJS, хотя и люблю JavaScript больше чем PHP.

Важно: не путайте демона написанного на php, с фреймворком асинхронных приложений phpDaemon. Который, конечно же, обязательно потребуется в случае развития проекта и многократного роста нагрузки на хостинг

Но для начала работы с WebSocket на дешевом хостинге можно обойтись и без него.

WebSocket compression

The extension is disabled by default on the server and enabled by default on the
client. It adds a significant overhead in terms of performance and memory
consumption so we suggest to enable it only if it is really needed.

Note that Node.js has a variety of issues with high-performance compression,
where increased concurrency, especially on Linux, can lead to catastrophic
memory fragmentation and slow performance. If you intend to use
permessage-deflate in production, it is worthwhile to set up a test
representative of your workload and ensure Node.js/zlib will handle it with
acceptable performance and memory usage.

See for more options.

const WebSocket = require('ws');

const wss = new WebSocket.Server({
  port: 8080,
  perMessageDeflate: {
    zlibDeflateOptions: {
      // See zlib defaults.
      chunkSize: 1024,
      memLevel: 7,
      level: 3
    },
    zlibInflateOptions: {
      chunkSize: 10 * 1024
    },
    // Other options settable:
    clientNoContextTakeover: true, // Defaults to negotiated value.
    serverNoContextTakeover: true, // Defaults to negotiated value.
    serverMaxWindowBits: 10, // Defaults to negotiated value.
    // Below options specified as default values.
    concurrencyLimit: 10, // Limits zlib concurrency for perf.
    threshold: 1024 // Size (in bytes) below which messages
    // should not be compressed.
  }
});

The client will only use the extension if it is supported and enabled on the
server. To always disable the extension on the client set the
option to .

const WebSocket = require('ws');

const ws = new WebSocket('ws://www.host.com/path', {
  perMessageDeflate: false
});

Chat example

Let’s review a chat example using browser WebSocket API and Node.js WebSocket module https://github.com/websockets/ws. We’ll pay the main attention to the client side, but the server is also simple.

HTML: we need a to send messages and a for incoming messages:

From JavaScript we want three things:

  1. Open the connection.
  2. On form submission – for the message.
  3. On incoming message – append it to .

Here’s the code:

Server-side code is a little bit beyond our scope. Here we’ll use Node.js, but you don’t have to. Other platforms also have their means to work with WebSocket.

The server-side algorithm will be:

  1. Create – a set of sockets.
  2. For each accepted websocket, add it to the set and setup event listener to get its messages.
  3. When a message received: iterate over clients and send it to everyone.
  4. When a connection is closed: .

Here’s the working example:

You can also download it (upper-right button in the iframe) and run locally. Just don’t forget to install Node.js and before running.

Закрытие подключения

Обычно, когда сторона хочет закрыть соединение (браузер и сервер имеют равные права), они отправляют «фрейм закрытия соединения» с кодом закрытия и указывают причину в виде текста.

Метод для этого:

  • – специальный WebSocket-код закрытия (не обязателен).
  • – строка с описанием причины закрытия (не обязательна).

Затем противоположная сторона в обработчике события получит и код и причину , например:

– это не любое число, а специальный код закрытия WebSocket.

Наиболее распространённые значения:

  • – по умолчанию, нормальное закрытие,
  • – невозможно установить такой код вручную, указывает, что соединение было потеряно (нет фрейма закрытия).

Есть и другие коды:

  • – сторона отключилась, например сервер выключен или пользователь покинул страницу,
  • – сообщение слишком большое для обработки,
  • – непредвиденная ошибка на сервере,
  • …и так далее.

Полный список находится в .

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

Оповещение пользователя

Если кликнуть по имени пользователя, то имя вставляется в поле ввода сообщения и заворачивается в фигурные скобки: «{» и «}».

На сервере имеется паттерн обработки такого текста (функция $worker->onMessage), который заменяет фигурные скобки на теги «<b>» и «</b>», выделяя текст жирным шрифтом.

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

void Widget::onPublicMessage(int userId,
                             const QString &userName,
                             const QString &userColor,
                             const QString &text)
{
    if (text.contains("" + m_userName + "")) {
        qApp->beep();
        qApp->alert(this);
    }

    QString html = QString("%1 %3:"
                           " %4")
            .arg(datetime())
            .arg(userColor)
            .arg(userName)
            .arg(text)
            .arg(userId);

    ui->textBrowser->append(html);
}

По такой же схеме можно реализовать полноценную поддержку markdown, вставку смайликов и картинок. 

Расширяя функционал сервера и клиента можно также добавить:

  • поддержку чат-комнат и полноценных приватных диалогов;
  • сохранении истории сообщений в БД и её отправку при подключении или по запросу;
  • статусы пользователей («Работаю», «Отдыхаю», «Отошёл» и др.);
  • звуковые уведомления «Послать сигнал»;
  • редактирование и удаление сообщений;
  • цитирование сообщений других пользователей;
  • передачу файлов.

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

Добавление веб-сокетов в Денвер

Теперь задача настроить Денвер. Мне довелось работать с разными сборками Денвера. Последняя из них Denwer3_Base_2013-06-02_a2.2.22_p5.3.13_m5.5.25_pma3.5.1_xdebug.exe, к сожалению, она и другие имеющиеся в настоящий момент сборки Денвера(дело в PHP) не поддерживают сокеты по умолчанию.

Но эта проблема решается путём поиска и установки подходящей php_sockets.dll. Для того, чтобы всё заработало, достаточно разместить dll файл в каталоге Денвера \usr\local\php5\ext\php_sockets.dll и отредактировать файл \usr\local\php5\php.ini убрав точку с запятой перед строкой

extension=php_sockets.dll

перезагрузить Денвер и всё, или почти всё: в некоторых случаях при перезагрузке Денвера может возникнуть ошибка

это значит что вы используете не подходящую версию файла php_sockets.dll. Чтобы облегчить поиски предлагаю две версии – одна гарантированно подходит для PHP 5.2.12 (скачать), а вторая для гарантированно подходит для PHP 5.3.13 (скачать). Но если вам не подошел ни один из этих файлов, предлагаю скачать полный архив соответствующей версии php для windows с веб-сайта php.net и найти в архиве файл php_sockets.dll, который точно подойдёт.

Теперь можете запустить файлик sockettest.php через браузер и увидеть заветную строку “WebSockets OK”, означающую что всё необходимое для работы с Web-Socket установлено и работает хорошо.

Сервер

Чат будет работать по такому принципу: сообщения между сервером и клиентом передаются в формате JSON с указанием, какое «действие» (action) выполняет это сообщение. Таким образом можно разделить сообщения на типы: служебные, публичные, приватные и т.д., и с лёгкостью дополнять различные типы служебной и иной сопутствующей информацией.

Такой подход позволит в будущем при необходимости произвести «безболезненную» модернизацию чата. Например, если сервер начнёт отправлять сообщения неизвестного действия, то клиент просто не будет на них реагировать, но можно оповестить пользователя о том, что он использует устаревшую версию клиента.

Наш простейший чат будет поддерживать следующие действия:

  • авторизация пользователя 

    action = Authorized
    При подключении пользователя к чату сервер предварительно проверяет свободность выбранного никнейма. Если никнейм занят, то приписываем к нему номер (2, 3, 4 и т.д.). Если никнейм свободен, то отправляем пользователю сообщение «Authorized», в котором передаются данные, с которыми он был авторизован в чате и список пользователей чата.
    Дополнительно пользователь может выбрать цвет отображения своего имени и указать, к какому полу (М/Ж) относится.

  • оповещение всех пользователей о присоединении нового участника к чату

    action = Connected
    После авторизации нового пользователя сервер отправляет всем участникам сообщение «Connected», в котором передаются данные авторизованного пользователя.

  • оповещение всех пользователей при выходе участника из чата

    action = Disconnected
    При выходе пользователя из чата все участники оповещаются сообщением «Disconnected».

  • отправка сообщения в общий чат

    action = PublicMessage
    Если пользователь отправляет сообщение в чат без указания адресата, то такое сообщение определяется как «Публичное» и рассылается всем участникам.

  • отправка приватного сообщения

    action = PrivateMessage
    Если пользователь отправляет сообщение в чат с указанием адресата, то такое сообщение определяется как «Приватное» и отправляется только адресату.

  • проверка пользователей на потерю соединений

    action = Ping
    Сервер рассылает всем участникам служебное сообщение «Ping» с определённым интервалом и ожидает от каждого ответное сообщение «Pong».

  • оповещение пользователей о потере соединения участником

    action = ConnectionLost
    Если сервером несколько раз подряд не будет получено ответное на «Ping» сообщение от участника, то участник считается отключившимся, всем остальным участникам рассылается сообщение «ConnectionLost» с данными “отвалившегося” пользователя.

Summary

WebSocket is a modern way to have persistent browser-server connections.

  • WebSockets don’t have cross-origin limitations.
  • They are well-supported in browsers.
  • Can send/receive strings and binary data.

The API is simple.

Methods:

  • ,
  • .

Events:

  • ,
  • ,
  • ,
  • .

WebSocket by itself does not include reconnection, authentication and many other high-level mechanisms. So there are client/server libraries for that, and it’s also possible to implement these capabilities manually.

Sometimes, to integrate WebSocket into existing project, people run WebSocket server in parallel with the main HTTP-server, and they share a single database. Requests to WebSocket use , a subdomain that leads to WebSocket server, while goes to the main HTTP-server.

Surely, other ways of integration are also possible.

Создание приложения исполняемым

Несмотря на то, что пакет этого сервиса может быть в составе web-приложения и
WAR файлов,
более простой подход, продемонстрированный ниже создает отдельное самостоятельное приложение.
Вы упаковываете все в единый, исполняемый JAR-файл, который запускается через хорошо знакомый
старый Java-метод. Попутно, вы используете поддержку Spring для встроенного
Tomcat
контейнера сервлетов как HTTP среду выполнения вместо развертывания на сторонний экземпляр.

Метод передает управление вспомогательному классу
, предоставляя
как аргумент его методу. Это говорит Spring о том, чтобы
прочитать аннотацию метаданных из и управлять им
как компонентом в Spring Application Context.

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

Сборка исполняемого JAR

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

Затем вы можете запустить JAR-файл:

Если вы используете Maven, вы можете запустить приложение, используя ,
либо вы можете собрать приложение с и запустить JAR примерно так:

Процедура, описанная выше, создает исполняемый JAR. Вы также можете вместо него
собрать классический WAR-файл.

Если вы используете Gradle, вы можете запустить ваш сервис из командной строки:

Если вы используете Maven, то можете запустить ваш сервис таким образом:
.

Как вариант, вы можете запустить ваш сервис напрямую из Gradle примерно так:

С mvn — .

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

Basic example¶

Here’s a WebSocket server example.

It reads a name from the client, sends a greeting, and closes the connection.

#!/usr/bin/env python

# WS server example

import asyncio
import websockets

async def hello(websocket, path):
    name = await websocket.recv()
    print(f"< {name}")

    greeting = f"Hello {name}!"

    await websocket.send(greeting)
    print(f"> {greeting}")

start_server = websockets.serve(hello, "localhost", 8765)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

On the server side, executes the handler coroutine
once for each WebSocket connection. It closes the connection when the handler
coroutine returns.

Here’s a corresponding WebSocket client example.

#!/usr/bin/env python

# WS client example

import asyncio
import websockets

async def hello():
    uri = "ws://localhost:8765"
    async with websockets.connect(uri) as websocket
        name = input("What's your name? ")

        await websocket.send(name)
        print(f"> {name}")

        greeting = await websocket.recv()
        print(f"< {greeting}")

asyncio.get_event_loop().run_until_complete(hello())

Полезные функции для манипуляций с сокетами в PHP

  • socket_accept(socketObject) — после запроса принимает соединение на стороне сервера для текущего сокета, который вставляется в параметр;
  • socket_create_listen(port, connect_count) — принимает соединение на указанном порту первого параметра, а второй параметр указывает сколько максимум может быть в очереди ожидающих соединений;
  • socket_get_option(socketObject, level_of_protocol, option) — получает параметры потока при соединении, где второй параметр указывается уровень протокола, на котором расположена опция из третьего параметра. Третий параметр использует одну из предопределенных констант, хранящих значения опций, ознакомиться с которыми можно в документации к PHP. Функция возвращает значение константы опции, при ошибке возвращает false;
  • socket_last_error(socketObject) — возвращает последнюю возникшую ошибку при сбое соединения в числовом формате;
  • socket_listen(socketObject, connect_count) — прослушивает соединения с сервером, после того как сокет был создан, а клиент присоединен к серверу. Второй параметр указывает максимальное количество ожидаемых соединений, которых может находиться в очереди. В случае успеха возвращает true, или false при ошибке;
  • socket_send(socketObject, sending_data, length) — отправляет данные клиенту, который подсоединился к сокету. Третий параметр указывает максимальное количество байт, которые будут отправлены на сервер. Возвращает количество отправленных байтов или false;
  • socket_sendto(socketObject, sending_data, length, adress, port) — отправка сообщения длиной length по адресу address через порт port посредством сокет-протокола даже при отсутствии подключения;
  • socket_set_block(socketObject) — включает режим блокировки отправки данных до тех пор, пока сокет не получит сигнал на отправку данных – работа скрипта на сервере будет приостановлена. В случае ошибки блокировки соединения будет возвращено false;
  • socket_set_option(socketObject, level_of_protocol, option) — настраивает параметры сокета. Последний параметр принимает только одну из предусмотренных в PHP констант;
  • socket_strerror(code_of_error) — возвращает ошибку в формате строки. В параметр записывается код ошибки после выполнения функции socket_last_error();
  • socket_write(socketObject, data, length) – осуществляет запись данных в сокет. Необязательный параметр length позволяет установить ограничение на размер записываемых данных, который указывается в количестве байт. Возвращает количество байт, записанных в сокет или false, в случае возникновения ошибки.

Детальнее о работе сокетов

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

Клиент устанавливает соединение с сервером, который отвечает взаимностью — выразить это можно в рукопожатии:

  1. Клиент отправляет HTTP запрос с дополнительным заголовком upgrade, который сообщает, что соединение должно установиться по сокету.
  2. Сервер принимает запрос и отправляет ответ по HTTP с таким же дополнительным заголовком.
  3. Рукопожатие осуществлено и теперь между клиентом и сервером сохраняется постоянное соединение на время сессии по сокету.
  4. Основой для такого соединения выступает TCP/IP.
  5. Клиент и сервер могут обмениваться данными в обход HTTP.
  6. Само собой, обмен может осуществляться и по HTTP.
  7. Суть в том, что один функционал приложения работает с сокетами, другой с HTTP.

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

  • GET/POST ws://mediacontent.buisness.com/ HTTP/1.1 — стандартный HTTP заголовок, который формируется через URL запрос;
  • Origin: http://buisness.com — Описывает протокол, домен и порт, куда отправляется запрос;
  • Connection: Upgrade — указывает, что браузер хочет установить соединение через сокет;
  • Host: mediacontent.buisness.com — указывает имя сервера;
  • Upgrade: websocket — протокол соединения.
  • Sec-WebSocket-Key: Iv8op/8s+lYFgNBcXmNP8Q= — ключ безопасного соединения, который позволяет браузеру убедиться, что ответ предназначен для него;

Заголовок ответа, отправляемый сервером:

  • HTTP/1.1 101 Switching Protocols;
  • Date: Fri, 12 Oct 2020 10:37:20 GMT;
  • Connection: Upgrade;
  • Upgrade: WebSocket;
  • Sec-WebSocket-Accept: hhFluiDokk24srzEOFBUlVSlC2g=== — ключ безопасного соединения, который позволяет браузеру убедиться, что ответ предназначен для него;
  • Sec-WebSocket-Version: 13 — версия протокола.

После того, как соединение между клиентом и сервером установлено, передача данных осуществляется по протоколу WS, в обход HTTP. При этом, соединение поддерживается постоянно до закрытия окна (окончания сессии).

В зависимости от версии сервера, браузера или сложности скрипта, могут отправляться и дополнительные заголовки:

Sec-WebSocket-Extensions: deflate-frame. Говорит о том, что браузером поддерживается сжатие для данных. Если объект WebSocket модифицирован, что относится к последним версиям браузеров, то и заголовки также расширены. Этот заголовок отправляет информацию о том, какие расширения поддерживает браузер.

Sec-WebSocket-Protocol: soap, wamp. Браузер предупреждает сервер о том, что будут отправляться не только стандартные данные, но и данные, которые поддерживают протоколы SOAP и WAMP. Заголовок описывает формат данных, которые клиент и сервер будут отправлять друг другу. Значения данных заголовков устанавливаются не автоматически, а передаются вызов конструктора:

Компоненты распознавания и печати штрих-кодов Промо

Комплект программного обеспечения для реализации функций оптического распознавания штрих-кодов различных систем при помощи обычной web-камеры, а также их отображения в печатных формах. Программы могут работать в составе конфигураций, созданных на базе платформ «1С-Предприятие» версий 7.7, 8.2, 8.3. Компонент чтения кодов реализован в виде внешней компоненты 1С с COM-интерфейсом. Компонент отображения создан по стандартной технологии ActiveX для Windows, и может быть встроен в любое приложение, поддерживающее встраивание ActiveX элементов управления, например в документ Word или Excel, или форму VBA.

P.S. Добавлена новая версия программы распознавания. Новые функции: обработка видео в реальном режиме (а не по таймеру, как раньше), добавлена возможность распознавания штрих-кодов из графических файлов JPEG, PNG, GIF, BMP, а также передавать для распознавания картинки из 1С, теперь можно получить в 1С захваченное с камеры или файла изображение, как с выделением мест, содержащих коды, так и без, а также отдельные фрагменты изображений, содержащие код. Добавлены новые свойства и методы для программирования. Обновлена документация.

10 стартмани

Функции и особенности WSS Consultant O365:

  • Создание прозрачного процесса управления отделами/сотрудниками.
  • Адаптация процессов совместной работы с документами в рамках обращения: создание документов из шаблонов, отслеживание этапов движения документов.
  • Настройка удалённой работы сотрудников в ресурсе: доступ к информации (документы, файлы, аудио), возможность аудио/видеоконференций.
  • Автоматизация системы аналитики, настройка конструктора отчётов.
  • Создание централизованного хранилища документов.
  • Эффективность и простота создания обращения.
  • Простой и понятный интерфейс с возможностью отслеживания состояния задач.
  • Организация эффективной коммуникации с исполнителями.
  • Адаптированный интерфейс для мобильных устройств.
  • Возможность организовать совместную работу с документами в рамках обращения.

Для всех пользователей, будет доступен корпоративный портал, в котором можно просмотреть актуальные корпоративные новости, просмотреть ближайшие мероприятия, поднять тему на форуме, а также получить доступ к базе всех внутренних документов. Кроме этого, все зарегистрированные сотрудники, получают доступ к встроенным веб-сервисам Office 365, для организации удаленной работы, таким как: Microsoft Teams, Planner, OneDrive.

Так как решение направлено на корпоративный сегмент рынка, и связано с работой с конфиденциальными и персонализированными данными, мы позаботились о безопасности. WSS Consultant O365 включает в себя двухфакторную аутентификацию, DLP систему(предупреждение потери данных), управление пользовательскими права доступа, шифрование данных в Office 365, расширенную защиту от угроз Exchange Online Protection, Active Directory Federation Service. Все персональные данные, хранящиеся в базе WSS Consultant O365 полностью соответствуют требования законодательства РФ. Кроме этого, безопасность в решении представлена Etoken, FIDO 2 и КриптоПро.

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

Запишитесь на бесплатный демо-тест уже сегодня, и оцените все преимущества WSS Consultant O365:

REST

The architectural style, REST (REpresentational State Transfer) is by far the most standardized way of structuring the web APIs for requests. REST is purely an architectural style based on several principles. The APIs adhering to REST principles are called RESTful APIs. REST APIs use a request/response model where every message from the server is the response to a message from the client. In general, RESTful APIs uses HTTP as its transport protocol. For such cases, lookups should use requests. , , and requests should be used for mutation, creation, and deletion respectively (avoid using requests for updating information).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector