mirror of https://github.com/nealey/microchat.git
126 lines
2.0 KiB
Go
126 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
type Message struct {
|
|
When int64
|
|
Who string
|
|
Text string
|
|
}
|
|
|
|
type Forum struct {
|
|
Name string
|
|
Log []Message
|
|
SendQ chan Message
|
|
LogQ chan []Message
|
|
}
|
|
|
|
var foraByName map[string]*Forum
|
|
|
|
func (f *Forum) HandleSends() {
|
|
for m := range f.SendQ {
|
|
f.Log = append(f.Log, m)
|
|
}
|
|
}
|
|
|
|
func (f *Forum) HandleReads() {
|
|
for {
|
|
f.LogQ <- f.Log
|
|
}
|
|
}
|
|
|
|
func newForum(name string) *Forum {
|
|
f := &Forum{
|
|
Name: name,
|
|
SendQ: make(chan Message, 10),
|
|
LogQ: make(chan []Message, 10),
|
|
}
|
|
go f.HandleSends()
|
|
go f.HandleReads()
|
|
|
|
foraByName[name] = f
|
|
return f
|
|
}
|
|
|
|
func sayHandler(w http.ResponseWriter, r *http.Request) {
|
|
message := Message{
|
|
When: time.Now().Unix(),
|
|
Who: r.FormValue("who"),
|
|
Text: r.FormValue("text"),
|
|
}
|
|
forumName := r.FormValue("forum")
|
|
f, ok := foraByName[forumName]
|
|
if !ok {
|
|
f = newForum(forumName)
|
|
}
|
|
f.SendQ <- message
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func readHandler(w http.ResponseWriter, r *http.Request) {
|
|
r.ParseForm()
|
|
|
|
forumName := r.FormValue("forum")
|
|
entriesStr := r.FormValue("entries")
|
|
|
|
if entriesStr == "" {
|
|
entriesStr = "0"
|
|
}
|
|
entries, err := strconv.Atoi(entriesStr)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if entries <= 0 {
|
|
entries = 20
|
|
} else if entries > 500 {
|
|
entries = 500
|
|
}
|
|
|
|
f, ok := foraByName[forumName]
|
|
if !ok {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
log := <-f.LogQ
|
|
|
|
pos := len(log) - entries
|
|
if pos < 0 {
|
|
pos = 0
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
e := json.NewEncoder(w)
|
|
e.Encode(f.Log[pos:])
|
|
}
|
|
|
|
func main() {
|
|
http.HandleFunc("/say", sayHandler)
|
|
http.HandleFunc("/read", readHandler)
|
|
http.Handle("/", http.FileServer(http.Dir("static/")))
|
|
|
|
foraByName = map[string]*Forum{}
|
|
f := newForum("")
|
|
f.Log = []Message{
|
|
{
|
|
When: time.Now().Unix(),
|
|
Who: "(system)",
|
|
Text: "Welcome to μChat",
|
|
},
|
|
}
|
|
|
|
bind := ":8080"
|
|
log.Printf("Listening on %s", bind)
|
|
log.Fatal(http.ListenAndServe(bind, nil))
|
|
}
|