6
0
mirror of https://git.mills.io/prologic/msgbus.git synced 2024-07-03 00:34:16 +00:00
prologic-msgbus/server.go

127 lines
2.6 KiB
Go
Raw Normal View History

2017-06-03 19:15:20 +00:00
package msgbus
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"golang.org/x/net/websocket"
"github.com/julienschmidt/httprouter"
)
2017-06-08 04:53:21 +00:00
// Server ...
type Server struct {
bind string
bus *MessageBus
router *httprouter.Router
}
2017-06-03 19:15:20 +00:00
// IndexHandler ...
2017-06-08 04:53:21 +00:00
func (s *Server) IndexHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprint(w, "Welcome!\n")
}
2017-06-03 19:15:20 +00:00
}
// PushHandler ...
2017-06-08 04:53:21 +00:00
func (s *Server) PushHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
topic := p.ByName("topic")
websocket.Handler(s.PushWebSocketHandler(topic)).ServeHTTP(w, r)
}
2017-06-03 19:15:20 +00:00
}
// PullHandler ...
2017-06-08 04:53:21 +00:00
func (s *Server) PullHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
topic := p.ByName("topic")
message, ok := s.bus.Get(topic)
if !ok {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
2017-06-03 19:15:20 +00:00
2017-06-08 04:53:21 +00:00
out, err := json.Marshal(message)
if err != nil {
http.Error(w, "Internal Error", http.StatusInternalServerError)
return
}
2017-06-03 19:15:20 +00:00
2017-06-08 04:53:21 +00:00
w.Write(out)
}
2017-06-03 19:15:20 +00:00
}
// PutHandler ...
2017-06-08 04:53:21 +00:00
func (s *Server) PutHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
topic := p.ByName("topic")
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Internal Error", http.StatusInternalServerError)
return
}
2017-06-03 19:15:20 +00:00
2017-06-08 04:53:21 +00:00
s.bus.Put(topic, s.bus.NewMessage(body))
}
2017-06-03 19:15:20 +00:00
}
// PushWebSocketHandler ...
2017-06-08 04:53:21 +00:00
func (s *Server) PushWebSocketHandler(topic string) websocket.Handler {
2017-06-03 19:15:20 +00:00
return func(conn *websocket.Conn) {
id := conn.Request().RemoteAddr
2017-06-08 04:53:21 +00:00
ch := s.bus.Subscribe(id, topic)
2017-06-03 19:15:20 +00:00
defer func() {
2017-06-08 04:53:21 +00:00
s.bus.Unsubscribe(id, topic)
2017-06-03 19:15:20 +00:00
}()
var (
err error
2017-06-08 04:53:21 +00:00
ack Ack
2017-06-03 19:15:20 +00:00
)
for {
msg := <-ch
err = websocket.JSON.Send(conn, msg)
if err != nil {
log.Printf("Error sending msg to %s", id)
continue
}
err = websocket.JSON.Receive(conn, &ack)
if err != nil {
log.Printf("Error receiving ack from %s", id)
continue
}
log.Printf("message %v acked %v by %s", msg, ack, id)
}
}
}
2017-06-08 04:53:21 +00:00
func (s *Server) ListenAndServe() {
log.Fatal(http.ListenAndServe(s.bind, s.router))
2017-06-03 19:15:20 +00:00
}
2017-06-08 04:53:21 +00:00
func (s *Server) initRoutes() {
s.router.GET("/", s.IndexHandler())
s.router.GET("/push/:topic", s.PushHandler())
s.router.GET("/pull/:topic", s.PullHandler())
s.router.PUT("/:topic", s.PutHandler())
2017-06-03 19:15:20 +00:00
}
2017-06-08 04:53:21 +00:00
// NewServer ...
func NewServer(bind string) *Server {
server := &Server{
bind: bind,
bus: NewMessageBus(),
router: httprouter.New(),
}
2017-06-03 19:15:20 +00:00
2017-06-08 04:53:21 +00:00
server.initRoutes()
return server
2017-06-03 19:15:20 +00:00
}