add dispatcher
simplify transport implementation support wildcard subscriptions
This commit is contained in:
@ -1,73 +1,67 @@
|
||||
package subscription
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/thesyncim/faye/message"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var ErrInvalidChannelName = errors.New("invalid channel channel")
|
||||
|
||||
type Unsubscriber func(subscription *Subscription) error
|
||||
|
||||
type Publisher func(msg message.Data) (string, error)
|
||||
|
||||
type Subscription struct {
|
||||
id string //request Subscription ID
|
||||
channel string
|
||||
ok chan error //used by
|
||||
unsub Unsubscriber
|
||||
pub Publisher
|
||||
msgCh chan *message.Message
|
||||
}
|
||||
|
||||
func NewSubscription(id string, chanel string, unsub Unsubscriber, pub Publisher, msgCh chan *message.Message, ok chan error) *Subscription {
|
||||
//todo error
|
||||
func NewSubscription(chanel string, unsub Unsubscriber, msgCh chan *message.Message) (*Subscription, error) {
|
||||
if !IsValidSubscriptionName(chanel) {
|
||||
return nil, ErrInvalidChannelName
|
||||
}
|
||||
return &Subscription{
|
||||
pub: pub,
|
||||
ok: ok,
|
||||
id: id,
|
||||
channel: chanel,
|
||||
unsub: unsub,
|
||||
msgCh: msgCh,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Subscription) OnMessage(onMessage func(msg message.Data)) error {
|
||||
func (s *Subscription) OnMessage(onMessage func(channel string, msg message.Data)) error {
|
||||
var inMsg *message.Message
|
||||
for inMsg = range s.msgCh {
|
||||
if inMsg.GetError() != nil {
|
||||
return inMsg.GetError()
|
||||
}
|
||||
onMessage(inMsg.Data)
|
||||
onMessage(inMsg.Channel, inMsg.Data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Subscription) ID() string {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func (s *Subscription) MsgChannel() chan *message.Message {
|
||||
return s.msgCh
|
||||
}
|
||||
|
||||
func (s *Subscription) Channel() string {
|
||||
func (s *Subscription) Name() string {
|
||||
return s.channel
|
||||
}
|
||||
|
||||
//todo remove
|
||||
func (s *Subscription) SubscriptionResult() chan error {
|
||||
return s.ok
|
||||
}
|
||||
|
||||
//Unsubscribe ...
|
||||
func (s *Subscription) Unsubscribe() error {
|
||||
return s.unsub(s)
|
||||
}
|
||||
|
||||
func (s *Subscription) Publish(msg message.Data) (string, error) {
|
||||
return s.pub(msg)
|
||||
}
|
||||
|
||||
//validChannelName channel specifies is the channel is in the format /foo/432/bar
|
||||
var validChannelName = regexp.MustCompile(`^\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*$`)
|
||||
|
||||
var validChannelPattern = regexp.MustCompile(`^(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*\/\*{1,2}$`)
|
||||
|
||||
func IsValidChannel(channel string) bool {
|
||||
func IsValidSubscriptionName(channel string) bool {
|
||||
return validChannelName.MatchString(channel) || validChannelPattern.MatchString(channel)
|
||||
}
|
||||
|
||||
//isValidPublishName
|
||||
func IsValidPublishName(channel string) bool {
|
||||
return validChannelName.MatchString(channel)
|
||||
}
|
||||
|
@ -1,20 +1,23 @@
|
||||
package subscription
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
/*
|
||||
assertEqual( ["/**", "/foo", "/*"],
|
||||
Channel.expand("/foo") )
|
||||
channel.expand("/foo") )
|
||||
|
||||
assertEqual( ["/**", "/foo/bar", "/foo/*", "/foo/**"],
|
||||
Channel.expand("/foo/bar") )
|
||||
channel.expand("/foo/bar") )
|
||||
|
||||
assertEqual( ["/**", "/foo/bar/qux", "/foo/bar/*", "/foo/**", "/foo/bar/**"],
|
||||
*/
|
||||
func TestIsValidChannel(t *testing.T) {
|
||||
func TestIsValidSubscriptionName(t *testing.T) {
|
||||
type args struct {
|
||||
channel string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
@ -62,11 +65,18 @@ func TestIsValidChannel(t *testing.T) {
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "asterisk before slash",
|
||||
args: args{
|
||||
channel: "/foo*",
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := IsValidChannel(tt.args.channel); got != tt.want {
|
||||
t.Errorf("IsValidChannel() = %v, want %v", got, tt.want)
|
||||
if got := IsValidSubscriptionName(tt.args.channel); got != tt.want {
|
||||
t.Errorf("isValidChannelName() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user