# Connecting Multiple Scripts on the Same Computer using NEP+ Tools: A Step-by-Step Tutorial

{% hint style="success" %}
In this tutorial, we will guide you through the process of connecting two or more scripts that reside on the same computer using NEP+ tools and libraries
{% endhint %}

## Background:

In this tutorial, we will explore the Publisher-Subscriber pattern for sending messages between scripts. A fascinating aspect of this approach is its ability to connect scripts written in different programming languages.

### What is the  Publisher-Subscriber pattern?&#x20;

The publisher-subscriber pattern is a messaging design pattern where publishers and subscribers interact without direct knowledge of each other. Publishers are responsible for sending messages, while subscribers express interest in receiving specific types of messages.

The publisher-subscriber pattern offers the advantage of asynchrony, allowing publishers to send messages without waiting for subscribers to process them and enabling subscribers to receive messages at their own pace. This asynchrony enhances system responsiveness and overall performance by decoupling the timing of message production and consumption.

The publisher-subscriber pattern provides the benefit of loose coupling, which enables independent development and maintenance of publishers and subscribers.

{% hint style="info" %}
Communication between a Publisher socket and a Subscriber socket is generally configured to be **asynchronous**. Therefore, the **Subscriber socket will not block the program execution** when trying to read a message.
{% endhint %}

### What is a topic?

In the publisher-subscriber pattern, a topic is a category or subject assigned to messages. Publishers use topics to indicate the content of messages, while subscribers express interest in receiving messages based on specific topics. Topics enable subscribers to filter and receive only relevant messages, optimizing communication efficiency. They serve as a classification mechanism that helps organize and target messages based on shared interests or message types.

### What is a node?

In the context of distributed systems or network architectures, a node refers to an individual device or entity that participates in the system. Each node typically has a unique identifier, commonly known as a node ID or node name. The node name is a distinctive value assigned to the node, allowing it to be uniquely identified and distinguished from other nodes within the system.

### What is a message type?

The message type or format refers to the structure and encoding of the data within a message. It defines how the data is organized, represented, and interpreted by the publisher and subscriber components. JSON (JavaScript Object Notation) is a commonly used format that specifies the structure of the message using key-value pairs. With NEP+, publishers and subscribers can encode and decode messages in JSON format, ensuring a shared understanding of the data's structure and facilitating consistent communication within the publisher-subscriber system.

## Prerequisites:&#x20;

Before you proceed with this tutorial, make sure you have one of the following NEP+ tools installed on your computer:

<table><thead><tr><th width="174.04817179338363">NEP+ tool</th><th>Requirements</th><th>Comments</th></tr></thead><tbody><tr><td><a href="../../../developer-tools/nep-cli#manage-connection-between-nodes">NEP CLI</a></td><td>Node.js and nep-cli package installed</td><td>For users preferring command line tools</td></tr><tr><td><a href="../../user-interfaces/nep+-app-0.0.4-deprecated">NEP+ App</a></td><td>NEP+ app installed</td><td>For users preferring graphical interfaces</td></tr></tbody></table>

## Step 1: Executing NEP+ environment

### If using NEP-CLI

Execute the following command, and don't close the terminal&#x20;

```shell
nep master
```

### If using NEP+ App

Just open the NEP+ App and don't close the interface

## Step 2: Create a Publisher socket

1. Importing the necessary modules:

{% tabs %}
{% tab title="Python" %}
```python
import nep
import time
```
{% endtab %}

{% tab title="C#" %}
```csharp
using Nep;
using Newtonsoft.Json;
```
{% endtab %}

{% tab title="Java" %}
```java
import java.util.HashMap;
import java.util.Map;
import nep.Node;
import nep.Publisher;
```
{% endtab %}
{% endtabs %}

2. Creating a new nep node:

{% tabs %}
{% tab title="Python" %}
```python
node = nep.node('basic_pub_py')
```
{% endtab %}

{% tab title="C#" %}
```csharp
NepNode node = new NepNode("basic_pub_cs");
```
{% endtab %}

{% tab title="Java" %}
```java
 Node node = new Node("basic_pub_jv");
```
{% endtab %}
{% endtabs %}

3. Create a new Publisher and define the type of message as **JSON**:

{% tabs %}
{% tab title="Python" %}
```python
pub = node.new_pub('test','json')
```
{% endtab %}

{% tab title="C#" %}
```csharp
NepPublisher pub = node.NewPub("test", "json");
```
{% endtab %}

{% tab title="Java" %}
```java
Publisher pub = node.new_pub("test", "json");
```
{% endtab %}
{% endtabs %}

4. Send a JSON message:

{% tabs %}
{% tab title="Python" %}
```python
 # Define the message to send using the JSON format (a python dictionary)
 msg = {'message':0}
 # Send the message with the next line	
 pub.publish(msg)
```
{% endtab %}

{% tab title="C#" %}
```csharp
// Message to send, used for serialization in JSON
class Msg
{
    public int message { get; set; }
}

// ...

//  Create a new message
Msg msg = new Msg();
    
// Fill message to send
msg.message = 0;
// Send the message with the next line
pub.Publish(msg);
```
{% endtab %}

{% tab title="Java" %}
<pre class="language-java"><code class="lang-java">// A HashMap stores items in "key/value" pairs and can be used to define messages to send
Map msg = new HashMap();
// ...
// Fill message to send
msg.put("message", 0);
<strong>// Send the message with the next line
</strong>pub.publish(msg);
</code></pre>
{% endtab %}
{% endtabs %}

A full example of sending 50 messages each .5 seconds is show below:&#x20;

{% tabs %}
{% tab title="Python" %}
```python
import nep
import time

# Create a new nep node
# The parameter given to this function must be different for each script
node = nep.node('basic_pub_py') 
# Create a new publisher with the topic 'test'
pub = node.new_pub('test','json')

i = 0
while i<50 :
    # You will put your code here ...
    i = i + 1
    # Define the message to send using the JSON format (a python dictionary)
    msg = {'message':i}
    # Send the message with the next line	
    pub.publish(msg)
    # Use the next line to send messages each 0.5 seconds approx.	
    time.sleep(.5)

print('Publisher program finished!')
```
{% endtab %}

{% tab title="C#" %}
```csharp
using Nep;

namespace NepTest
{
    // Message to send, used for serialization in JSON
    class Msg
    {
        public int message { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Create a new nep node
            // The parameter given to this function must be different for each script
            NepNode node = new NepNode("basic_pub_cs");
            // Create a new publisher with the topic "test"
            NepPublisher pub = node.NewPub("test", "json");
            // Define the message to send 
            Msg msg = new Msg();
            int i = 0;
            while (i < 50)
            {
                i++;
                // Fill message to send
                msg.message = i;
                // Send the message with the next line
                pub.Publish(msg);
                // Use the next line to send messages each 0.5 seconds approx.
                System.Threading.Thread.Sleep(500);
            }
            // Close sockets
            pub.Dispose();
            node.Close();
            Console.WriteLine("Publisher program finished!");
        }
    }
}
```
{% endtab %}

{% tab title="Java" %}
```java
import java.util.HashMap;
import java.util.Map;
import nep.Node;
import nep.Publisher;


public class Testnep { // Change the name of the class 

    public static void main(String[] args) {
        
        // Create a new nep node
        // The parameter given to this function must be different for each script
        Node node = new Node("basic_pub_jv");
        // Create a new publisher with the topic <'test'>
        Publisher pub = node.new_pub("test");
        // A HashMap stores items in "key/value" pairs and can be used to define messages to send
        Map msg = new HashMap();
        int i = 0;
        // # You will put your code here, which is doing some analysis...
        while(i<50)
        {    
            i++;
            // Set message to send
            msg.put("result", i);
            // Send message
            pub.publish(msg);
            // Thread.sleep is used to send messages each 0.5 seconds 
            try{
                Thread.sleep(500);
            }
            catch(java.lang.InterruptedException ie){
            }
             
        }
    }
}
```
{% endtab %}
{% endtabs %}

## Step 3: Create a Subscriber socket (in another script)

1. Importing the necessary modules:

{% tabs %}
{% tab title="Python" %}
```python
import nep
import time
```
{% endtab %}

{% tab title="C#" %}
```csharp
using Nep;
using Newtonsoft.Json;
```
{% endtab %}

{% tab title="Java" %}
```java
import java.util.HashMap;
import java.util.Map;
import nep.Node;
import nep.Publisher;
```
{% endtab %}
{% endtabs %}

2. Creating a new nep node:

{% tabs %}
{% tab title="Python" %}
```python
node = nep.node('basic_sub_py')
```
{% endtab %}

{% tab title="C#" %}
```csharp
NepNode node = new NepNode("basic_sub_cs");
```
{% endtab %}

{% tab title="Java" %}
```java
 Node node = new Node("basic_sub_jv");
```
{% endtab %}
{% endtabs %}

3. Create a new Subscriber and define the type of message as **json**:

{% tabs %}
{% tab title="Python" %}
```python
sub = node.new_sub('test','json') 
```
{% endtab %}

{% tab title="C#" %}
```csharp
NepSubscriber sub = node.NewSub("test", "json");
```
{% endtab %}

{% tab title="Java" %}
```java
Subscriber sub = node.new_sub("test", "json");
```
{% endtab %}
{% endtabs %}

4. Listen JSON messages:

