JSON-RPC

Поделись знанием:
Перейти к: навигация, поиск

JSON-RPC (сокр. от англ. JavaScript Object Notation Remote Procedure Call — JSON-вызов удалённых процедур) — протокол удалённого вызова процедур, использующий JSON для кодирования сообщений. Это очень простой протокол (очень похожий на XML-RPC), определяющий только несколько типов данных и команд. JSON-RPC поддерживает уведомления (информация, отправляемая на сервер, не требует ответа) и множественные вызовы.





Краткая история

Версия Описание Дата
1.0 [json-rpc.org/wiki/specification/ Оригинальная версия] в настоящее время считается официальной[1]. 2005
1.1 WD [web.archive.org/web/20100718181845/json-rpc.org/wd/JSON-RPC-1-1-WD-20060807.html Рабочий черновик]

Добавлены именованные параметры, специфичные коды ошибок и функции самонаблюдения.

2008.08.07
1.1 Alt [jsonrpc.org/historical/json-rpc-1-1-alt.txt Соглашение о простом JSON-RPC 1.1]

Альтернативное предложение к 1.1 WD.

2007.05.06
1.1 Object Specification [jsonrpc.org/historical/json-rpc-object-specification.html Объектная спецификация] Альтернативное предложение к 1.1 WD/1.1 Alt 2007.07.30
1.2 [jsonrpc.org/historical/jsonrpc12_proposal.html Предложение] Поздняя версия этого документа была переименована в 2.0. 2007.12.27
2.0 [jsonrpc.org/historical/json-rpc-1-2-proposal.txt Предложение спецификации] 2009.05.24
2.0 (Revised) [www.jsonrpc.org/specification Спецификация] 2010.03.26
2.0 (Updated) [www.jsonrpc.org/specification Спецификация] 2013.01.04

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

JSON-RPC работает отсылая запросы к серверу, реализующему протокол. Клиентом обычно является программа, которой нужно вызвать метод на удалённой системе. Множество входных параметров может быть передано удалённому методу, как массив или объект. Метод также может вернуть множество выходных данных (это зависит от реализации). Удалённый метод вызывается отправлением запроса на удалённый сервер посредством HTTP или TCP/IP сокета (начиная с версии 2.0). При использовании HTTP, заголовок Content-Type определяется как application/json[2].

Все передаваемые данные — простые объекты, сериализованные в JSON[3]. Запрос — вызов определённого метода, предоставляемого удалённой системой. Он должен содержать три обязательных свойства:

  • method — Строка с именем вызываемого метода.
  • params — Массив объектов, которые должны быть переданы методу, как параметры.
  • id — Значение любого типа, которое используется для установки соответствия между запросом и ответом.

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

  • result — Данные, которые вернул метод. Если произошла ошибка во время выполнения метода, это свойство должно быть установлено в null.
  • error — Код ошибки, если произошла ошибка во время выполнения метода, иначе null.
  • id — То же значение, что и в запросе, к которому относится данный ответ.

Для ситуаций, когда ответ не требуется, были введены уведомления. Уведомление отличается от запроса отсутствием свойства id, которое не требуется, так как не будет передан ответ. В таком случае свойство id может быть пропущено (версия 2.0) или установлено в null (версия 1.0).

Примеры

В данных примерах, --> обозначает данные, отправленные серверу (запрос), а <-- обозначает ответ.

Версия 1.0

Простой запрос и ответ.

--> {"method": "echo", "params": ["Hello JSON-RPC"], "id":1}
<-- {"result": "Hello JSON-RPC", "error": null, "id":1}

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

...
--> {"method": "postMessage", "params": ["Hello all!"], "id": 99}
<-- {"result": 1, "error": null, "id": 99}
<-- {"method": "handleMessage", "params": ["user1", "we were just talking"], "id": null}
<-- {"method": "handleMessage", "params": ["user3", "sorry, gotta go now, ttyl"], "id": null}
--> {"method": "postMessage", "params": ["I have a question:"], "id": 101}
<-- {"method": "userLeft", "params": ["user3"], "id": null}
<-- {"result": 1, "error": null, "id": 101}
...

