v8dispatcher

package module
v0.0.0-...-c0c00a7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 6, 2016 License: MIT Imports: 6 Imported by: 0

README

v8dispatcher

v8dispatcher is a Go package for communicating to and from Javascript running in V8.

It provides a message abstraction layer on top of the v8worker package which has been enhanced to support synchronous messaging. The v8dispatcher has a MessageDispatcher component that is used to dispatch MessageSend values to function calls, both in Go and in Javascript (no reflection).

GoDoc

Calling Go from Javascript

Go

md := NewMessageDispatcher()
md.RegisterFunc("now",func(m MessageSend) (interface{},error) {
	return time.Now(), nil	
})

Javascript

var now = V8D.callReturn("","now");		

This is the minimal example for which a simple function (no arguments) is registered and called from Javascript when loading the source like this:

Go

md.Worker().Load("example.js", `var now = V8D.callReturn("","now");`)
Calling Javascript from Go

Javascript

function now() {
	return new Date();
}

Go

md := NewMessageDispatcher()
now, _ := md.CallReturn("this","now")
Asynchronous call from Javascript

Go

md := NewMessageDispatcher()
md.RegisterFunc("handleEvent",func(m MessageSend) (interface{},error) {
	dataMap := m.Arguments[0].(map[string]interface{})
	data := dataMap["data"]
	...
	return nil, nil	
})

Javascript

V8D.call("","handleEvent", {"data": "some event data"});
Asynchronous call from Go

Javascript

function handleEvent(data) {
	...
}

Go

md := NewMessageDispatcher()
md.Call("this","handleEvent",map[string]interface{}{
	"data" : "some event data",
})
Set and Get global variables

Go

md := NewMessageDispatcher()
md.Set("shoeSize",42)
shoeSize, _ := md.Get("shoeSize")

Javascript

var shoeSize = this["shoeSize"]	
MessageHandler

To invoke Go methods from Javascript, you can register a value whoes type implements the MessageHandler interface.

Go

type MusicPlayer struct {}

func (m MusicPlayer) Perform(m MessageSend) (interface{}, error) {
	switch (m.Selector) {
		case "start":
		case "stop":
		case "pause": 
		case "reset": 
		default: return nil , errors.New("unknown selector")
	}
}

Register an instance of MusicPlayer

Go

player := MusicPlayer{}
md := NewMessageDispatcher()
md.Register("player", player)

Now you can use this from Javascript

Javascript

V8D.call("player","start");

(c) 2016, http://ernestmicklei.com. MIT License

Documentation

Overview

Package v8dispatcher adds a message layer on top of the v8worker package (binding to Javascript V8).

The https://github.com/ry/v8worker package is a simple binding that provides a few Javascript operations to send simple messages (string) to and receive from Go. Recently, the v8worker package has been enhanced to support synchronous communication; this allows for accessing return values from functions. The v8dispatcher package sends MessageSend values serialized as JSON strings to be dispatched in Go or Javascript. A MessageDispatcher is used to dispatch MessageSend values to function calls, both in Go and in Javascript (no reflection).

Methods available in Go to invoke custom functions in Javascript (see MessageDispatcher):

// Call is an asynchronous call to Javascript and does no expect a return value.
// CallReturn is synchronous call to Javascript and expects a return value.
// Callback is an asynchronous call to Javascript that will perform a registered function with optional arguments.

Functions available in Javascript to invoke custom functions in Go (see js folder):

// V8D.call performs a MessageSend in Go and does NOT return a value.
// V8D.callReturn performs a MessageSend in Go and returns the value from that result.
// V8D.callThen performs a MessageSend in Go which calls the onReturn function with the result.

Variables in Javascript can be set and get using:

// Set will add/replace the value for a global variable in Javascript.
// Get will return the value for the global variable in Javascript.

Registration of dispatchers

Dispatching MessageSend values to functions in Go requires the registration of handlers. The RegisterFunc can be used to map a function name (the MessageSend receiver and/or selector) to a Go function. Alternatively, by implementing the MessageHandler interface, the mapping of selectors will have to be implemented in the Perform method.

Dispatching strategy

In Javascript, the receiver field of a MessageSend is used to find the namespace starting at the global. An empty receiver or "this" refers to the gobal namespace. The selector is used to lookup the function in the namespace.

In Go, the receiver field of a MessageSend is used to find a handler (MessageSendHandler) in the registry of the dispatcher. If found, the handler's Perform method is called with the MessageSend in which the selector can be inspected. An empty receiver will cause the dispatcher to look for a registered function (MessageSendHandlerFunc) instead.

A MessageDispatcher has a default function mapped on "console.log" that call the standard log.Println.

For examples see the README.md and the tests.

(c) 2016, http://ernestmicklei.com. MIT License

Index

Examples

Constants

This section is empty.

Variables

