initial API definition
This commit is contained in:
parent
d35b9045c7
commit
b8d1d7dc3d
48
client.go
Normal file
48
client.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package faye
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/thesyncim/faye/message"
|
||||||
|
"github.com/thesyncim/faye/transport"
|
||||||
|
)
|
||||||
|
|
||||||
|
type options struct {
|
||||||
|
inExtension message.Extension
|
||||||
|
outExtension message.Extension
|
||||||
|
transport transport.Transport
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultOpts = options{
|
||||||
|
transport: transport.GetTransport("websocket"),
|
||||||
|
}
|
||||||
|
|
||||||
|
//https://faye.jcoglan.com/architecture.html
|
||||||
|
type client interface {
|
||||||
|
Subscribe(subscription string, onMsg func(message *message.Message)) error
|
||||||
|
Publish(subscription string, message *message.Message) error
|
||||||
|
//todo unsubscribe,etc
|
||||||
|
}
|
||||||
|
|
||||||
|
type Option func(*options)
|
||||||
|
|
||||||
|
var _ client = (*Client)(nil)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
opts options
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(url string, opts ...Option) (*Client, error) {
|
||||||
|
var c Client
|
||||||
|
c.opts = defaultOpts
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(&c.opts)
|
||||||
|
}
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Subscribe(subscription string, onMsg func(message *message.Message)) error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Publish(subscription string, message *message.Message) error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
35
message/message.go
Normal file
35
message/message.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package message
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
type Extension func(message *Message)
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Channel string `json:"channel,omitempty"`
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
SupportedConnectionTypes []string `json:"supportedConnectionTypes,omitempty"`
|
||||||
|
MinimumVersion string `json:"minimumVersion,omitempty"`
|
||||||
|
Successful bool `json:"successful,omitempty"`
|
||||||
|
Ext interface{} `json:"ext,omitempty"`
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
ClientId string `json:"clientId,omitempty"`
|
||||||
|
Advice Advise `json:"advice,omitempty"`
|
||||||
|
Data interface{} `json:"data,omitempty"`
|
||||||
|
Timestamp uint64 `json:"timestamp,omitempty"`
|
||||||
|
AuthSuccessful bool `json:"authSuccessful,omitempty"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
Subscription string `json:"subscription,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) GetError() error {
|
||||||
|
if m.Error == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New(m.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Advise struct {
|
||||||
|
Reconnect string `json:"reconnect,omitempty"`
|
||||||
|
Interval int64 `json:"interval,omitempty"`
|
||||||
|
Timeout int64 `json:"timeout,omitempty"`
|
||||||
|
}
|
43
transport/transport.go
Normal file
43
transport/transport.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package transport
|
||||||
|
|
||||||
|
import "github.com/thesyncim/faye/message"
|
||||||
|
|
||||||
|
// handshake, connect, disconnect, subscribe, unsubscribe and publish
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
Url string
|
||||||
|
InExt message.Extension
|
||||||
|
outExt message.Extension
|
||||||
|
//todo dial timeout
|
||||||
|
//todo read/write deadline
|
||||||
|
}
|
||||||
|
|
||||||
|
type Transport interface {
|
||||||
|
Name() string
|
||||||
|
Init(options *Options) error
|
||||||
|
Options() *Options
|
||||||
|
Handshake() error
|
||||||
|
Connect() error
|
||||||
|
Subscribe(subscription string, onMessage func(message *message.Message)) error
|
||||||
|
Unsubscribe(subscription string) error
|
||||||
|
Publish(subscription string, message *message.Message) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Event string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Subscribe Event = "/meta/subscribe"
|
||||||
|
Unsubscribe Event = "/meta/unsubscribe"
|
||||||
|
Handshake Event = "/meta/handshake"
|
||||||
|
Disconnect Event = "/meta/disconnect"
|
||||||
|
)
|
||||||
|
|
||||||
|
var registeredTransports = map[string]Transport{}
|
||||||
|
|
||||||
|
func RegisterTransport(t Transport) {
|
||||||
|
registeredTransports[t.Name()] = t //todo validate
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTransport(name string) Transport {
|
||||||
|
return registeredTransports[name]
|
||||||
|
}
|
84
transport/websocket/websocket.go
Normal file
84
transport/websocket/websocket.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package websocket
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"github.com/thesyncim/faye/message"
|
||||||
|
"github.com/thesyncim/faye/transport"
|
||||||
|
"strconv"
|
||||||
|
"sync/atomic"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
transport.RegisterTransport(&Websocket{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Websocket struct {
|
||||||
|
TransportOpts *transport.Options
|
||||||
|
conn *websocket.Conn
|
||||||
|
clientID string
|
||||||
|
msgID *uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ transport.Transport = (*Websocket)(nil)
|
||||||
|
|
||||||
|
func (w *Websocket) Init(options *transport.Options) error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
msgID uint64
|
||||||
|
)
|
||||||
|
|
||||||
|
w.TransportOpts = options
|
||||||
|
w.msgID = &msgID
|
||||||
|
w.conn, _, err = websocket.DefaultDialer.Dial(options.Url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (w *Websocket) Name() string {
|
||||||
|
return "websocket"
|
||||||
|
}
|
||||||
|
func (w *Websocket) nextMsgID() string {
|
||||||
|
return strconv.Itoa(int(atomic.AddUint64(w.msgID, 1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Websocket) Options() *transport.Options {
|
||||||
|
return w.TransportOpts
|
||||||
|
}
|
||||||
|
func (w *Websocket) Handshake() (err error) {
|
||||||
|
if err = w.conn.WriteJSON(append(nil, message.Message{
|
||||||
|
Channel: string(transport.Handshake),
|
||||||
|
Version: "1.0", //todo const
|
||||||
|
SupportedConnectionTypes: []string{"websocket"},
|
||||||
|
})); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var hsResps []message.Message
|
||||||
|
if err = w.conn.ReadJSON(hsResps); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := hsResps[0]
|
||||||
|
if resp.GetError() != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.clientID = resp.ClientId
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Websocket) Connect() error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Websocket) Subscribe(subscription string, onMessage func(message *message.Message)) error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Websocket) Unsubscribe(subscription string) error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Websocket) Publish(subscription string, message *message.Message) error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user