Так как свойство params является массивом объектов, следующий формат является валидным.

{
    "method": "methodnamehere",
    "params": [
        {
            "firstparam": "this contains information of the firstparam.",
            "secondparam": 1121211234,
            "thirdparam": "this contains information of the thirdparam."
        },
        {
            "fourthparam": "this is already a different object.",
            "secondparam": "there can be same name fields in different objects.",
            "thirdparam": "this contains information of the thirdparam."
        }
    ],
    "id": 1234
}

Версия 1.1 (Рабочий черновик)

Формат запроса должен быть примерно следующим:

{
    "version": "1.1",
    "method": "confirmFruitPurchase",
    "id": "194521489",
    "params": [
        ["apple", "orange", "Mangoos"],
        1.123
    ]
}

Формат ответа может быть примерно таким:

{
    "version": "1.1",
    "result": "done",
    "error": null,
    "id": "194521489"
}

Версия 2.0

Вызов процедуры с позиционными параметрами:

--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}
--> {"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2}
<-- {"jsonrpc": "2.0", "result": -19, "id": 2}

Вызов процедуры с именованными параметрами:

--> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
<-- {"jsonrpc": "2.0", "result": 19, "id": 3}
--> {"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}
<-- {"jsonrpc": "2.0", "result": 19, "id": 4}

Уведомление:

--> {"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}
--> {"jsonrpc": "2.0", "method": "foobar"}

Вызов несуществующей функции:

--> {"jsonrpc": "2.0", "method": "foobar", "id": 10}
<-- {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Procedure not found."}, "id": 10}

Вызов процедуры с неправильным JSON:

--> {"jsonrpc": "2.0", "method": "foobar", "params": "bar", "baz"]
<-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}

Вызов процедуры с неправильным JSON-RPC:

--> [1,2,3]
<-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid JSON-RPC."}, "id": null}
--> {"jsonrpc": "2.0", "method": 1, "params": "bar"}
<-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid JSON-RPC."}, "id": null}

Реализации

Название версия JSON-RPC Описание Язык(и), Платформы
[jsonrpc2.codeplex.com/ JSON-RPC.NET] 2.0 Быстрый JSON-RPC сервер. Поддерживает сокеты, именованные сокеты и HTTP с помощью ASP.NET требует Mono или .NET Framework 4.0. .NET
Jayrock 1.0 Серверная реализация JSON-RPC 1.0 для Microsoft .NET Framework версий 1.1 и 2.0 . .NET
[github.com/hmng/jsonrpc-c jsonrpc-c] 2.0 Реализация JSON-RPC через TCP сокеты (только сервер). C
[github.com/cinemast/libjson-rpc-cpp/ libjson-rpc-cpp] 2.0 + 1.0 C++ JSON-RPC фреймворк, поддерживающий клиентскую и серверную стороны через HTTP. C++
[code.google.com/p/blowthemall/downloads/list Phobos] 2.0 Реализация для Qt/C++. Абстрагирует уровень передачи данных (готовые к использованию классы для TCP и HTTP). C++
[bitbucket.org/devonit/qjsonrpc qjsonrpc] 2.0 Реализация для Qt/C++. Поддерживает соединения между сообщениями и QObject слотами (как QDBus, qxtrpc). Использует новые JSON классы, включённые в Qt 5. C++
[www.progdigy.com/?page_id=6 JSON Toolkit] 2.0 Реализация на Delphi Delphi
[golang.org/pkg/net/rpc/ go/net/rpc]  ? Реализация JSON-RPC стандартной библиотеки Go Go
[github.com/briandilley/jsonrpc4j jsonrpc4j] 2.0 Java реализация JSON-RPC 2.0 поддерживает как сокеты, так и HTTP-соединение. Java
[github.com/RitwikSaikia/jsonrpc json-rpc] 1.0 Базовая Java/JavaScript реализация, которая хорошо интегрируется в Android/Servlets/Standalone Java/JavaScript/App-Engine приложения. Java / JavaScript
[jpoxy.org/ jpoxy] 2.0 Простая Java реализация JSON-RPC созданная для упрощения реализации доступа к POJOs через сырой RPC фрэймворк. Java
[stefaniuk.github.com/json-service/ JSON Service] 2.0 JSON-RPC серверная реализация с поддержкой Service Mapping Description. Хорошо интегрируется с Dojo Toolkit и Spring Framework. Java
[software.dzhuvinov.com/json-rpc-2.0-base.html JSON-RPC 2.0] 2.0 Лёгкая библиотека на Java для разбора и сериализации JSON-RPC 2.0 сообщений (open source). Несколько реализация на сайте. (Base, Client, Shell, …) Java
[java-json-rpc.sourceforge.net/ java-json-rpc] 2.0 Реализация для J2EE серверов. Java
[code.google.com/p/libjsonrpc/ lib-json-rpc] 2.0 Реализация servlet, client, JavaScript Java
[code.google.com/p/simplejsonrpc/ simplejsonrpc] 2.0 Простой JSON-RPC 2.0 Servlet, обслуживающий методы класса. Java
[code.google.com/p/gson-rmi/ gson-rmi] 2.0 Легковесный, независимый от способа передачи RMI фрэймворк разработанный для распределённых вычислений. Java
[github.com/gimmi/jsonrpcjs jsonrpcjs] 2.0 JavaScript клиентская библиотека для JSON-RPC 2.0, Не имеет зависимостей. JavaScript
[easyxdm.net/ easyXDM] 2.0 Библиотека для cross-domain соединений с поддержкой RPC. Поддерживает все браузеры postMessage, nix, frameElement, window.name, и FIM, очень проста в использовании. JavaScript
Dojo Toolkit 1.0+ Предоставляет поддержку JSON-RPC JavaScript
[github.com/izuzak/pmrpc Pmrpc] 2.0 JavaScript библиотека для использования в HTML5 браузерах. Реализация JSON-RPC, используя [dev.w3.org/html5/spec/Overview.html#crossDocumentMessages HTML5 postMessage API] для передачи сообщений. JavaScript
[manual.qooxdoo.org/current/pages/communication/rpc.html qooxdoo] 2.0 Имеет JSON-RPC реализацию с опциональными бэк-эндами на Java, PHP, Perl и Python. JavaScript, Java, PHP, PERL, & Python
[jsolait.net/ JSON-RPC Реализация на JavaScript] 2.0 Поддерживает JSON-RPC через HTTP и TCP/IP. JavaScript
[www.jabsorb.org/ jabsorb] 2.0 Легковесный Ajax/Web 2.0 JSON-RPC Java фреймворк, расширяющий протокол JSON-RPC дополнительной ORB функциональностью, такой как поддержка циклических зависимостей. JavaScript, Java
The Wakanda platform 2.0 Поддерживает JSON-RPC 2.0 клиент внутри Ajax Framework и JSON-RPC 2.0 сервис в серверном JavaScript JavaScript
[search.npmjs.org/#/deimos Deimos] 1.0+2.0 Серверная реализация для Node.js/JavaScript. JavaScript
[realtimelogic.com/ba/doc/?url=en/lua/json-rpc.html Barracuda Web Server] 2.0 Barracuda Web Server’s интегрированный Lua
[github.com/zinovyev/lugate Lugate API Gateway ] 2.0 Реализация API Gateway в виде JSON-RPC 2.0 модуля для NGINX Lua
[github.com/samuraisam/DeferredKit DeferredKit] 1.0 Поддерживает JSON-RPC 1.0 клиент. Objective-C
[github.com/dbowen/Demiurgic-JSON-RPC Demiurgic] 2.0 JSON-RPC 2.0 клиент для Objective-C Objective-C
[code.google.com/p/oxeniphonecommons/wiki/JsonComponents Oxen iPhone Commons JSON components] 1.0 JSON-RPC 1.0 клиент для Objective-C Objective-C
[github.com/styrken/objc-JSONRpc objc-JSONRpc] 2.0 Objective-c JSON RPC клиент. Поддерживает уведомления, простые вызовы и множественные вызовы. Objective-C
[github.com/AFNetworking/AFJSONRPCClient AFJSONRPCClient] 2.0 Objective-c JSON RPC клиент. Objective-C
[metacpan.org/module/JSON::RPC JSON::RPC] 2.0 Реализация сервера JSON RPC 2.0 Perl
[github.com/bbkr/jsonrpc json-rpc-perl6] 2.0 Клиент и сервер. Perl 6
[bitbucket.org/jbg/php-json-rpc php-json-rpc] 2.0 Простая PHP реализация JSON-RPC 2.0 через HTTP клиента. PHP
[tanabi.com/projects/jsonrpc JQuery JSON-RPC Server] 2.0 JSON-RPC сервер, специально сделанный для работы с Zend Framework JSON RPC Server. PHP, JavaScript
[github.com/mpcm/JSON-RPC-PHP jsonrpc2php] 2.0 PHP5 JSON-RPC 2.0 базовый класс и пример сервера PHP
[github.com/marcelklehr/tivoka tivoka] 1.0 + 2.0 Универсальный клиент/серверная JSON-RPC библиотека для PHP 5+. PHP
[github.com/EvilScott/junior junior] 2.0 Client/server библиотека для JSON-RPC 2.0 PHP
[github.com/Pozo/json-rpc-php json-rpc-php] 2.0 Client/server библиотека для JSON-RPC 2.0 PHP
[github.com/foglcz/JSONRpc2 JSONRpc2] 2.0 Реализация с «dot magic» для PHP (= поддержка группировки методов и разделения точками) PHP
[github.com/GetResponse/DevZone/blob/master/API/lib/jsonRPCClient.php GetResponse jsonRPCClient] 2.0 Объектно-ориентированная реализация клиента PHP
[sourceforge.net/projects/jsonrpc20api/ zoServices] 2.0 PHP, Node.js и JavaScript реализация JSON-RPC 2.0 PHP, JavaScript, Node.js
[github.com/subutux/json-rpc2php json-rpc2php] 2.0 Серверная и клиентская реализация для PHP. Содержит JavaScript клиент, использующий jQuery PHP, JavaScript
[code.google.com/p/jsonrpc-php/ jsonrpc-php] 2.0 JSON-RPC реализация для PHP PHP
[github.com/tuenti/php-json-rpc php-json-rpc] 2.0 Реализация JSON-RPC 2.0. PHP
[github.com/orokusaki/django-jsonrpc-2-0 Django JSON-RPC 2.0] 2.0 JSON-RPC сервер для Django Python
[pyjs.org Pyjamas] JSON-RPC клиентская реализация. Python
[pypi.python.org/pypi/z3c.jsonrpc/0.5.1 Zope 3] 1.1 JSON RPC реализация для Zope 3 Python
[github.com/joshmarshall/jsonrpclib jsonrpclib] 2.0 JSON-RPC клиентский модуль для Python. Python
[github.com/joshmarshall/tornadorpc tornadorpc] 2.0 Поддерживает JSON-RPC требует Tornado web server. Python
[pypi.python.org/pypi/tinyrpc tinyrpc] 2.0 Поддерживает JSON-RPC через TCP, WSGI, ZeroMQ и др. Разделяет передачу данных от обработки сообщений, может работать без пересылки сообщений. Python
[github.com/NCMI/jsonrpc jsonrpc] 2.0 JSON-RPC 2.0 для Python + Twisted. Python
[deavid.github.com/bjsonrpc/ bjsonrpc] 1.0+ Реализация через TCP/IP (асинхронная, двунаправленная) Python
[barrister.bitmechanic.com/ Barrister RPC] 2.0 JSON-RPC реализация клиента и сервера Python, Ruby, JavaScript (Node.js + web browser), PHP, Java
[docs.pylonsproject.org/projects/pyramid_rpc/en/latest/index.html pyramid_rpc] 2.0 Гибкая JSON-RPC реализация интегрированная в Pyramid web application. Работает с Pyramid’s системой авторизации. Python
[github.com/movitto/rjr rjr] 2.0 JSON-RPC через TCP/UDP, HTTP, WebSockets, AMQP, и прочие. Ruby (EventMachine) сервер с Ruby и JavaScript клиентами.
[github.com/chriskite/jimson jimson] 2.0 Клиент и сервер для Ruby Ruby
[github.com/martinkozak/json-rpc-objects JSON-RPC Objects] 1.0+ Реализация только объектов (без клиента и сервера). Ruby
[jsonrpcrt.codeplex.com/ JSON-RPC RT] 2.0 Полная поддержка JSON-RPC 2.0 через TCP. Windows Runtime (WinRT)
XINS 2.0 С версии 2.0, поддерживает JSON и JSON-RPC. XML

Официальная страница[4] содержит [json-rpc.org/wiki/implementations больше реализаций]. CPAN список [search.cpan.org/search?m=all&q=JSON+RPC&n=100 реализаций на Perl].

См. также

  • Remote procedure call (RPC);
  • XML-RPC
  • SOAPjr — гибрид SOAP и JSON-RPC;
  • JSON-WSP — основанный на JSON-RPC протокол c спецификацие для описания сервиса.
  • [labs.omniti.com/labs/jsend JSend спецификация которая только декларирует формат ответа]

Напишите отзыв о статье "JSON-RPC"

Примечания

  1. [groups.google.com/group/json-rpc/msg/c5633df97dc8f16f Группы Google]
  2. RFC 4627
  3. [json-rpc.org/wiki/specification Спецификация JSON-RPC]
  4. [json-rpc.org/ JSON-RPC — Trac]

Ссылки

  • [www.jsonrpc.org/ Официальный сайт]
  • [json-rpc.org/ Официальная страница JSON-RPC 1.0]
  • [groups.google.com/group/json-rpc JSON-RPC Google группа]. Обсуждение связанных с протоколом тем
  • [www.simple-is-better.org/json-rpc/ JSON-RPC спецификации, ссылки, и пр.]

Отрывок, характеризующий JSON-RPC

Эти ночные посещения Наташи, совершавшиеся до возвращения графа из клуба, были одним из любимейших наслаждений матери и дочери.
– Об чем же нынче? А мне нужно тебе сказать…
Наташа закрыла рукою рот матери.
– О Борисе… Я знаю, – сказала она серьезно, – я затем и пришла. Не говорите, я знаю. Нет, скажите! – Она отпустила руку. – Скажите, мама. Он мил?
– Наташа, тебе 16 лет, в твои года я была замужем. Ты говоришь, что Боря мил. Он очень мил, и я его люблю как сына, но что же ты хочешь?… Что ты думаешь? Ты ему совсем вскружила голову, я это вижу…
Говоря это, графиня оглянулась на дочь. Наташа лежала, прямо и неподвижно глядя вперед себя на одного из сфинксов красного дерева, вырезанных на углах кровати, так что графиня видела только в профиль лицо дочери. Лицо это поразило графиню своей особенностью серьезного и сосредоточенного выражения.
Наташа слушала и соображала.
– Ну так что ж? – сказала она.
– Ты ему вскружила совсем голову, зачем? Что ты хочешь от него? Ты знаешь, что тебе нельзя выйти за него замуж.
– Отчего? – не переменяя положения, сказала Наташа.
– Оттого, что он молод, оттого, что он беден, оттого, что он родня… оттого, что ты и сама не любишь его.
– А почему вы знаете?
– Я знаю. Это не хорошо, мой дружок.
– А если я хочу… – сказала Наташа.
– Перестань говорить глупости, – сказала графиня.
– А если я хочу…
– Наташа, я серьезно…
Наташа не дала ей договорить, притянула к себе большую руку графини и поцеловала ее сверху, потом в ладонь, потом опять повернула и стала целовать ее в косточку верхнего сустава пальца, потом в промежуток, потом опять в косточку, шопотом приговаривая: «январь, февраль, март, апрель, май».
– Говорите, мама, что же вы молчите? Говорите, – сказала она, оглядываясь на мать, которая нежным взглядом смотрела на дочь и из за этого созерцания, казалось, забыла всё, что она хотела сказать.
– Это не годится, душа моя. Не все поймут вашу детскую связь, а видеть его таким близким с тобой может повредить тебе в глазах других молодых людей, которые к нам ездят, и, главное, напрасно мучает его. Он, может быть, нашел себе партию по себе, богатую; а теперь он с ума сходит.
– Сходит? – повторила Наташа.
– Я тебе про себя скажу. У меня был один cousin…
– Знаю – Кирилла Матвеич, да ведь он старик?
– Не всегда был старик. Но вот что, Наташа, я поговорю с Борей. Ему не надо так часто ездить…
– Отчего же не надо, коли ему хочется?
– Оттого, что я знаю, что это ничем не кончится.
– Почему вы знаете? Нет, мама, вы не говорите ему. Что за глупости! – говорила Наташа тоном человека, у которого хотят отнять его собственность.
– Ну не выйду замуж, так пускай ездит, коли ему весело и мне весело. – Наташа улыбаясь поглядела на мать.
– Не замуж, а так , – повторила она.
– Как же это, мой друг?
– Да так . Ну, очень нужно, что замуж не выйду, а… так .
– Так, так, – повторила графиня и, трясясь всем своим телом, засмеялась добрым, неожиданным старушечьим смехом.
– Полноте смеяться, перестаньте, – закричала Наташа, – всю кровать трясете. Ужасно вы на меня похожи, такая же хохотунья… Постойте… – Она схватила обе руки графини, поцеловала на одной кость мизинца – июнь, и продолжала целовать июль, август на другой руке. – Мама, а он очень влюблен? Как на ваши глаза? В вас были так влюблены? И очень мил, очень, очень мил! Только не совсем в моем вкусе – он узкий такой, как часы столовые… Вы не понимаете?…Узкий, знаете, серый, светлый…
– Что ты врешь! – сказала графиня.
Наташа продолжала:
– Неужели вы не понимаете? Николенька бы понял… Безухий – тот синий, темно синий с красным, и он четвероугольный.
– Ты и с ним кокетничаешь, – смеясь сказала графиня.
– Нет, он франмасон, я узнала. Он славный, темно синий с красным, как вам растолковать…
– Графинюшка, – послышался голос графа из за двери. – Ты не спишь? – Наташа вскочила босиком, захватила в руки туфли и убежала в свою комнату.
Она долго не могла заснуть. Она всё думала о том, что никто никак не может понять всего, что она понимает, и что в ней есть.
«Соня?» подумала она, глядя на спящую, свернувшуюся кошечку с ее огромной косой. «Нет, куда ей! Она добродетельная. Она влюбилась в Николеньку и больше ничего знать не хочет. Мама, и та не понимает. Это удивительно, как я умна и как… она мила», – продолжала она, говоря про себя в третьем лице и воображая, что это говорит про нее какой то очень умный, самый умный и самый хороший мужчина… «Всё, всё в ней есть, – продолжал этот мужчина, – умна необыкновенно, мила и потом хороша, необыкновенно хороша, ловка, – плавает, верхом ездит отлично, а голос! Можно сказать, удивительный голос!» Она пропела свою любимую музыкальную фразу из Херубиниевской оперы, бросилась на постель, засмеялась от радостной мысли, что она сейчас заснет, крикнула Дуняшу потушить свечку, и еще Дуняша не успела выйти из комнаты, как она уже перешла в другой, еще более счастливый мир сновидений, где всё было так же легко и прекрасно, как и в действительности, но только было еще лучше, потому что было по другому.

На другой день графиня, пригласив к себе Бориса, переговорила с ним, и с того дня он перестал бывать у Ростовых.


31 го декабря, накануне нового 1810 года, le reveillon [ночной ужин], был бал у Екатерининского вельможи. На бале должен был быть дипломатический корпус и государь.
На Английской набережной светился бесчисленными огнями иллюминации известный дом вельможи. У освещенного подъезда с красным сукном стояла полиция, и не одни жандармы, но полицеймейстер на подъезде и десятки офицеров полиции. Экипажи отъезжали, и всё подъезжали новые с красными лакеями и с лакеями в перьях на шляпах. Из карет выходили мужчины в мундирах, звездах и лентах; дамы в атласе и горностаях осторожно сходили по шумно откладываемым подножкам, и торопливо и беззвучно проходили по сукну подъезда.
Почти всякий раз, как подъезжал новый экипаж, в толпе пробегал шопот и снимались шапки.
– Государь?… Нет, министр… принц… посланник… Разве не видишь перья?… – говорилось из толпы. Один из толпы, одетый лучше других, казалось, знал всех, и называл по имени знатнейших вельмож того времени.
Уже одна треть гостей приехала на этот бал, а у Ростовых, долженствующих быть на этом бале, еще шли торопливые приготовления одевания.
Много было толков и приготовлений для этого бала в семействе Ростовых, много страхов, что приглашение не будет получено, платье не будет готово, и не устроится всё так, как было нужно.
Вместе с Ростовыми ехала на бал Марья Игнатьевна Перонская, приятельница и родственница графини, худая и желтая фрейлина старого двора, руководящая провинциальных Ростовых в высшем петербургском свете.
В 10 часов вечера Ростовы должны были заехать за фрейлиной к Таврическому саду; а между тем было уже без пяти минут десять, а еще барышни не были одеты.
Наташа ехала на первый большой бал в своей жизни. Она в этот день встала в 8 часов утра и целый день находилась в лихорадочной тревоге и деятельности. Все силы ее, с самого утра, были устремлены на то, чтобы они все: она, мама, Соня были одеты как нельзя лучше. Соня и графиня поручились вполне ей. На графине должно было быть масака бархатное платье, на них двух белые дымковые платья на розовых, шелковых чехлах с розанами в корсаже. Волоса должны были быть причесаны a la grecque [по гречески].
Все существенное уже было сделано: ноги, руки, шея, уши были уже особенно тщательно, по бальному, вымыты, надушены и напудрены; обуты уже были шелковые, ажурные чулки и белые атласные башмаки с бантиками; прически были почти окончены. Соня кончала одеваться, графиня тоже; но Наташа, хлопотавшая за всех, отстала. Она еще сидела перед зеркалом в накинутом на худенькие плечи пеньюаре. Соня, уже одетая, стояла посреди комнаты и, нажимая до боли маленьким пальцем, прикалывала последнюю визжавшую под булавкой ленту.
– Не так, не так, Соня, – сказала Наташа, поворачивая голову от прически и хватаясь руками за волоса, которые не поспела отпустить державшая их горничная. – Не так бант, поди сюда. – Соня присела. Наташа переколола ленту иначе.
– Позвольте, барышня, нельзя так, – говорила горничная, державшая волоса Наташи.
– Ах, Боже мой, ну после! Вот так, Соня.
– Скоро ли вы? – послышался голос графини, – уж десять сейчас.
– Сейчас, сейчас. – А вы готовы, мама?
– Только току приколоть.
– Не делайте без меня, – крикнула Наташа: – вы не сумеете!
– Да уж десять.
На бале решено было быть в половине одиннадцатого, a надо было еще Наташе одеться и заехать к Таврическому саду.
Окончив прическу, Наташа в коротенькой юбке, из под которой виднелись бальные башмачки, и в материнской кофточке, подбежала к Соне, осмотрела ее и потом побежала к матери. Поворачивая ей голову, она приколола току, и, едва успев поцеловать ее седые волосы, опять побежала к девушкам, подшивавшим ей юбку.
Дело стояло за Наташиной юбкой, которая была слишком длинна; ее подшивали две девушки, обкусывая торопливо нитки. Третья, с булавками в губах и зубах, бегала от графини к Соне; четвертая держала на высоко поднятой руке всё дымковое платье.
– Мавруша, скорее, голубушка!
– Дайте наперсток оттуда, барышня.
– Скоро ли, наконец? – сказал граф, входя из за двери. – Вот вам духи. Перонская уж заждалась.
– Готово, барышня, – говорила горничная, двумя пальцами поднимая подшитое дымковое платье и что то обдувая и потряхивая, высказывая этим жестом сознание воздушности и чистоты того, что она держала.
Наташа стала надевать платье.
– Сейчас, сейчас, не ходи, папа, – крикнула она отцу, отворившему дверь, еще из под дымки юбки, закрывавшей всё ее лицо. Соня захлопнула дверь. Через минуту графа впустили. Он был в синем фраке, чулках и башмаках, надушенный и припомаженный.
– Ах, папа, ты как хорош, прелесть! – сказала Наташа, стоя посреди комнаты и расправляя складки дымки.
– Позвольте, барышня, позвольте, – говорила девушка, стоя на коленях, обдергивая платье и с одной стороны рта на другую переворачивая языком булавки.
– Воля твоя! – с отчаянием в голосе вскрикнула Соня, оглядев платье Наташи, – воля твоя, опять длинно!
Наташа отошла подальше, чтоб осмотреться в трюмо. Платье было длинно.
– Ей Богу, сударыня, ничего не длинно, – сказала Мавруша, ползавшая по полу за барышней.
– Ну длинно, так заметаем, в одну минутую заметаем, – сказала решительная Дуняша, из платочка на груди вынимая иголку и опять на полу принимаясь за работу.
В это время застенчиво, тихими шагами, вошла графиня в своей токе и бархатном платье.
– Уу! моя красавица! – закричал граф, – лучше вас всех!… – Он хотел обнять ее, но она краснея отстранилась, чтоб не измяться.
– Мама, больше на бок току, – проговорила Наташа. – Я переколю, и бросилась вперед, а девушки, подшивавшие, не успевшие за ней броситься, оторвали кусочек дымки.
– Боже мой! Что ж это такое? Я ей Богу не виновата…
– Ничего, заметаю, не видно будет, – говорила Дуняша.
– Красавица, краля то моя! – сказала из за двери вошедшая няня. – А Сонюшка то, ну красавицы!…
В четверть одиннадцатого наконец сели в кареты и поехали. Но еще нужно было заехать к Таврическому саду.
Перонская была уже готова. Несмотря на ее старость и некрасивость, у нее происходило точно то же, что у Ростовых, хотя не с такой торопливостью (для нее это было дело привычное), но также было надушено, вымыто, напудрено старое, некрасивое тело, также старательно промыто за ушами, и даже, и так же, как у Ростовых, старая горничная восторженно любовалась нарядом своей госпожи, когда она в желтом платье с шифром вышла в гостиную. Перонская похвалила туалеты Ростовых.
Ростовы похвалили ее вкус и туалет, и, бережа прически и платья, в одиннадцать часов разместились по каретам и поехали.


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