# NetWorking

# Introduction

In order to communicate with other services, you need to configure a transporter. Most of the supported transporters connect to a central message broker that provide a reliable way of exchanging messages among remote services.

# Transporter

In ExpressWebJs, transporter is an important feature if you are running services on multiple nodes. Transporter communicates with other nodes. It transfers events, calls requests and processes responses. If multiple instances of a service are running on different nodes then the requests will be load-balanced among them.

The whole communication logic is outside of transporter class which means that you can switch between transporters without changing any line of code.

ExpressWebJs supports several built-in transporters.

# TCP transporter

TCP uses Gossip protocol to disseminate node status, service list and heartbeats. It contains an integrated UDP discovery feature to detect new and disconnected nodes on the network. If the UDP is prohibited on your network, use urls option. It is a list of remote endpoints (host/ip, port, nodeID). It can be a static list in your configuration or a file path which contains the list.

# Use TCP transporter with default options

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "TCP",
  },
});
Copied!

# All TCP transporter options with default values

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: {
      type: "TCP",
      options: {
        // Enable UDP discovery
        udpDiscovery: true,
        // Reusing UDP server socket
        udpReuseAddr: true,

        // UDP port
        udpPort: 4445,
        // UDP bind address (if null, bind on all interfaces)
        udpBindAddress: null,
        // UDP sending period (seconds)
        udpPeriod: 30,

        // Multicast address.
        udpMulticast: "239.0.0.0",
        // Multicast TTL setting
        udpMulticastTTL: 1,

        // Send broadcast (Boolean, String, Array<String>)
        udpBroadcast: false,

        // TCP server port. Null or 0 means random port
        port: null,
        // Static remote nodes address list (when UDP discovery is not available)
        urls: null,
        // Use hostname as preffered connection address
        useHostname: true,

        // Gossip sending period in seconds
        gossipPeriod: 2,
        // Maximum enabled outgoing connections. If reach, close the old connections
        maxConnections: 32,
        // Maximum TCP packet size
        maxPacketSize: 1 * 1024 * 1024,
      },
    },
  },
});
Copied!

# TCP transporter with static endpoint list

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    nodeID: "node-1",
    transporter: {
      type: "TCP",
      options: {
        udpDiscovery: false,
        urls: ["172.17.0.1:6000/node-1", "172.17.0.2:6000/node-2", "172.17.0.3:6000/node-3"],
      },
    },
  },
});
Copied!

# TCP transporter with shorthand static endpoint list

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    nodeID: "node-1",
    transporter: "tcp://172.17.0.1:6000/node-1,172.17.0.2:6000/node-2,172.17.0.3:6000/node-3",
  },
});
Copied!

# TCP transporter with static endpoint list file

// app.ts

StartApp.withServiceBroker({
  BrokerOptions: {
    nodeID: "node-1",
    transporter: "file://./nodes.json",
  },
});
Copied!
// nodes.json
["127.0.0.1:6001/client-1", "127.0.0.1:7001/server-1", "127.0.0.1:7002/server-2"];
Copied!
💡 Serviceless node: Please note, you don’t need to list all remote nodes. It’s enough at least one node which is online. For example, create a “serviceless” gossiper node, which does nothing, just shares other remote nodes addresses by gossip messages. So all nodes must know only the gossiper node address to be able to communicate with all other nodes.

# NATS Transporter

Built-in transporter for NATS.

💡 NATS Server is a simple, high performance open source messaging system for cloud-native applications, IoT messaging, and microservices architectures.
📦 Dependencies: To use the nats transporter, you will need to install the nats node package with npm install nats --save command.
// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    nodeID: "server-1",
    transporter: "nats://nats.server:4222",
  },
});
Copied!

# Connect to ‘nats://localhost:4222’

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "NATS",
  },
});
Copied!

# Connect to a remote NATS server

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "nats://nats-server:4222",
  },
});
Copied!

# Connect to a remote NATS server with auth

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "nats://user:pass@nats-server:4222",
  },
});
Copied!

# Connect with options

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: {
      type: "NATS",
      options: {
        servers: ["nats://localhost:4222"],
        user: "admin",
        pass: "1234",
      },
    },
  },
});
Copied!

# Connect with TLS

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: {
        type: "NATS",
        options: {
            servers: ["nats://localhost:4222"]
            // More info: https://github.com/nats-io/node-nats#tls
            tls: {
                key: fs.readFileSync('./client-key.pem'),
                cert: fs.readFileSync('./client-cert.pem'),
                ca: [ fs.readFileSync('./ca.pem') ]
            }
        }
    }
  }});
Copied!

# Redis Transporter

Built-in transporter for Redis.

💡 Redis in-memory data store used by millions of developers as a database, cache, streaming engine, and message broker.
📦 Dependencies: To use redis transporter, you will need to install the ioredis node package with npm install ioredis --save command.
// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    nodeID: "server-1",
    transporter: "redis://redis.server:6379",
  },
});
Copied!