{% tabs %}
{% tab title="Python" %}
```python
s, msg = sub.listen() 
# if s == True, then there is data in the socket      
if s:                     
    # Print messsage
    print(msg)
# otherwise, the program does not block
else:
# A small sleep is not compulsory but can reduce the computational load
    time.sleep(.0001)
```
{% endtab %}

{% tab title="C#" %}
```csharp
/// Non-blocking listen to receive a message
bool ok = sub.Listen(out msg);
if (ok)
{
    // Convert JSON string to Msg object using JsonConvert
    Msg message = JsonConvert.DeserializeObject<Msg>(msg);
    Console.WriteLine(message.message);
    i = i + 1;
}
```
{% endtab %}

{% tab title="Java" %}
```java
String msg = sub.listen(); // Message obtained as an String
if (!"{}".equals(msg)) // If message is not {}
{
                // Convert string to Java object
                Gson gson = new Gson();
                json_value obj = gson.fromJson(msg,json_value.class);
                // Print message
                System.out.println(obj.result);
} 
```
{% endtab %}
{% endtabs %}

A full example of a subscriber is show below:&#x20;

{% tabs %}
{% tab title="Python" %}
```python
import nep
import time

# Create a new nep node. The name set to a NEP node must be different for each script
node = nep.node('basic_sub_py')
# Create a new subscriber with the topic 'test'   
sub = node.new_sub('test','json') 

i = 0
while i<50:
    # Read data in a non-blocking mode
    s, msg = sub.listen() 
    # if s == True, then there is data in the socket      
    if s:                       
        print(msg)
        i = i + 1
    # otherwise, the program does not block
    else:
        # A small sleep is not compulsory but can reduce the computational load
        time.sleep(.0001)

print('Subscriber program finished!')
```
{% endtab %}

{% tab title="C#" %}
```csharp
using System;
using Nep;
using Newtonsoft.Json;

// Change <NepTest> for the correct namespace
namespace NepTest
{
    // Message to read, used for deserialization
    class Msg
    {
        // JSON key = message, value is an int
        public int message { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Create a new Nep Node with a specified name
            NepNode node = new NepNode("basic_sub_cs");

            // Create a new Subscriber for the "test" topic with "json" message type
            NepSubscriber sub = node.NewSub("test", "json");

            String msg = "";

            // Print the received messages
            int i = 0;
            while (i < 50)
            {
                // Non-blocking listen to receive a message
                bool ok = sub.Listen(out msg);
                if (ok)
                {
                    // Convert JSON string to Msg object using JsonConvert
                    Msg message = JsonConvert.DeserializeObject<Msg>(msg);
                    Console.WriteLine(message.message);
                    i = i + 1;
                }
            }

            // Close the Subscriber and Node
            sub.Dispose();
            node.Close();

            Console.WriteLine("Subscriber program finished!");
        }
    }
}
```
{% endtab %}

{% tab title="Unity" %}
<pre class="language-csharp"><code class="lang-csharp">using Nep;
using Newtonsoft.Json;
// ...

// Inside the MonoBehaviour
public NepCallback sub;
Msg msg2read;

class Msg
{
    public int {get; set;}
}

// ...



void Start()
{
<strong>    node = new Node("basic_sub_unity");
</strong><strong>    System.Action&#x3C;string> printAction = read_callback;
</strong><strong>    sub = node.new_callback("test", "json", printAction);
</strong>    sub.Start();
}

void read_callback(string message)
{
    msg2read = JsonConvert.DeserializeObject&#x3C;Msg>(message);
}


void Update()
{
    sub.UpdateMessage();
}


private void OnDestroy()
{
    sub.Stop();
    node.close();
}

</code></pre>
{% endtab %}

{% tab title="Java" %}
```java
import nep.Node;
import nep.Subscriber; 
import com.google.gson.Gson; // Important -- import this module
import java.io.IOException;


public class Testnep { // Change the name of the class 
    
    // This class will be used to save messages obtained by the subscriber
    public class json_value { 
        int result;
    }

    // throws IOException is required 
    public static void main(String[] args) throws IOException {  
        
        // Create a new nep node
        // The parameter given to this function must be different for each script
        Node node = new Node("basic_sub_jv");
        // Create a new publisher with the topic <'test'>
        Subscriber sub = node.new_sub("test");
     
        while(true)
        {    
            String msg = sub.listen(); // Message obtained as an String
            if (!"{}".equals(msg)) // If message is not {}
            {
                // Then, convert string to Java object
                Gson gson = new Gson();
                json_value obj = gson.fromJson(msg,json_value.class);
                // Print message
                System.out.println(obj.result);
            } 
             
        }
    }
}
```
{% endtab %}
{% endtabs %}
