         @register_data_handler(opts.data_channel, session.handle_data)
         opts.cb(false, session)
 
+    _do_call: (opts, cb) =>
+        id = opts.message.id ?= misc.uuid()
+
+        @call_callbacks[id] =
+            cb          : (args...) =>
+                if cb?
+                    cb()
+                    cb = undefined
+                opts.cb(args...)
+            error_event : opts.error_event
+            first       : true
+
+        @send(opts.message)
+
+        if opts.timeout
+            setTimeout(
+                (() =>
+                    if @call_callbacks[id]?.first
+                        error = "Timeout after #{opts.timeout} seconds"
+                        if cb?
+                            cb()
+                            cb = undefined
+                        opts.cb(error, message.error(id:id, error:error))
+                        delete @call_callbacks[id]
+                ), opts.timeout*1000
+            )
+
     call: (opts={}) =>
         # This function:
         #    * Modifies the message by adding an id attribute with a random uuid value

        @setMaxListeners(3000)  # every open file/table/sync db listens for connect event, which adds up.

        @emit("connecting")
        @_id_counter       = 0
        @_sessions         = {}
        @_new_sessions     = {}

###############################################################################

DEBUG = false

# Maximum number of outstanding concurrent messages (that have responses)
# to send at once to the backend.
MAX_CONCURRENT = 20

{EventEmitter} = require('events')

