{"id":18913571,"url":"https://github.com/eerimoq/messi","last_synced_at":"2025-04-15T08:30:52.875Z","repository":{"id":39888226,"uuid":"262519375","full_name":"eerimoq/messi","owner":"eerimoq","description":"⚽ Reliable message passing in distributed systems.","archived":false,"fork":false,"pushed_at":"2023-06-05T05:48:33.000Z","size":481,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T18:50:41.418Z","etag":null,"topics":["distributed-systems","message-passing"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eerimoq.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-09T07:54:43.000Z","updated_at":"2024-01-03T14:17:01.000Z","dependencies_parsed_at":"2023-01-21T11:17:12.801Z","dependency_job_id":null,"html_url":"https://github.com/eerimoq/messi","commit_stats":null,"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eerimoq%2Fmessi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eerimoq%2Fmessi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eerimoq%2Fmessi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eerimoq%2Fmessi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eerimoq","download_url":"https://codeload.github.com/eerimoq/messi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249035298,"owners_count":21202052,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-systems","message-passing"],"created_at":"2024-11-08T10:08:16.808Z","updated_at":"2025-04-15T08:30:52.495Z","avatar_url":"https://github.com/eerimoq.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"|buildstatus|_\n|coverage|_\n|codecov|_\n|nala|_\n\n⚽ Messi\n========\n\nReliable message passing in distributed systems.\n\nHighlights:\n\n- Guaranteed in order message delivery.\n\n- Client automatically reconnects when the server connection is lost.\n\n- Protocols defined in Googles `Protocol Buffers`_ language version 3.\n\n- Designed to work in resource constrained systems.\n\n- `C` and `Python` source code generators.\n\nProject homepage: https://github.com/eerimoq/messi\n\nInstallation\n------------\n\n.. code-block:: python\n\n   $ pip install messi\n\nC source code\n-------------\n\nGenerate server and client side C source code.\n\n.. code-block:: text\n\n   $ messi generate_c_source examples/my_protocol/my_protocol.proto\n\nUse ``-p/--platform`` to select which platform to generate code\nfor.\n\nUse ``-s/--side`` to select which side (client and/or server) to\ngenerate code for.\n\nSupported platforms:\n\n- Linux, using TCP sockets, `epoll`_ and `timerfd`_.\n\n- The `async`_ framework (client only).\n\nThe generated code is **not** thread safe.\n\nKnown limitations:\n\n- The connection is immediately dropped if ``write()`` does not accept\n  exaxtly given amount of bytes. Buffering of remaining data may be\n  added at some point.\n\nLinux client side\n^^^^^^^^^^^^^^^^^\n\nSee `tests/files/my_protocol/linux/my_protocol_client.h`_ for the\ngenerated code and `examples/my_protocol/client/linux/main.c`_ for\nexample usage.\n\nLinux server side\n^^^^^^^^^^^^^^^^^\n\nSee `tests/files/my_protocol/linux/my_protocol_server.h`_ for the\ngenerated code and `examples/my_protocol/server/linux/main.c`_ for\nexample usage.\n\nAsync client side\n^^^^^^^^^^^^^^^^^\n\nSee `tests/files/my_protocol/async/my_protocol_client.h`_ for the\ngenerated code and `examples/my_protocol/client/async/main.c`_ for\nexample usage.\n\nPython source code\n------------------\n\nGenerate client side Python source code.\n\n.. code-block:: text\n\n   $ messi generate_py_source examples/my_protocol/my_protocol.proto\n\nUse ``-s/--side`` to select which side (client and/or server) to\ngenerate code for.\n\nClient side\n^^^^^^^^^^^\n\nSee `tests/files/my_protocol/my_protocol_client.py`_ for the generated\ncode and `examples/my_protocol/client/python/main.py`_ for example\nusage.\n\nServer side\n^^^^^^^^^^^\n\nNot yet implemented.\n\nArchitecture\n------------\n\nA `Messi` system consists of servers and clients. Once a client has\nsuccessfully connected to a server, messages defined in their protocol\nspecification can be reliably sent between them.\n\n`Messi` guarantees that all sent messages are delivered in order to\nthe peer. However, just as for TCP, any data/messages in flight when\nthe connection is lost will likely be lost.\n\nBelow is a sequence diagram showing typical communication between a\nserver and a client. The messages ``FooReq``, ``FooRsp``, ``BarInd``,\n``FieReq`` and ``FieRsp`` are defined in the protocol ``my_protocol``,\nwhich is defined later in this document.\n\nEach step (1 to 6) is described in detail after the sequence diagram.\n\n.. code-block:: text\n\n                 +--------+                               +--------+\n                 | client |                               | server |\n                 +--------+                               +--------+\n                     |             1. TCP connect              |\n                     |========================================\u003e|\n      on_connected() |                2. ping                  | on_client_connected()\n                     |----------------------------------------\u003e|\n                     |                   pong                  |\n                     |\u003c----------------------------------------|\n              send() |               3. FooReq                 |\n                     |========================================\u003e|\n                     |                  FooRsp                 | reply()\n                     |\u003c========================================|\n              send() |               4. BarInd                 |\n                     |========================================\u003e|\n              send() |                  BarInd                 |\n                     |========================================\u003e|\n                     |               5. FieReq                 | send()\n                     |\u003c========================================|\n              send() |                  FieRsp                 |\n                     |========================================\u003e|\n                     .                                         .\n                     .                                         .\n                     .                                         .\n                     |                6. ping                  |\n                     |----------------------------------------\u003e|\n                     .                                         .\n   on_disconnected() .                                         . on_client_disconnected()\n                     .                                         .\n\n   Legend:\n\n     ---: Background communication. No user interaction needed.\n\n     ===: User initiated communication.\n\nStep by step description:\n\n1. The client connects to the server. ``on_connected()`` and\n   ``on_client_connected()`` are called to notify the user that the\n   connection has been established.\n\n2. The client sends a ping message to the server, which responds with\n   a pong message. This is done in the background. No user interaction\n   needed.\n\n3. The client sends ``FooReq`` to the server, which responds with\n   ``FooRsp``.\n\n4. The client sends ``BarInd`` twice to the server. No response is\n   defined.\n\n5. The server sends ``FieReq`` to the client, which responds with\n   ``FieRsp``.\n\n6. The client sends another ping message. This time the server does\n   not respond. ``on_disconnected()`` and ``on_client_disconnected()``\n   are called to notify the user about the disconnection.\n\nMessi protocol specification\n----------------------------\n\nAll messages sent on the wire consists of a type, a size and optional\npayload. This enables both streaming and packet based transport\nprotocols. The transport protocol must be reliable (guaranteed in\norder delivery).\n\nType and size are in network byte order (big endian).\n\n.. code-block:: text\n\n   +---------+---------+-----------------+\n   | 1b type | 3b size | \u003csize\u003eb payload |\n   +---------+---------+-----------------+\n\n   TYPE  SIZE  DESCRIPTION\n   ------------------------------------------------------------------\n      1     n  Client to server user message (client --\u003e server).\n\n               Encoded \"message ClientToServer\" messages.\n\n      2     n  Server to client user message (server --\u003e client).\n\n               Encoded \"message ServerToClient\" messages.\n\n      3     0  Ping message (client --\u003e server).\n      4     0  Pong message (server --\u003e client).\n\nUser messages\n^^^^^^^^^^^^^\n\nUser messages are defined in Googles `Protocol Buffers`_ language\nversion 3.\n\nHere is an example defining a protocol called ``my_protocol``. The two\nmessages ``ClientToServer`` and ``ServerToClient`` must be present in\nevery protocol specification. ``ClientToServer`` contains all messages\nsent from clients to servers, and ``ServerToClient`` contains all\nmessages sent from servers to clients.\n\n.. code-block:: protobuf\n\n   syntax = \"proto3\";\n\n   // The protocol name.\n   package my_protocol;\n\n   // Messages sent from client to server.\n   message ClientToServer {\n       oneof messages {\n           FooReq foo_req = 1;\n           BarInd bar_ind = 2;\n           FieRsp fie_rsp = 3;\n       }\n   }\n\n   // Messages sent from server to client.\n   message ServerToClient {\n       oneof messages {\n           FooRsp foo_rsp = 1;\n           FieReq fie_req = 2;\n       }\n   }\n\n   // Message definitions.\n   message FooReq {\n   }\n\n   message FooRsp {\n   }\n\n   message BarInd {\n   }\n\n   message FieReq {\n   }\n\n   message FieRsp {\n   }\n\nPing and pong messages\n^^^^^^^^^^^^^^^^^^^^^^\n\nA client pings its server periodically. A client will close the\nconnection and report an error if the server does not answer with pong\nwithin given time. Likewise, the server will close the connection and\nreport an error if it does not receive ping within given time.\n\nThe ping-pong mechanism is only used if the transport layer does not\nprovide equivalent functionality.\n\nError handling\n--------------\n\n`Messi` aims to minimize the amount of error handling code in the user\napplication. Almost all functions always succeeds from the caller\npoint of view. For example, ``my_protocol_client_send()`` returns\n``void``. If an error occurs, likely a connection issue, the\ndisconnect callback is called to notify the user that the connection\nwas dropped.\n\nSimilar solutions\n-----------------\n\n- `gRPC`_ with bidirectional streaming.\n\n- `Embedded RPC`_.\n\n.. |buildstatus| image:: https://travis-ci.com/eerimoq/messi.svg?branch=master\n.. _buildstatus: https://travis-ci.com/eerimoq/messi\n\n.. |coverage| image:: https://coveralls.io/repos/github/eerimoq/messi/badge.svg?branch=master\n.. _coverage: https://coveralls.io/github/eerimoq/messi\n\n.. |codecov| image:: https://codecov.io/gh/eerimoq/messi/branch/master/graph/badge.svg\n.. _codecov: https://codecov.io/gh/eerimoq/messi\n\n.. |nala| image:: https://img.shields.io/badge/nala-test-blue.svg\n.. _nala: https://github.com/eerimoq/nala\n\n.. _epoll: https://en.wikipedia.org/wiki/Epoll\n\n.. _timerfd: http://man7.org/linux/man-pages/man2/timerfd_settime.2.html\n\n.. _async: https://github.com/eerimoq/async\n\n.. _Protocol Buffers: https://developers.google.com/protocol-buffers/docs/proto3\n\n.. _examples/my_protocol/client/linux/main.c: https://github.com/eerimoq/messi/blob/master/examples/my_protocol/client/linux/main.c\n\n.. _examples/my_protocol/server/linux/main.c: https://github.com/eerimoq/messi/blob/master/examples/my_protocol/server/linux/main.c\n\n.. _tests/files/my_protocol/my_protocol_client.py: https://github.com/eerimoq/messi/blob/master/tests/files/my_protocol/my_protocol_client.py\n\n.. _examples/my_protocol/client/python/main.py: https://github.com/eerimoq/messi/blob/master/examples/my_protocol/client/python/main.py\n\n.. _tests/files/my_protocol/linux/my_protocol_client.h: https://github.com/eerimoq/messi/blob/master/tests/files/my_protocol/linux/my_protocol_client.h\n\n.. _examples/my_protocol/client/linux/main.c: https://github.com/eerimoq/messi/blob/master/examples/my_protocol/client/linux/main.c\n\n.. _tests/files/my_protocol/async/my_protocol_client.h: https://github.com/eerimoq/messi/blob/master/tests/files/my_protocol/async/my_protocol_client.h\n\n.. _examples/my_protocol/client/async/main.c: https://github.com/eerimoq/messi/blob/master/examples/my_protocol/client/async/client.c\n\n.. _tests/files/my_protocol/linux/my_protocol_server.h: https://github.com/eerimoq/messi/blob/master/tests/files/my_protocol/linux/my_protocol_server.h\n\n.. _examples/my_protocol/server/linux/main.c: https://github.com/eerimoq/messi/blob/master/examples/my_protocol/server/linux/main.c\n\n.. _gRPC: https://grpc.io/\n\n.. _Embedded RPC: https://github.com/EmbeddedRPC/erpc\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feerimoq%2Fmessi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feerimoq%2Fmessi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feerimoq%2Fmessi/lists"}