Browse Source

gophers example

master
Ola Holmström 9 years ago
parent
commit
dfa17ad2ae
  1. 88
      README.md
  2. BIN
      examples/gophers/demo.gif
  3. 70
      examples/gophers/index.html
  4. 62
      examples/gophers/main.go

88
README.md

@ -21,19 +21,16 @@ your way so you can write real-time apps. Features include:
go get github.com/olahol/melody go get github.com/olahol/melody
``` ```
## [Example](https://github.com/olahol/melody/tree/master/examples)
## [Example: chat](https://github.com/olahol/melody/tree/master/examples/chat)
[Multi channel chat server](https://github.com/olahol/melody/tree/master/examples/multichat),
error handling left as en exercise for the developer.
[![Chat demo](https://cdn.rawgit.com/olahol/melody/master/examples/chat/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/multichat)
[![Chat](https://cdn.rawgit.com/olahol/melody/master/examples/chat/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/chat)
```go ```go
package main package main
import ( import (
"github.com/olahol/melody"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/olahol/melody"
"net/http" "net/http"
) )
@ -45,24 +42,87 @@ func main() {
http.ServeFile(c.Writer, c.Request, "index.html") http.ServeFile(c.Writer, c.Request, "index.html")
}) })
r.GET("/channel/:name", func(c *gin.Context) {
http.ServeFile(c.Writer, c.Request, "chan.html")
})
r.GET("/channel/:name/ws", func(c *gin.Context) {
r.GET("/ws", func(c *gin.Context) {
m.HandleRequest(c.Writer, c.Request) m.HandleRequest(c.Writer, c.Request)
}) })
m.HandleMessage(func(s *melody.Session, msg []byte) { m.HandleMessage(func(s *melody.Session, msg []byte) {
m.BroadcastFilter(msg, func(q *melody.Session) bool {
return q.Request.URL.Path == s.Request.URL.Path
})
m.Broadcast(msg)
}) })
r.Run(":5000") r.Run(":5000")
} }
``` ```
## [Example: gophers](https://github.com/olahol/melody/tree/master/examples/gophers)
[![Gophers](https://cdn.rawgit.com/olahol/melody/master/examples/gophers/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/gophers)
```go
package main
import (
"github.com/gin-gonic/gin"
"github.com/olahol/melody"
"net/http"
"strconv"
"strings"
"sync"
)
type GopherInfo struct {
ID, X, Y string
}
func main() {
router := gin.Default()
mrouter := melody.New()
gophers := make(map[*melody.Session]*GopherInfo)
lock := new(sync.Mutex)
counter := 0
router.GET("/", func(c *gin.Context) {
http.ServeFile(c.Writer, c.Request, "index.html")
})
router.GET("/ws", func(c *gin.Context) {
mrouter.HandleRequest(c.Writer, c.Request)
})
mrouter.HandleConnect(func(s *melody.Session) {
lock.Lock()
for _, info := range gophers {
s.Write([]byte("set " + info.ID + " " + info.X + " " + info.Y))
}
gophers[s] = &GopherInfo{strconv.Itoa(counter), "0", "0"}
s.Write([]byte("iam " + gophers[s].ID))
counter += 1
lock.Unlock()
})
mrouter.HandleDisconnect(func(s *melody.Session) {
lock.Lock()
mrouter.BroadcastOthers([]byte("dis "+gophers[s].ID), s)
delete(gophers, s)
lock.Unlock()
})
mrouter.HandleMessage(func(s *melody.Session, msg []byte) {
p := strings.Split(string(msg), " ")
lock.Lock()
info := gophers[s]
if len(p) == 2 {
info.X = p[0]
info.Y = p[1]
mrouter.BroadcastOthers([]byte("set "+info.ID+" "+info.X+" "+info.Y), s)
}
lock.Unlock()
})
router.Run(":5000")
}
```
### [More examples](https://github.com/olahol/melody/tree/master/examples) ### [More examples](https://github.com/olahol/melody/tree/master/examples)
## [Documentation](https://godoc.org/github.com/olahol/melody) ## [Documentation](https://godoc.org/github.com/olahol/melody)

BIN
examples/gophers/demo.gif

After

Width: 1663  |  Height: 723  |  Size: 596 KiB

70
examples/gophers/index.html

@ -0,0 +1,70 @@
<html>
<head>
<meta charset="utf-8">
<title>goofy gophers</title>
<style>
body {
cursor: none;
overflow: hidden;
}
.gopher {
background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Go_gopher_mascot_bw.png/768px-Go_gopher_mascot_bw.png');
width: 95px;
height: 95px;
background-size: cover;
position: absolute;
left: 0px;
top: 0px;
}
</style>
</head>
<body>
<script>
var url = "ws://" + window.location.host + "/ws";
var ws = new WebSocket(url);
var myid = -1;
ws.onmessage = function (msg) {
var cmds = {"iam": iam, "set": set, "dis": dis};
if (msg.data) {
var parts = msg.data.split(" ")
var cmd = cmds[parts[0]];
if (cmd) {
cmd.apply(null, parts.slice(1));
}
}
};
function iam(id) {
myid = id;
}
function set(id, x, y) {
var node = document.getElementById("gopher-" + id);
if (!node) {
node = document.createElement("div");
document.body.appendChild(node);
node.className = "gopher";
node.style.zIndex = id + 1;
node.id = "gopher-" + id;
}
node.style.left = x + "px";
node.style.top = y + "px";
}
function dis(id) {
var node = document.getElementById("gopher-" + id);
if (node) {
document.body.removeChild(node);
}
}
window.onmousemove = function (e) {
if (myid > -1) {
set(myid, e.pageX, e.pageY);
ws.send([e.pageX, e.pageY].join(" "));
}
}
</script>
</body>
</html>

62
examples/gophers/main.go

@ -0,0 +1,62 @@
package main
import (
"github.com/gin-gonic/gin"
"github.com/olahol/melody"
"net/http"
"strconv"
"strings"
"sync"
)
type GopherInfo struct {
ID, X, Y string
}
func main() {
router := gin.Default()
mrouter := melody.New()
gophers := make(map[*melody.Session]*GopherInfo)
lock := new(sync.Mutex)
counter := 0
router.GET("/", func(c *gin.Context) {
http.ServeFile(c.Writer, c.Request, "index.html")
})
router.GET("/ws", func(c *gin.Context) {
mrouter.HandleRequest(c.Writer, c.Request)
})
mrouter.HandleConnect(func(s *melody.Session) {
lock.Lock()
for _, info := range gophers {
s.Write([]byte("set " + info.ID + " " + info.X + " " + info.Y))
}
gophers[s] = &GopherInfo{strconv.Itoa(counter), "0", "0"}
s.Write([]byte("iam " + gophers[s].ID))
counter += 1
lock.Unlock()
})
mrouter.HandleDisconnect(func(s *melody.Session) {
lock.Lock()
mrouter.BroadcastOthers([]byte("dis "+gophers[s].ID), s)
delete(gophers, s)
lock.Unlock()
})
mrouter.HandleMessage(func(s *melody.Session, msg []byte) {
p := strings.Split(string(msg), " ")
lock.Lock()
info := gophers[s]
if len(p) == 2 {
info.X = p[0]
info.Y = p[1]
mrouter.BroadcastOthers([]byte("set "+info.ID+" "+info.X+" "+info.Y), s)
}
lock.Unlock()
})
router.Run(":5000")
}
Loading…
Cancel
Save