@@ -18,11 +18,6 @@ type registeredClient struct {
18
18
topics map [string ]bool
19
19
}
20
20
21
- func New () * Stream {
22
- s := & Stream {}
23
- return s
24
- }
25
-
26
21
// Register adds a client to the stream to receive all broadcast
27
22
// messages. Has no effect if the client is already registered.
28
23
func (s * Stream ) Register (c * Client ) {
@@ -95,12 +90,57 @@ func (s *Stream) CloseTopic(topic string) {
95
90
96
91
}
97
92
93
+ // ServeHTTP takes a client connection, registers it for broadcasts,
94
+ // then blocks so long as the connection is alive.
98
95
func (s * Stream ) ServeHTTP (w http.ResponseWriter , r * http.Request ) {
99
96
97
+ // ensure the client accepts an event-stream
98
+ if ! checkRequest (r ) {
99
+ http .Error (w , "This is an EventStream endpoint" , http .StatusNotAcceptable )
100
+ return
101
+ }
102
+
103
+ // create the client
104
+ c := NewClient (w )
105
+ if c == nil {
106
+ http .Error (w , "EventStream not supported for this connection" , http .StatusInternalServerError )
107
+ return
108
+ }
109
+
110
+ // wait for the client to exit or be shutdown
111
+ s .Register (c )
112
+ c .Wait ()
100
113
}
101
114
102
- func (s * Stream ) TopicHandler (topic string ) http.HandlerFunc {
115
+ // TopicHandler returns an HTTP handler that will register a client for broadcasts
116
+ // and for any topics, and then block so long as they are connected
117
+ func (s * Stream ) TopicHandler (topics []string ) http.HandlerFunc {
103
118
119
+ return func (w http.ResponseWriter , r * http.Request ) {
120
+ // ensure the client accepts an event-stream
121
+ if ! checkRequest (r ) {
122
+ http .Error (w , "This is an EventStream endpoint" , http .StatusNotAcceptable )
123
+ return
124
+ }
125
+
126
+ // create the client
127
+ c := NewClient (w )
128
+ if c == nil {
129
+ http .Error (w , "EventStream not supported for this connection" , http .StatusInternalServerError )
130
+ return
131
+ }
132
+
133
+ // broadcasts
134
+ s .Register (c )
135
+
136
+ // topics
137
+ for _ , topic := range topics {
138
+ s .Subscribe (topic , c )
139
+ }
140
+
141
+ // wait for the client to exit or be shutdown
142
+ c .Wait ()
143
+ }
104
144
}
105
145
106
146
// Register a function to be called when a client connects to this stream's
@@ -109,8 +149,9 @@ func (s *Stream) ClientConnectHook(fn func(*http.Request, *Client)) {
109
149
s .clientConnectHook = fn
110
150
}
111
151
112
- func (s * Stream ) sendAll (ev * Event ) {
113
-
152
+ // Checks that a client expects an event-stream
153
+ func checkRequest (r * http.Request ) bool {
154
+ return r .Header .Get ("Accept" ) == "text/event-stream"
114
155
}
115
156
116
157
func (s * Stream ) getClient (c * Client ) * registeredClient {
@@ -130,12 +171,15 @@ func (s *Stream) getClient(c *Client) *registeredClient {
130
171
}
131
172
132
173
func (s * Stream ) addClient (c * Client ) * registeredClient {
133
- s .listLock .Lock ()
134
174
135
- s . clients . PushBack ( & registeredClient {
175
+ cli := & registeredClient {
136
176
c : c ,
137
177
topics : make (map [string ]bool ),
138
- })
178
+ }
139
179
180
+ s .listLock .Lock ()
181
+ s .clients .PushBack (cli )
140
182
s .listLock .Unlock ()
183
+
184
+ return cli
141
185
}
0 commit comments