Skip to content

Latest commit

 

History

History
118 lines (85 loc) · 3.59 KB

README.md

File metadata and controls

118 lines (85 loc) · 3.59 KB

Kry10 Msg Server native bindings

This mix pagage contains simble NIF bindings for calling a KOS msg_server native interface from Elixir.

Installation

def deps do
  [
    {:k10_msg_server, path: ./path/to/package}
  ]
end

Version 1.0.0 of this library introduces breaking changes that currently work KOS version 1.0.0-epsilon. It will not work with nightly releases that are released before 15/10/24 (DD-MM-YY).

Version 0.1.0 of this library works with KOS version 1.0.0-gamma and possibly nightly releases that were released before 15/10/24 (DD-MM-YY).

A simple server example:

  import K10.MsgServer

  @protocol kos_c_string("testprotocol")

  # Settings for publishing the protocol
  @request_label 1
  @request_badge 100
  @request_flags K10.MsgServer.kos_msg_flag_send_payload

  # Settings for client connection token
  @client_badge_start 10
  @client_token_flags K10.MsgServer.kos_msg_flag_send_payload
  @client_response_payload <<0::64, 0::32, 1::16, 0::16, "help\0">>

  def start(_type, _args) do

    # Set up the current pid as the one to receive kos_msg_server messages
    :ok = set_controlling_pid(self())

    # Publish the protocol
    :kos_status_ok = kos_dir_publish_str(@protocol, @request_label, @request_badge, @request_flags)

    # Read the protocol publish status.
    :kos_status_ok = kos_dir_query_str(@protocol)

    # Allocate a new empty token slot for creating new connection tokens.
    {:kos_status_ok, new_token_slot} = kos_msg_token_slot_pool_alloc()

    # Start receiving loop.
    receive_loop(new_token_slot, 0)

  end

  defp receive_loop(new_token_slot, num_clients) do
    receive do
      {:kos_msg, :up} ->
        # We are successfully receiving kos_msg_server messages.
        IO.puts("Server receiving messages:")
        receive_loop(new_token_slot, num_clients) 

      {:kos_msg, @request_badge, _caller, _msg} ->
        # Connection request
        IO.puts("Request protocol")

        # create a new token with a custom badge
        new_badge = @client_badge_start + num_clients
        :kos_status_created = kos_msg_token_create(new_badge, @client_token_flags, new_token_slot)
        
        # reply to the connection request with a new token for the client to use.
        client_connect_response = kos_msg_new(K10.MsgServer.kos_status_ok, 0, new_token_slot, @client_response_payload)
        :ok = reply(client_connect_response)
        receive_loop(new_token_slot, num_clients + 1) 

      {:kos_msg, badge, caller, kos_msg} ->
        # Message from a client
        IO.puts("Regular message")

        # Print message and reply with dummy response.
        IO.inspect({kos_msg, badge, caller})
        :ok = reply(kos_msg_new(600, 0, 0, "No funds"))
        receive_loop(new_token_slot, num_clients) 
    end
  end

A simple client example:

  import K10.MsgServer

  @protocol kos_c_string("testprotocol")

  @connection_request_msg kos_msg_new(0, 43, 0, "hi")
  @regular_msg kos_msg_new(1, 0, 0, "a_message")
  @regular_reply_flags K10.MsgServer.kos_msg_flag_send_payload
  def start(_type, _args) do
    hello()

    # Wait for the protocol to get published
    :kos_status_ok = check_published(@protocol)

    # Allocate an empty token slot and request a connection
    {:kos_status_ok, token} = kos_msg_token_slot_pool_alloc()
    {:kos_status_ok, _response_msg} = IO.inspect(kos_dir_request_str(@protocol, token, @connection_request_msg))

    # Once connection is successful send another message using the new token
    {:kos_status_ok, _response_msg} = IO.inspect(kos_msg_call(token, @regular_reply_flags, @regular_msg))

    {:ok, self()}
  end