2022-01-02 08:44:18 -03:00
|
|
|
package nostr
|
2021-02-20 17:44:05 -03:00
|
|
|
|
2022-11-26 09:25:51 -03:00
|
|
|
import (
|
2023-01-01 20:22:40 -03:00
|
|
|
"context"
|
2022-11-26 09:25:51 -03:00
|
|
|
"sync"
|
|
|
|
)
|
2022-11-16 10:07:15 -03:00
|
|
|
|
2021-02-20 17:44:05 -03:00
|
|
|
type Subscription struct {
|
2022-11-26 09:25:51 -03:00
|
|
|
id string
|
|
|
|
conn *Connection
|
|
|
|
mutex sync.Mutex
|
2021-02-20 17:44:05 -03:00
|
|
|
|
2022-11-26 09:25:51 -03:00
|
|
|
Relay *Relay
|
2022-11-19 14:00:29 -03:00
|
|
|
Filters Filters
|
2023-01-26 09:04:27 -03:00
|
|
|
Events chan *Event
|
2022-11-12 21:49:57 -03:00
|
|
|
EndOfStoredEvents chan struct{}
|
2022-02-07 11:33:45 -03:00
|
|
|
|
2022-11-16 10:07:15 -03:00
|
|
|
stopped bool
|
|
|
|
emitEose sync.Once
|
2021-02-20 17:59:47 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
type EventMessage struct {
|
2022-01-02 08:44:18 -03:00
|
|
|
Event Event
|
2021-02-20 17:59:47 -03:00
|
|
|
Relay string
|
2021-02-20 17:44:05 -03:00
|
|
|
}
|
|
|
|
|
2023-01-16 06:27:11 -05:00
|
|
|
// Unsub closes the subscription, sending "CLOSE" to relay as in NIP-01.
|
|
|
|
// Unsub() also closes the channel sub.Events.
|
2022-11-26 09:25:51 -03:00
|
|
|
func (sub *Subscription) Unsub() {
|
|
|
|
sub.mutex.Lock()
|
|
|
|
defer sub.mutex.Unlock()
|
2021-02-20 17:44:05 -03:00
|
|
|
|
2022-11-26 09:25:51 -03:00
|
|
|
sub.conn.WriteJSON([]interface{}{"CLOSE", sub.id})
|
|
|
|
if sub.stopped == false && sub.Events != nil {
|
2022-11-06 21:15:42 -03:00
|
|
|
close(sub.Events)
|
2021-02-20 17:44:05 -03:00
|
|
|
}
|
2022-11-26 09:25:51 -03:00
|
|
|
sub.stopped = true
|
2021-02-20 17:44:05 -03:00
|
|
|
}
|
|
|
|
|
2023-01-16 06:27:11 -05:00
|
|
|
// Sub sets sub.Filters and then calls sub.Fire(ctx).
|
2023-01-01 20:22:40 -03:00
|
|
|
func (sub *Subscription) Sub(ctx context.Context, filters Filters) {
|
2022-11-19 14:00:29 -03:00
|
|
|
sub.Filters = filters
|
2023-01-01 20:22:40 -03:00
|
|
|
sub.Fire(ctx)
|
2022-11-19 14:00:29 -03:00
|
|
|
}
|
2021-12-16 20:47:53 -03:00
|
|
|
|
2023-01-16 06:27:11 -05:00
|
|
|
// Fire sends the "REQ" command to the relay.
|
|
|
|
// When ctx is cancelled, sub.Unsub() is called, closing the subscription.
|
2023-01-01 20:22:40 -03:00
|
|
|
func (sub *Subscription) Fire(ctx context.Context) {
|
2022-11-06 21:15:42 -03:00
|
|
|
message := []interface{}{"REQ", sub.id}
|
2022-11-19 14:00:29 -03:00
|
|
|
for _, filter := range sub.Filters {
|
2021-12-16 20:47:53 -03:00
|
|
|
message = append(message, filter)
|
|
|
|
}
|
|
|
|
|
2022-11-06 21:15:42 -03:00
|
|
|
sub.conn.WriteJSON(message)
|
2023-01-01 20:22:40 -03:00
|
|
|
|
|
|
|
// the subscription ends once the context is canceled
|
|
|
|
go func() {
|
|
|
|
<-ctx.Done()
|
|
|
|
sub.Unsub()
|
|
|
|
}()
|
2021-02-20 17:44:05 -03:00
|
|
|
}
|