# Redis default setting connection

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    nodeID: "server-1",
    transporter: "Redis",
  },
});
Copied!

# Connect with redis connection string

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "redis://localhost:6379",
  },
});
Copied!

# Connect to a secure Redis server

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "redis://localhost:6379",
  },
});
Copied!

# Connect with redis options

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: {
      type: "Redis",
      options: {
        host: "redis-server",
        db: 0,
      },
    },
  },
});
Copied!

# Connect to Redis cluster

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: {
      type: "Redis",
      options: {
        cluster: {
          nodes: [
            { host: "localhost", port: 6379 },
            { host: "localhost", port: 6378 },
          ],
        },
      },
    },
  },
});
Copied!

# MQTT Transporter

Built-in transporter for MQTT.

💡 MQTT is an OASIS standard messaging protocol for the Internet of Things (IoT). It is designed as an extremely lightweight publish/subscribe messaging transport that is ideal for connecting remote devices with a small code footprint and minimal network bandwidth.
📦 Dependencies: To use mqtt transporter, you will need to install the mqtt node package with npm install mqtt --save command.
// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    nodeID: "server-1",
    transporter: "mqtt://mqtt-server:1883",
  },
});
Copied!

# MQTT default setting connection

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "MQTT",
  },
});
Copied!

# Connect with MQTT connection string

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "mqtt://mqtt-server:1883",
  },
});
Copied!

# Connect to secure MQTT server

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "mqtts://mqtt-server:1883",
  },
});
Copied!

# Connect to MQTT options

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: {
      type: "MQTT",
      options: {
        host: "mqtt-server",
        port: 1883,
        qos: 0,
        topicSeparator: ".",
      },
    },
  },
});
Copied!

# AMQP (0.9) Transporter

Built-in transporter for AMQP. 0.9 protocol (e.g.: RabbitMQ).

💡RabbitMQ is an open-source message-broker software that originally implemented the Advanced Message Queuing Protocol and has since been extended with a plug-in architecture to support Streaming Text Oriented Messaging Protocol, MQ Telemetry Transport, and other protocols.
📦 Dependencies: To use amqp transporter, you will need to install the amqplib node package with npm install amqplib --save command.

# Connect to ‘amqp://guest:guest@localhost:5672’

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "AMQP",
  },
});
Copied!

# Connect to a remote amqp server

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "amqp://rabbitmq-server:5672",
  },
});
Copied!

# Connect to a secure amqp server

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "amqps://rabbitmq-server:5672",
  },
});
Copied!

# Connect to a remote amqp server with options & credentials

// app.ts

StartApp.withServiceBroker({
  brokerOptions:{
    transporter: {
        type: "AMQP",
        options: {
            url: "amqp://user:pass@rabbitmq-server:5672",
            eventTimeToLive: 5000,
            prefetch: 1,
            socketOptions: {
                servername: process.env.RABBIT_SERVER_NAME
            }
            // If true, queues will be autodeleted once service is stopped, i.e., queue listener is removed
            autoDeleteQueues: true
        }
    }
  }});
Copied!

# Kafka Transporter

Built-in transporter for Kafka.

💡Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for high-performance data pipelines, streaming analytics, data integration, and mission-critical applications.
📦 Dependencies: To use kafka transporter, you will need to install the kafka node package with npm install kafka-node --save command.

# Connect to Zookeeper

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "kafka://192.168.51.29:2181",
  },
});
Copied!

# Connect to Zookeeper with custom options

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: {
      type: "kafka",
      options: {
        host: "192.168.51.29:2181",

        // KafkaClient options. More info: https://github.com/SOHU-Co/kafka-node#clientconnectionstring-clientid-zkoptions-noackbatchoptions-ssloptions
        client: {
          zkOptions: undefined,
          noAckBatchOptions: undefined,
          sslOptions: undefined,
        },

        // KafkaProducer options. More info: https://github.com/SOHU-Co/kafka-node#producerclient-options-custompartitioner
        producer: {},
        customPartitioner: undefined,

        // ConsumerGroup options. More info: https://github.com/SOHU-Co/kafka-node#consumergroupoptions-topics
        consumer: {},

        // Advanced options for `send`. More info: https://github.com/SOHU-Co/kafka-node#sendpayloads-cb
        publish: {
          partition: 0,
          attributes: 0,
        },
      },
    },
  },
});
Copied!

# NATS Streaming (STAN) Transporter

Built-in transporter for NATS.

📦 Dependencies: To use this transporter, you will need to install the node-nats-streaming node package with npm install node-nats-streaming --save command.
// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    nodeID: "server-1",
    transporter: "stan://nats-streaming-server:4222",
  },
});
Copied!

# Connect with NATS connection string

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: "stan://nats-streaming-server:4222",
  },
});
Copied!

# Connect with NATS options

// app.ts

StartApp.withServiceBroker({
  brokerOptions: {
    transporter: {
      type: "STAN",
      options: {
        url: "stan://127.0.0.1:4222",
        clusterID: "my-cluster",
      },
    },
  },
});
Copied!