Coder Social home page Coder Social logo

zpj8 / protobuf-qml Goto Github PK

View Code? Open in Web Editor NEW

This project forked from nsuke/protobuf-qml

0.0 1.0 0.0 511 KB

Protocol Buffers and gRPC binding for QML (QtQuick2)

License: MIT License

CMake 4.29% Dockerfile 0.37% Shell 0.63% C++ 62.09% QML 23.04% JavaScript 2.45% C 0.13% Python 6.88% Batchfile 0.13%

protobuf-qml's Introduction

protobuf-qml

Build Status Build status

Efficient schematized serialization and RPC for QtQuick2 applications through Protocol Buffers and gRPC bindings.

Usage

For installation, see INSTALL.md.

Protocol Buffers binding

For Protocol Buffers itself, see upstream official site:

https://developers.google.com/protocol-buffers/

Code generation

Suppose you write following .proto file, say my_foo.proto:

    message Foo {
      string text = 1;
      repeated uint32 nums = 2;
    }

you can generate QML/Javascript message type using compiler plugin:

$ protoc --qml_out gen my_foo.proto

This will yield gen/my_foo.pb.js file. Let's import this file from any QML using relative path.

Docker image

If you want to try it out without building protobuf-qml, a docker image for code generator is available.

# docker pull nsuke/protobuf-qml
# docker run -it -v $(pwd):/opt/protobuf-qml nsuke/protobuf-qml -I. \
    --qml_out=<relative path to output dir> \
    <relative path to your .proto file>

Note that the relative paths cannot contain parent or sibling directories, i.e., they need to be within current or sub directories.

Serialization

import 'gen/my_foo.pb.js' as Types

then you can use the message type inside signal handlers, property bindings or functions:

var foo = new Types.Foo({
  text: 'hello world',
  nums: [ 3, 4, 5 ],
});

var buf = foo.serialize();

here, the buf variable is an ArrayBuffer object.

Deserialization

Deserialization is quite simple too:

var foo2 = Types.Foo.parse(buf);

console.log(foo2.text)
// output: hello world
console.log(foo2.nums(1))
// output: 4

TBD: Link to full sample code

gRPC binding

For gRPC itself, see upstream official page: http://www.grpc.io/

gRPC binding is still experimental.

Code generation

Suppose you add service definition to the my_foo.proto above:

service MyService {
  rpc ExchangeFoo(Foo) returns(Foo) {}
}

compiler plugin will additionally yield MyService.qml and MyServiceClient.qml files besides my_foo.pb.js file. Let's import the directory containing those QML files:

import 'gen'

then you can instantiate QML elements:

MyServiceClient {
  id: client
}
MyService {
  id: service
}

Client

To make the client element functional, plug it to a gRPC channel. (In fact, you can plug to custom RPC implementation but gRPC works out of the box)

import 'gen'
import gRPC
GrpcChannel {
  id: gchannel
  target: 'example.org:44448'
  credentials: InsecureCredentials {}
}

MyServiceClienit {
  id: client
  channel: gchannel
}

Then inside signal handlers, property bindings or functions :

client.exchangeFoo({
  text: 'hi',
  nums: [1, 2, 3],
}, function(err, responseFoo) {
  if (err) {
    console.warn('Received error response: ' + err);
    return;
  }

  // Do some useful stuff with "responseFoo" content
});

This will make a RPC call to example.org port 44448.

Server

You can create gRPC server in QML app if you want to. It's handy for P2P communication and/or notifications, but not suitable for heavy computation.

import 'gen'
import gRPC
GrpcServer {
  id: gserver
  address: '0.0.0.0:44448'
  credentials: ServerInsecureCredentials {}
}

MyService {
  id: server
  server: gserver

  // This function is called for each incoming request.
  exchangeFoo: function(requestFoo, callback) {

    // First argument is error.
    callback(null, {
      text: 'In response to ' + requestFoo.text,
      nums: [42],
    });
  }
}

QtWebSockets with Qt 5.8+

From Qt 5.8 (QtWebSockets 1.1 QML module) on, we can send array buffers through websockets.

Sending serialized message with QtWebSockets

import QtWebSockets 1.1
WebSocket {
  id: socket
  url: 'ws://your.remote.server'
  active: true
}
// Inside function or handler
var msg = new Types.Foo({
  text: 'hello world',
  nums: [ 3, 4, 5 ],
});
var buf = msg.serialize();
socket.sendBinaryMessage(buf);

Receiving serialized message with QtWebSockets

WebSocket {
  id: socket
  url: 'ws://your.remote.server'
  active: true

  onBinaryMessageReceived: {
    var msg = Types.Foo.parse(message);
    console.log(msg.text);
    console.log(msg.nums(0));
    console.log(msg.nums(1));
    // ... Do whatever with the data
  }
}

The complete code is available under examples/WebSockets directory.

Future examples

In the future, it might become possible to send ArrayBuffer using XMLHttpRequest too.

I've submitted a patch for XMLHttpRequest to Qt project which enables following usage.

Send and receive serialized message with XMLHttpRequest

// Inside function or handler
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://your.remote.server/');
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    var response = Types.Foo.parse(xhr.response);
    // ... Do whatever with the data
  }
};
xhr.responseType = 'arraybuffer';

var msg = new Types.Foo({
  text: 'hello world',
  // ...,
});

var buf = msg.serialize();

xhr.send(new DataView(buf));

The complete code is available under examples/XMLHttpRequest directory.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.