Skip to content

Writing Network Adapters

Thomas Howe edited this page Jun 8, 2016 · 2 revisions

Network Adapters

A network adapter connects a Greenbot Server to a messaging network. Samples of network adapters are available at https://github.com/green-bot/greenbot-core/tree/master/server/network_adapters

Architectural Choices

There are two basic methods to writing network adapters:

  1. Write a embedded adapter that is attached to the greenbot server node image
  2. Write an adapter that runs in a different process, then connects to the socket.io adapater of Greenbot

Embedded Network Adapter

The localtelnet adapter is a simple embedded adapter example. It starts a simple telnet server inside GreenBot, and allows a developer to connect using telnet for simple testing.

Telnet = require('telnet')
ShortUUID = require 'shortid'

The global events object allows the adapter to send and receive messages from greenbot-core. Messages are sent and received using the Events package of Node.

Pubsub = require('../pubsub')
events = Pubsub.pubsub

The network adapter has a telnet server to handle the inbound connection request from a telnet client. This code block will execute every time a new telnet connection arrives.

Telnet.createServer((client) ->

We have detected a new telnet session inbound. We need a unique name to register with the events so that we can catch the egress message.

  egressEvent = 'telnet'

When a line arrives from the telnet client, this callback fires.

  client.on 'data', (b) ->
    msg = b.toString()

Inbound (or ingress) messages require a simple structure identifying the source of the message, the destination, the text that arrives and the name of the event handler. Once created, send it in to the core.

    msg =
      dst: process.env.DEV_ROOM_NAME or 'development::telnet'
      src: 'telnet'
      txt: b.toString()
      egressEvent: egressEvent
    events.emit 'ingress', msg
    return

When a message comes from the core (egress), it will be show up in the egressEvent.

  events.on egressEvent, (msg) ->
    events.emit 'log', 'Local telnet egress' + msg.txt
    client.write new Buffer msg.txt + "\n"

  events.emit 'log',  'Telnet server listening'
  return
).listen 3002

Socket.io Connections

An alternative is to connect to the greenbot core using the socket.io connector. The socket.io connector listens on port GREENBOT_BOT_SERVER_PORT. Here's a browser-side example from greenbot-admin:

Start and connect to the socket.io connector to the far end.

socketUrl = Meteor.settings.public.GREENBOT_IO_URL console.log socketUrl connect = -> io.connect(socketUrl, { reconnection: true, reconnectionDelay: 1000, reconnectionDelayMax : 5000, reconnectionAttempts: Infinity })

@io = connect()
@io.on 'connect', -> console.log 'connected to server'
@io.on 'disconnect', ->
  console.log 'disconnected from server'
  window.setTimeout connect, 5000

Start the conversation by sending the keyword into the system.

@sendMsg(@keyword)

When messages are received from greenbot, they will appear on the egress event name.

@io.on 'egress', (msg) ->
  return if self.src isnt msg.dst
  self.drawMessage 'their', msg.txt

When the conversation is complete, we will get the 'session:ended' event. Be aware that session:ended events may not be for your session!!!

@io.on 'session:ended', (sess) =>
  return unless sess.src is @src
  console.log sess

  $('ul.tabs li').removeClass('disabled')
  $('form input').prop('disabled', true)
  collectedData.set(sess.collectedData)
  transcriptData.set(sess.transcript)
  self.logContainer.append("<p>Session has ended. You may start it over by pressing 'restart conversation' button.</p>")
  @disconnect()

disconnect: -> @io.disconnect() sendMsg: (txt) -> msg = dst: "development::#{ @handle }" src: @src txt: txt + '\n' @io.emit 'ingress', msg @drawMessage 'mine', msg.txt