# IPC-Class

Inter-Process-Communication Class helps with communication between all the services and clients used in the machine-vision projects. It provides easy to use interface, as well as a Manager class that abstracts away IP's and Ports from the source. So it is possible to change the end points without needing to recompile the projects. IPC uses ASIO TCP for communication, but might use UDP later for locally constrained systems or even file sockets on Linux. The IPC automatically runs in a separate thread so that IP operations wouldn't block the main thread.

IPC is meant to be robust for connects and disconnects, so order of launch for Server and Client shouldn't matter, neither should Server going down while Client was listening to it. If the Server comes back up Client should reconnect. Currently this doesn't work in all cases.

---

## Usage

### Submodules

This class is usually a submodule for all of the projects that use it. To add it as a submodule do:
```git
   git submodule add git@git.playgineering.com:internal/IPC-Class.git submodules/IPC-Class
```
Then (or if the submodule is already added):
```git
   git submodule init
   git submodule update
```
For updating if the code in this repo changes:
```git
   git submodule update --remote --merge
```
### In Code

Include the ipc.h header. IPC supports servers (usually Daemons) and clients (usually Monitors). They are easy to create using the IPC Manager.
An example for making "Tracker" server:
```c++
  ipc::Manager manager("service_info.txt");
  auto tracker_server = manager.create_server<TrackerServerSession>("Tracker");
```

An example for making "Tracker" client:
```c++
  ipc::Manager manager("service_info.txt");
  auto tracker_client = manager.create_client<TrackerClientSession>("Tracker");
```

`TrackerServerSession` and `TrackerClientSession` are custom session classes that are extended from ipc::Session.
service_info.txt is a simple list file which holds endpoint information (ports and IP's). An example on how it might look like:

    Tablo 127.0.0.1 9841
    Tracker 127.0.0.1 9840 

The IPC class uses name resolution as well, so it is possible to pass URL's. In this case the service_info might look like this:

    Tracker tracker.playgineering.com 9840 

## Protocol

Communication level changes must only be implemented in ipc_protocol.h. In this header any new structures and message types can be added. Note that only trivially copyable structs are okay, which means they can be copied with memcpy(). This is automatically checked during compilation though. An example of trivially copyable struct:
```c++
  struct TrackerPlayerPositionMsg {
    float player_x[16];
    float player_y[16];
  };
```
Or:
```c++
  struct TrackerPlayerPositionMsg {
    std::array<float,16> player_x;
    std::array<float,16> player_y;
  };
```
Example of structure that cannot be used:
```c++
  struct TrackerPlayerPositionMsg {
    std::vector<float> player_x;
    std::vector<float> player_y;
  };
```
This will throw a compile time error (static assert). It is unlikely this limitation will be lifted any time soon, as it would require custom data serialization.