github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2012/insidepresent.slide (about) 1 Inside the "present" tool 2 3 Andrew Gerrand 4 Google 5 @enneff 6 adg@golang.org 7 http://golang.org 8 9 10 * The Playground API 11 12 The API used by the Playground (and the Tour) is a simple HTTP POST request 13 that returns a JSON-encoded response. 14 15 Request: 16 17 POST /compile HTTP/1.1 18 Host:play.golang.org 19 Content-Length:113 20 Content-Type:application/x-www-form-urlencoded; charset=UTF-8 21 22 body=package+main%0A%0Aimport+%22fmt%22%0A%0Afunc+main()+%7B%0A%09fmt.Println(%22Hello%2C+playground%22)%0A%7D%0A 23 24 Response body: 25 26 {"compile_errors":"","output":"Hello, playground\n"} 27 28 29 * Playground drawbacks 30 31 The compile service has no concept of time. (Necessary to limit resource use.) 32 33 The API reflects this; output is sent in one blob, not streamed. 34 35 Even when running locally, the API is bad for demonstrating code that uses time. 36 37 Rob needed to use time in his _Go_Concurrency_Patterns_ talk. 38 39 40 * Enter WebSockets 41 42 WebSockets are a bi-directional communication channel between a JavaScript program running in a web browser and a web server. They are part of HTML 5. 43 44 The `websocket` package in Go's `go.net` sub-repository provides a WebSocket client and server. 45 46 I thought I could use WebSockets to stream program output to a running 47 presentation. 48 49 And thus the `present` tool was born. 50 51 52 * Hello, WebSocket 53 54 .code insidepresent/websocket.js 55 .play insidepresent/websocket.go 56 57 58 * Messages 59 60 The client (browser) and server (present) communicate with JSON-encoded messages. 61 62 .code insidepresent/socket.go /Message is/,/^}/ 63 64 Go's `encoding/json` format can convert these `Message` values to and from JSON. 65 66 Go: 67 68 Message{Id: "0", Kind: "run", Body: `package main; func main() { print("hello"); }`} 69 70 JSON: 71 72 {"Id":"0","Kind":"run","Body":"package main; func main() { print(\"hello\"); }"} 73 74 75 * On the wire 76 77 .play insidepresent/hello.go 78 79 .html insidepresent/wire.html 80 81 82 * Implementation 83 84 * socketHandler (1/3) 85 86 First, register the handler with the `net/http` package: 87 88 http.Handle("/socket", websocket.Handler(socketHandler)) 89 90 Implementation: 91 92 .code insidepresent/socket.go /func socketHandler/,/errc/ 93 94 * socketHandler (2/3) 95 96 .code insidepresent/socket.go /Decode messages/,/END/ 97 98 * socketHandler (3/3) 99 100 .code insidepresent/socket-simple.go /Start and kill/,/^}/ 101 102 103 * Process 104 105 .code insidepresent/socket.go /Process represents/,/^}/ 106 107 * StartProcess 108 109 .code insidepresent/socket.go /StartProcess builds/,/^}/ 110 111 * Process.start (1/2) 112 113 .code insidepresent/socket.go /start builds/,/END/ 114 115 * Process.start (2/2) 116 117 .code insidepresent/socket.go /build x\.go/,/^}/ 118 119 * Process.cmd 120 121 .code insidepresent/socket.go /cmd builds/,/^}/ 122 .code insidepresent/socket.go /messageWriter is/,/END/ 123 124 * Process.wait and Process.end 125 126 .code insidepresent/socket.go /wait waits/,/^}/ 127 .code insidepresent/socket.go /end sends/,/^}/ 128 129 * Process.Kill 130 131 .code insidepresent/socket.go /Kill stops/,/^}/ 132 133 134 * One more thing 135 136 * Limiting output (1/2) 137 138 .code insidepresent/socket.go /switch m\.Kind/,/^ }/ 139 140 * Limiting output (2/2) 141 142 .code insidepresent/socket.go /limiter returns/,/^}/ 143 144