Skip to content

Allow kite creation with an existing transport/ws #51

@usirin

Description

@usirin

This is crucial for creating a bi-directional connection between client/server. And would be used by rope.

This can be hooked into the KiteServer connection event.
We are emitting a Session object with connection event, and this occurs right after a server class receives a connection.
Since a low-level server class (e.g WebSocketServer and SockJsServer classes) will have a connection info attached to it and it's a similar object in which we are creating ourselves in Kite base class (this.ws = new WebSocket()) having a way to create a Kite object with an existing connection object would be really helpful here.

  • This is gonna be implemented in Kite base class, and it's gonna accept a connection via transport option.
  • If a transport option is present in the option, it's gonna immediately wrap the connection and it's gonna behave as it's connected.
  • This is gonna affect connect and onOpen functions.
    • onOpen is gonna be called immediately if a transport option is set to get things going.
    • connect is gonna be a noop.
  • autoReconnect option is gonna be redundant when a transport option is present, as we don't know how we are gonna connect back to a connection if we didn't create it.
  • url option will not gonna be used.

Let's say we have a KiteServer running on ws://localhost:9999:

import { KiteServer } from 'kite.js'

const server = new KiteServer({
  name: 'square',
  auth: false,
  api: {
    square(x, done) { done(null, x * x) }
  }
})

server.listen(9999)

After transport option feature is implemented we will be able to connect to this server with 2 different ways:

import { Kite } from 'kite.js'
import WebSocket from 'ws'

// first the usual one:
const kite = new Kite({
  url: 'ws://localhost:9999',
  auth: false,
})

kite.connect()

// with transport option we will be able to reuse a `ws` connection:
const ws = new WebSocket('ws://localhost:9999')
const kite = new Kite({
  auth: false,
  transport: ws
})

Why do we need this?

Rope server implementation requires bi-directional communication between 2 ends of the websocket connection. If we were to have this way of passing transport objects on Kite client creation, required implementation for Rope can be satisfied within the api limits of Kite and KiteServer:

After introduction of transport option, following would be how we could interact with the other end of the connection:

// client.js
import { Kite } from 'kite.js'

const kite = new Kite({
  name: 'basic-whoami',
  api: {
    whoami(callback) {
      callback(null, 'square')
    }
  }
})
// server.js
import { Kite, KiteServer } from 'kite.js'

const server = new KiteServer({
  name: 'square',
  auth: false,
  api: {
    square(x, done) { done(null, x * x) }
  }
})

// add an event listener directly onto server object of created KiteServer.
server.server.on('connection', connection => {
  const otherKite = new Kite({
    auth: false,
    transport: connection
  })

  otherKite.tell('whoami').then(res => console.log(`Hello my name is ${res}`))
  // => Hello my name is square
})

server.listen(9999)

What i was trying to explain in the beginning was instead of attaching an event listener of the internal server object, we can use existing connection event of KiteServer, and the connection/session object emitted with it will have a kite object attached to it, so if we were to rewrite the last example:

// server.js
import { Kite, KiteServer } from 'kite.js'

const server = new KiteServer({
  name: 'square',
  auth: false,
  api: {
    square(x, done) { done(null, x * x) }
  }
})

// add an event listener directly to our KiteServer instance connection object
// connection object passed to it will have a reference to the caller kite which is an instance of `Kite`
server.on('connection', connection => {
  const otherKite = connection.kite
  otherKite.tell('whoami').then(res => console.log(`Hello my name is ${res}`))
  // => Hello my name is square
})
server.listen(9999)

/cc @gokmen

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions