В рамках прототипа, над которым я работал, у меня была возможность опробовать протоколы буферов для сквозного сценария. Поскольку мне приходилось собирать фрагменты информации из разных источников, чтобы заставить ее работать, я подумал, что было бы полезно собрать ее в одном сообщении. Вот оно.
Буферы протокола
Буферы протокола предоставляют альтернативу JSON (и аналогичным форматам) для обмена сообщениями. Они используются для описания протокола в файлах .proto, а компилятор буферов протокола (protoc) используется для компиляции этих файлов в оболочки для различных языков программирования (C ++, C # , Java, JavaScript и т. Д.) Для использования описываемого протокола. Подробная информация о буферах протокола представлена в документации Google:
Для целей этого блога давайте определим простое сообщение в testmessage.proto:
syntax = "proto3"; message TestMessage { string someText = 1; }
Чтобы сгенерировать оболочки JavaScript для этого протокола, загрузите компилятор протоколов буферов отсюда и разархивируйте его:
Теперь запустите эту команду, чтобы сгенерировать оболочку testmessage_pb.js:
$ protoc --js_out=import_style=commonjs,binary:. testmessage.proto
Эту оболочку нужно будет скопировать как в клиентский, так и в серверный код.
Сервер
Сервер будет реализован с использованием Express и WebSockets, и мы также будем использовать буферы протокола. Итак, эти зависимости необходимо будет установить:
$ npm install express ws google-protobuf
Поскольку мы хотим использовать HTTPS, мы будем использовать самозаверяющие сертификаты. Чтобы сгенерировать сертификаты, используйте эту команду:
$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 Generating a 2048 bit RSA private key …………………………………+++ …………………………………………………..+++ writing new private key to ‘key.pem’ Enter PEM pass phrase: Verifying — Enter PEM pass phrase: — — - You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.’, the field will be left blank. — — - Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:WA Locality Name (eg, city) []:Seattle Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test Organizational Unit Name (eg, section) []:Engineering Common Name (e.g. server FQDN or YOUR name) []:Admin Email Address []:[email protected]
Я использовал «тест» в качестве пароля. Также можно удалить парольную фразу из сертификата, но это всего лишь дополнительный шаг. Для простоты я просто добавлю парольную фразу в код. Файлы key.pem и cert.pem необходимо скопировать в код сервера.
Вот фрагмент кода для сервера:
'use strict' const TestMessage = require('./testmessage_pb') const Express = require('express') const Https = require('https') const WebSocket = require('ws') const FileSystem = require('fs') const app = Express() app.use(function (req, res) { res.send({ msg: 'hello' }) }) const server = Https.createServer({ key: FileSystem.readFileSync('key.pem'), cert: FileSystem.readFileSync('cert.pem'), passphrase: 'protobufjstest' }, app) const wss = new WebSocket.Server({ server }) wss.on('connection', function connection(ws) { ws.on('message', function incoming(message) { console.log('received: %s', message) }) var message = new proto.TestMessage(); message.setSometext('Hello Protocol Buffers') var bytes = message.serializeBinary() ws.send(bytes) }) server.listen(7070, function listening() { console.log('Listening on %d', server.address().port) })
Клиент
Теперь, когда у нас есть сервер, мы реализуем клиента. Клиенту нужно будет использовать WebSockets и Protocol Buffers. Итак, нам нужно будет установить эти зависимости:
$ npm install ws google-protobuf
Вот фрагмент кода для клиента:
'use strict' const TestMessage = require('./testmessage_pb') const WebSocket = require('ws') process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' const ws = new WebSocket('wss://localhost:7070/', { origin: 'https://localhost:7070' }) ws.on('open', function open() { console.log('connected') }) ws.on('close', function close() { console.log('disconnected') }) ws.on('message', function incoming(data, flags) { console.log('message') var bytes = Array.prototype.slice.call(data, 0) var message = proto.TestMessage.deserializeBinary(bytes) console.log(message.getSometext()) ws.close() })
Выход
После того, как сервер и клиент реализованы, давайте попробуем. Сначала запустим сервер:
$ node server.js Listening on 7070
Далее мы подключим клиента к серверу:
$ node client.js connected message Hello Protocol Buffers disconnected
И сообщение от сервера к клиенту успешно передается с использованием буферов протокола! Это был простой пример, демонстрирующий буферы протокола с WebSockets через HTTPS в Node.js / Express. Надеюсь, это было полезно.
Вот пример кода: