support Publish event
This commit is contained in:
parent
7bfdcc9f48
commit
01f041d2fc
14
client.go
14
client.go
@ -21,8 +21,8 @@ type client interface {
|
||||
Disconnect() error
|
||||
Subscribe(subscription string, onMessage func(message message.Data)) error
|
||||
Unsubscribe(subscription string) error
|
||||
Publish(subscription string, message message.Data) error
|
||||
//todo unsubscribe,etc
|
||||
Publish(subscription string, message message.Data) (string, error)
|
||||
OnPublishResponse(subscription string, onMsg func(message *message.Message))
|
||||
}
|
||||
|
||||
type Option func(*options)
|
||||
@ -68,10 +68,18 @@ func (c *Client) Unsubscribe(subscription string) error {
|
||||
return c.opts.transport.Unsubscribe(subscription)
|
||||
}
|
||||
|
||||
func (c *Client) Publish(subscription string, data message.Data) error {
|
||||
func (c *Client) Publish(subscription string, data message.Data) (id string, err error) {
|
||||
return c.opts.transport.Publish(subscription, data)
|
||||
}
|
||||
|
||||
//OnPublishResponse sets the handler to be triggered if the server replies to the publish request
|
||||
//according to the spec the server MAY reply to the publish request, so its not guaranteed that this handler will
|
||||
//ever be triggered
|
||||
//can be used to identify the status of the published request and for example retry failed published requests
|
||||
func (c *Client) OnPublishResponse(subscription string, onMsg func(message *message.Message)) {
|
||||
c.opts.transport.OnPublishResponse(subscription, onMsg)
|
||||
}
|
||||
|
||||
func (c *Client) Disconnect() error {
|
||||
return c.opts.transport.Disconnect()
|
||||
}
|
||||
|
@ -26,17 +26,29 @@ type Transport interface {
|
||||
Disconnect() error
|
||||
Subscribe(subscription string, onMessage func(message message.Data)) error
|
||||
Unsubscribe(subscription string) error
|
||||
Publish(subscription string, message message.Data) error
|
||||
Publish(subscription string, message message.Data) (id string, err error)
|
||||
//OnPublishResponse sets the handler to be triggered if the server replies to the publish request
|
||||
//according to the spec the server MAY reply to the publish request, so its not guaranteed that this handler will
|
||||
//ever be triggered
|
||||
//can be used to identify the status of the published request and for example retry failed published requests
|
||||
OnPublishResponse(subscription string, onMsg func(message *message.Message))
|
||||
}
|
||||
|
||||
type Meta = string
|
||||
type MetaMessage = string
|
||||
|
||||
const (
|
||||
MetaSubscribe Meta = "/meta/subscribe"
|
||||
MetaConnect Meta = "/meta/connect"
|
||||
MetaDisconnect Meta = "/meta/disconnect"
|
||||
MetaUnsubscribe Meta = "/meta/unsubscribe"
|
||||
MetaHandshake Meta = "/meta/handshake"
|
||||
MetaSubscribe MetaMessage = "/meta/subscribe"
|
||||
MetaConnect MetaMessage = "/meta/connect"
|
||||
MetaDisconnect MetaMessage = "/meta/disconnect"
|
||||
MetaUnsubscribe MetaMessage = "/meta/unsubscribe"
|
||||
MetaHandshake MetaMessage = "/meta/handshake"
|
||||
)
|
||||
|
||||
type EventMessage = int
|
||||
|
||||
const (
|
||||
EventPublish EventMessage = iota
|
||||
EventDelivery
|
||||
)
|
||||
|
||||
type Reconnect = string
|
||||
@ -56,17 +68,28 @@ const (
|
||||
ReconnectNone Reconnect = "none"
|
||||
)
|
||||
|
||||
var MetaEvents = []Meta{MetaSubscribe, MetaConnect, MetaUnsubscribe, MetaHandshake, MetaDisconnect}
|
||||
var metaMessages = []MetaMessage{MetaSubscribe, MetaConnect, MetaUnsubscribe, MetaHandshake, MetaDisconnect}
|
||||
|
||||
func IsMetaEvent(channel string) bool {
|
||||
for i := range MetaEvents {
|
||||
if channel == MetaEvents[i] {
|
||||
func IsMetaMessage(msg *message.Message) bool {
|
||||
for i := range metaMessages {
|
||||
if msg.Channel == metaMessages[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsEventDelivery(msg *message.Message) bool {
|
||||
if msg.Data != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsEventPublish(msg *message.Message) bool {
|
||||
return !IsEventDelivery(msg)
|
||||
}
|
||||
|
||||
var registeredTransports = map[string]Transport{}
|
||||
|
||||
func RegisterTransport(t Transport) {
|
||||
|
@ -25,10 +25,13 @@ type Websocket struct {
|
||||
once sync.Once
|
||||
advice atomic.Value //type message.Advise
|
||||
|
||||
stopCh chan struct{}
|
||||
stopCh chan error
|
||||
|
||||
subsMu sync.Mutex //todo sync.Map
|
||||
subs map[string]chan *message.Message
|
||||
|
||||
onPubResponseMu sync.Mutex //todo sync.Map
|
||||
onPublishResponse map[string]func(message *message.Message)
|
||||
}
|
||||
|
||||
var _ transport.Transport = (*Websocket)(nil)
|
||||
@ -41,7 +44,7 @@ func (w *Websocket) Init(options *transport.Options) error {
|
||||
w.TransportOpts = options
|
||||
w.msgID = &msgID
|
||||
w.subs = map[string]chan *message.Message{}
|
||||
w.stopCh = make(chan struct{})
|
||||
w.stopCh = make(chan error)
|
||||
w.conn, _, err = websocket.DefaultDialer.Dial(options.Url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -52,8 +55,8 @@ func (w *Websocket) Init(options *transport.Options) error {
|
||||
func (w *Websocket) readWorker() error {
|
||||
for {
|
||||
select {
|
||||
case <-w.stopCh:
|
||||
return nil
|
||||
case err := <-w.stopCh:
|
||||
return err
|
||||
default:
|
||||
}
|
||||
var payload []message.Message
|
||||
@ -68,7 +71,7 @@ func (w *Websocket) readWorker() error {
|
||||
w.handleAdvise(msg.Advice)
|
||||
}
|
||||
|
||||
if transport.IsMetaEvent(msg.Channel) {
|
||||
if transport.IsMetaMessage(msg) {
|
||||
//handle it
|
||||
switch msg.Channel {
|
||||
case transport.MetaSubscribe:
|
||||
@ -104,7 +107,12 @@ func (w *Websocket) readWorker() error {
|
||||
|
||||
continue
|
||||
}
|
||||
//is Event Message
|
||||
//there are 2 types of Event Message
|
||||
// 1. Publish
|
||||
// 2. Delivery
|
||||
|
||||
if transport.IsEventDelivery(msg) {
|
||||
w.subsMu.Lock()
|
||||
subscription := w.subs[msg.Channel]
|
||||
w.subsMu.Unlock()
|
||||
@ -114,6 +122,18 @@ func (w *Websocket) readWorker() error {
|
||||
if subscription != nil {
|
||||
subscription <- msg
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if transport.IsEventPublish(msg) {
|
||||
w.onPubResponseMu.Lock()
|
||||
onPublish, ok := w.onPublishResponse[msg.Channel]
|
||||
w.onPubResponseMu.Unlock()
|
||||
if ok {
|
||||
onPublish(msg)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +200,7 @@ func (w *Websocket) Disconnect() error {
|
||||
Id: w.nextMsgID(),
|
||||
}
|
||||
|
||||
w.stopCh <- struct{}{}
|
||||
w.stopCh <- nil
|
||||
close(w.stopCh)
|
||||
|
||||
return w.sendMessage(&m)
|
||||
@ -212,6 +232,8 @@ func (w *Websocket) Subscribe(subscription string, onMessage func(data message.D
|
||||
}
|
||||
onMessage(inMsg.Data)
|
||||
}
|
||||
//we we got were means that the subscription was closed
|
||||
// return nil for now
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -226,14 +248,24 @@ func (w *Websocket) Unsubscribe(subscription string) error {
|
||||
return w.sendMessage(m)
|
||||
}
|
||||
|
||||
func (w *Websocket) Publish(subscription string, data message.Data) error {
|
||||
func (w *Websocket) Publish(subscription string, data message.Data) (id string, err error) {
|
||||
id = w.nextMsgID()
|
||||
m := &message.Message{
|
||||
Channel: subscription,
|
||||
Data: data,
|
||||
ClientId: w.clientID,
|
||||
Id: w.nextMsgID(),
|
||||
Id: id,
|
||||
}
|
||||
return w.sendMessage(m)
|
||||
if err = w.sendMessage(m); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (w *Websocket) OnPublishResponse(subscription string, onMsg func(message *message.Message)) {
|
||||
w.onPubResponseMu.Lock()
|
||||
w.onPublishResponse[subscription] = onMsg
|
||||
w.onPubResponseMu.Unlock()
|
||||
}
|
||||
|
||||
func (w *Websocket) applyOutExtensions(m *message.Message) {
|
||||
|
Loading…
Reference in New Issue
Block a user