Skip to content

Commit 9427657

Browse files
committed
Add program
1 parent a355f89 commit 9427657

File tree

8 files changed

+193
-0
lines changed

8 files changed

+193
-0
lines changed

cmd/mouse/main.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Server-side part of the Go websocket sample.
2+
//
3+
// Eli Bendersky [http://eli.thegreenplace.net]
4+
// Bobbie Soedirgo [https://soedirgo.dev]
5+
// This code is in the public domain.
6+
package main
7+
8+
import (
9+
"flag"
10+
"fmt"
11+
"log"
12+
"net/http"
13+
"sync"
14+
"time"
15+
16+
"golang.org/x/net/trace"
17+
"golang.org/x/net/websocket"
18+
)
19+
20+
var (
21+
port = flag.Int("port", 4050, "The server port")
22+
cursors sync.Map
23+
)
24+
25+
type Event struct {
26+
// The fields of this struct must be exported so that the json module will be
27+
// able to write into them. Therefore we need field tags to specify the names
28+
// by which these fields go in the JSON representation of events.
29+
X int `json:"x"`
30+
Y int `json:"y"`
31+
}
32+
33+
// handleWebsocketEchoMessage handles the message e arriving on connection ws
34+
// from the client.
35+
func handleWebsocketEchoMessage(ws *websocket.Conn, e Event) error {
36+
// Log the request with net.Trace
37+
tr := trace.New("websocket.Receive", "receive")
38+
defer tr.Finish()
39+
tr.LazyPrintf("Got event %v\n", e)
40+
41+
// Echo the event back as JSON
42+
err := websocket.JSON.Send(ws, e)
43+
if err != nil {
44+
return fmt.Errorf("Can't send: %s", err.Error())
45+
}
46+
cursors.Store(ws, e);
47+
return nil
48+
}
49+
50+
// websocketEchoConnection handles a single websocket echo connection - ws.
51+
func websocketEchoConnection(ws *websocket.Conn) {
52+
log.Printf("Client connected from %s", ws.RemoteAddr())
53+
for {
54+
var event Event
55+
err := websocket.JSON.Receive(ws, &event)
56+
if err != nil {
57+
log.Printf("Receive failed: %s; closing connection...", err.Error())
58+
cursors.Delete(ws);
59+
if err = ws.Close(); err != nil {
60+
log.Println("Error closing connection:", err.Error())
61+
}
62+
break
63+
} else {
64+
if err := handleWebsocketEchoMessage(ws, event); err != nil {
65+
log.Println(err.Error())
66+
break
67+
}
68+
}
69+
}
70+
}
71+
72+
// websocketTimeConnection handles a single websocket time connection - ws.
73+
func websocketTimeConnection(ws *websocket.Conn) {
74+
for range time.Tick(10 * time.Millisecond) {
75+
// Once a second, send a message (as a string) with the current time.
76+
values := struct { Cursors []Event `json:"cursors"` } {}
77+
cursors.Range(func(k, v interface{}) bool {
78+
values.Cursors = append(values.Cursors, v.(Event))
79+
return true
80+
});
81+
websocket.JSON.Send(ws, values)
82+
}
83+
}
84+
85+
func main() {
86+
flag.Parse()
87+
// Set up websocket servers and static file server. In addition, we're using
88+
// net/trace for debugging - it will be available at /debug/requests.
89+
http.Handle("/wsecho", websocket.Handler(websocketEchoConnection))
90+
http.Handle("/wstime", websocket.Handler(websocketTimeConnection))
91+
http.Handle("/", http.FileServer(http.Dir("web/static")))
92+
93+
log.Printf("Server listening on port %d", *port)
94+
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
95+
}

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/soedirgo/mouse
2+
3+
go 1.14
4+
5+
require golang.org/x/net v0.0.0-20200506145744-7e3656a0809f

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
2+
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y=
3+
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
4+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5+
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

web/static/assets/labyrinth.jpg

37.6 KB
Loading

web/static/assets/pointer.png

6.15 KB
Loading

web/static/index.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
3+
<!--
4+
Client-side part of the Go websocket sample.
5+
6+
Simple HTML page with some JS that records mouse movement events and sends them
7+
into a websocket. On receiving messages from this websocket, reports them as
8+
text in a <p> beneath the box.
9+
10+
Eli Bendersky [http://eli.thegreenplace.net]
11+
Bobbie Soedirgo [https://soedirgo.dev]
12+
This code is in the public domain.
13+
-->
14+
<html>
15+
<head>
16+
<link rel="stylesheet" href="style.css" type="text/css" />
17+
</head>
18+
<body>
19+
<canvas id="canvas" width="500" height="479""></canvas>
20+
<p id="output"></p>
21+
</body>
22+
<script src="index.js"></script>
23+
</html>

web/static/index.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// WebSocket objects - created when window is loaded.
2+
let sockEcho = null,
3+
// Websocket server address.
4+
wsServerAddress = "ws://127.0.0.1:4050",
5+
canvas = document.getElementById("canvas"),
6+
ctx = canvas.getContext("2d"),
7+
ptr = new Image(20, 20);
8+
9+
ptr.src = "assets/pointer.png";
10+
11+
window.onload = () => {
12+
// Connect the WebSocket to the server and register callbacks on it.
13+
sockEcho = new WebSocket(wsServerAddress + "/wsecho");
14+
15+
sockEcho.onopen = () => {
16+
console.log("connected");
17+
}
18+
19+
sockEcho.onclose = e => {
20+
console.log("connection closed (" + e.code + ")");
21+
}
22+
23+
sockEcho.onmessage = e => {
24+
var msg = JSON.parse(e.data);
25+
var coordMsg = "Coordinates: (" + msg.x + "," + msg.y + ")";
26+
document.getElementById("output").innerHTML = coordMsg;
27+
}
28+
29+
sockTime = new WebSocket(wsServerAddress + "/wstime");
30+
sockTime.onmessage = e => {
31+
let cursors = JSON.parse(e.data).cursors;
32+
ctx.clearRect(0, 0, canvas.width, canvas.height);
33+
if (cursors) {
34+
cursors.forEach(cursor => {
35+
ctx.drawImage(ptr,
36+
cursor.x - 5,
37+
cursor.y - 2,
38+
20, 20);
39+
});
40+
}
41+
}
42+
};
43+
44+
canvas.onmousemove = e => {
45+
// When a "mouse moved" event is invoked, send it on the socket.
46+
socketSend({x: e.offsetX, y: e.offsetY});
47+
}
48+
49+
canvas.onmouseout = () => {
50+
document.getElementById("output").innerHTML = "";
51+
}
52+
53+
// Send the msg object, encoded with JSON, on the websocket if it's open.
54+
function socketSend(msg) {
55+
if (sockEcho != null && sockEcho.readyState == WebSocket.OPEN) {
56+
sockEcho.send(JSON.stringify(msg));
57+
} else {
58+
console.log("Socket isn't OPEN");
59+
}
60+
}

web/static/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#canvas {
2+
border: 1px solid black;
3+
background-image: url("assets/labyrinth.jpg");
4+
}

0 commit comments

Comments
 (0)