mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
ed45c77be5
Former-commit-id: ed635ee95de7160cde11eaabc0c1dcb0e460a620
174 lines
3.6 KiB
Go
174 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"sync/atomic"
|
|
|
|
"github.com/kataras/iris/v12"
|
|
|
|
"github.com/kataras/iris/v12/websocket"
|
|
)
|
|
|
|
var events = websocket.Namespaces{
|
|
"default": websocket.Events{
|
|
websocket.OnRoomJoined: onRoomJoined,
|
|
websocket.OnRoomLeft: onRoomLeft,
|
|
},
|
|
}
|
|
|
|
func main() {
|
|
// init the web application instance
|
|
// app := iris.New()
|
|
app := iris.Default()
|
|
|
|
// load templates
|
|
app.RegisterView(iris.HTML("./templates", ".html").Reload(true))
|
|
// setup the websocket server
|
|
ws := websocket.New(websocket.DefaultGorillaUpgrader, events)
|
|
|
|
app.Get("/my_endpoint", websocket.Handler(ws))
|
|
|
|
// register static assets request path and system directory
|
|
app.HandleDir("/js", "./static/assets/js")
|
|
|
|
h := func(ctx iris.Context) {
|
|
ctx.ViewData("", page{PageID: "index page"})
|
|
ctx.View("index.html")
|
|
}
|
|
|
|
h2 := func(ctx iris.Context) {
|
|
ctx.ViewData("", page{PageID: "other page"})
|
|
ctx.View("other.html")
|
|
}
|
|
|
|
// Open some browser tabs/or windows
|
|
// and navigate to
|
|
// http://localhost:8080/ and http://localhost:8080/other multiple times.
|
|
// Each page has its own online-visitors counter.
|
|
app.Get("/", h)
|
|
app.Get("/other", h2)
|
|
app.Listen(":8080")
|
|
}
|
|
|
|
type page struct {
|
|
PageID string
|
|
}
|
|
|
|
type pageView struct {
|
|
source string
|
|
count uint64
|
|
}
|
|
|
|
func (v *pageView) increment() {
|
|
atomic.AddUint64(&v.count, 1)
|
|
}
|
|
|
|
func (v *pageView) decrement() {
|
|
atomic.AddUint64(&v.count, ^uint64(0))
|
|
}
|
|
|
|
func (v *pageView) getCount() uint64 {
|
|
return atomic.LoadUint64(&v.count)
|
|
}
|
|
|
|
type (
|
|
pageViews []pageView
|
|
)
|
|
|
|
func (v *pageViews) Add(source string) {
|
|
args := *v
|
|
n := len(args)
|
|
for i := 0; i < n; i++ {
|
|
kv := &args[i]
|
|
if kv.source == source {
|
|
kv.increment()
|
|
return
|
|
}
|
|
}
|
|
|
|
c := cap(args)
|
|
if c > n {
|
|
args = args[:n+1]
|
|
kv := &args[n]
|
|
kv.source = source
|
|
kv.count = 1
|
|
*v = args
|
|
return
|
|
}
|
|
|
|
kv := pageView{}
|
|
kv.source = source
|
|
kv.count = 1
|
|
*v = append(args, kv)
|
|
}
|
|
|
|
func (v *pageViews) Get(source string) *pageView {
|
|
args := *v
|
|
n := len(args)
|
|
for i := 0; i < n; i++ {
|
|
kv := &args[i]
|
|
if kv.source == source {
|
|
return kv
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (v *pageViews) Reset() {
|
|
*v = (*v)[:0]
|
|
}
|
|
|
|
var v pageViews
|
|
|
|
func viewsCountBytes(viewsCount uint64) []byte {
|
|
// * there are other methods to convert uint64 to []byte
|
|
return []byte(fmt.Sprintf("%d", viewsCount))
|
|
}
|
|
|
|
func onRoomJoined(ns *websocket.NSConn, msg websocket.Message) error {
|
|
// the roomName here is the source.
|
|
pageSource := string(msg.Room)
|
|
|
|
v.Add(pageSource)
|
|
|
|
viewsCount := v.Get(pageSource).getCount()
|
|
if viewsCount == 0 {
|
|
viewsCount++ // count should be always > 0 here
|
|
}
|
|
|
|
// fire the "onNewVisit" client event
|
|
// on each connection joined to this room (source page)
|
|
// and notify of the new visit,
|
|
// including this connection (see nil on first input arg).
|
|
ns.Conn.Server().Broadcast(nil, websocket.Message{
|
|
Namespace: msg.Namespace,
|
|
Room: pageSource,
|
|
Event: "onNewVisit", // fire the "onNewVisit" client event.
|
|
Body: viewsCountBytes(viewsCount),
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
func onRoomLeft(ns *websocket.NSConn, msg websocket.Message) error {
|
|
// the roomName here is the source.
|
|
pageV := v.Get(msg.Room)
|
|
if pageV == nil {
|
|
return nil // for any case that this room is not a pageView source
|
|
}
|
|
// decrement -1 the specific counter for this page source.
|
|
pageV.decrement()
|
|
|
|
// fire the "onNewVisit" client event
|
|
// on each connection joined to this room (source page)
|
|
// and notify of the new, decremented by one, visits count.
|
|
ns.Conn.Server().Broadcast(nil, websocket.Message{
|
|
Namespace: msg.Namespace,
|
|
Room: msg.Room,
|
|
Event: "onNewVisit",
|
|
Body: viewsCountBytes(pageV.getCount()),
|
|
})
|
|
|
|
return nil
|
|
}
|