View Source
var Log = func(level, msg string, kvs ...interface{}) {

	buf := new(bytes.Buffer)
	fmt.Fprintf(buf, "[%s] %s", level, msg)
	for i := 0; i < len(kvs); i = i + 2 {
		var v interface{}
		if len(kvs) == i+1 {
			v = "*** missing ***"
		} else {
			v = kvs[i+1]
		}
		fmt.Fprintf(buf, ", %v = %v", kvs[i], v)
	}
	log.Println(buf.String())
}

Log can be used to inject your own logging framework

Functions

func ConsoleLog

func ConsoleLog(msg MessageSend) (interface{}, error)

ConsoleLog is the default registered function for "console.log" Register your own function to override this behavior.

Types

type MessageDispatcher

type MessageDispatcher struct {
	// contains filtered or unexported fields
}

MessageDispatcher is responsible for handling messages send from Javascript. It will do a receiver lookup and perform the message of the receiver. If no receiver given then the lookup is based on the selector to find the registered function.

func NewMessageDispatcher

func NewMessageDispatcher() *MessageDispatcher

NewMessageDispatcher returns a new MessageDispatcher initialize with empty handlers and a v8worker.

func (*MessageDispatcher) Call

func (d *MessageDispatcher) Call(receiver string, method string, arguments ...interface{}) error

Call is an asynchronous call to Javascript and does no expect a return value

func (*MessageDispatcher) CallReturn

func (d *MessageDispatcher) CallReturn(receiver string, method string, arguments ...interface{}) (interface{}, error)

CallReturn is synchronous call to Javascript and expects a return value

Example
md := NewMessageDispatcher()
md.Worker().Load("ex.js", `
		function now() {
			return new Date();
		}`)
now, _ := md.CallReturn("this", "now")
fmt.Println(now)
Output:

func (*MessageDispatcher) Callback

func (d *MessageDispatcher) Callback(functionReference string, arguments ...interface{}) error

Callback is an asynchronous call to Javascript that will perform a registered function with optional arguments. The funtionReference must have been created with "V8D.function_registry.put(yourFunction)".

func (*MessageDispatcher) Get

func (d *MessageDispatcher) Get(variableName string) (interface{}, error)

Get will return the value for the global variable in Javascript.

func (*MessageDispatcher) Receive

func (d *MessageDispatcher) Receive(jsonFromJS string)

Receive is a v8worker send async handler.

func (*MessageDispatcher) ReceiveSync

func (d *MessageDispatcher) ReceiveSync(jsonFromJS string) string

ReceiveSync is a v8worker send sync handler.

func (*MessageDispatcher) Register

func (d *MessageDispatcher) Register(name string, handler MessageSendHandler)

Register add a MessageSendHandler implementation that can perform MessageSends. The handler is called if the name matches the receiver of the MessageSend.

func (*MessageDispatcher) RegisterFunc

func (d *MessageDispatcher) RegisterFunc(name string, handler MessageSendHandlerFunc)

RegisterFunc adds a function as the handler of a MessageSend. The function is called if the name matches the selector of receiver.selector combination.

func (*MessageDispatcher) Set

func (d *MessageDispatcher) Set(variableName string, value interface{}) error

Set will add/replace the value for a global variable in Javascript.

func (*MessageDispatcher) Trace

func (d *MessageDispatcher) Trace(doTrace bool)

Trace will cause the internal message sends to be logged. See Log variable.

func (*MessageDispatcher) Worker

func (d *MessageDispatcher) Worker() *v8worker.Worker

Worker returns the worker for this dispatcher

type MessageSend

type MessageSend struct {
	// Receiver is used to lookup a registered MesageHandler
	Receiver string `json:"receiver" `

	// Selector is used to lookup a function or statement in a registered MessageHandler.
	Selector string `json:"selector" `

	// Arguments holds any arguments needed for the function
	Arguments []interface{} `json:"args" `

	// Callback can be a function reference registered in Javascript to call back into Javascript.
	Callback string `json:"callback" `

	// IsAsynchronous is to used to indicate that no return value is expected
	IsAsynchronous bool `json:"async"`
}

MessageSend encapsulates a performable message between Javascript and Go

func (MessageSend) JSON

func (m MessageSend) JSON() (string, error)

func (MessageSend) String

func (m MessageSend) String() string

String exists for debugging

type MessageSendHandler

type MessageSendHandler interface {
	Perform(MessageSend) (interface{}, error)
}

MessageSendHandler can be called by the dispatcher if registered using the message receiver.

type MessageSendHandlerFunc

type MessageSendHandlerFunc func(MessageSend) (interface{}, error)

MessageSendHandlerFunc is a function that can be called by the dispatcher if registered using the message selector or receiver.selector.

Directories

Path Synopsis
Command line program that interacts with a V8 Javascript engine through a v8dispatcher.MessageDispather go run cli.go Currently, every expression entered is wrapped in a console.log(...) call to print the value of that expression.
Command line program that interacts with a V8 Javascript engine through a v8dispatcher.MessageDispather go run cli.go Currently, every expression entered is wrapped in a console.log(...) call to print the value of that expression.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL