mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-03-17 13:21:50 +01:00
Added in gRPC-web support and boilerplate code for a client
This commit is contained in:
parent
690397468a
commit
0ac4c706e5
@ -40,5 +40,5 @@ func main() {
|
||||
|
||||
service.InitLed(false) //Set LED to manual trigger
|
||||
service.InitDefaultLEDSettings()
|
||||
service.StartRpcServer("", "50051") //start gRPC service
|
||||
service.StartRpcServerAndWeb("0.0.0.0", "50051") //start gRPC service
|
||||
}
|
||||
|
@ -1,2 +1,7 @@
|
||||
#!/bin/bash
|
||||
# golang version
|
||||
protoc -I proto/ proto/grpc.proto --go_out=plugins=grpc:proto
|
||||
|
||||
# gopherjs version
|
||||
protoc -I proto/ proto/grpc.proto --gopherjs_out=plugins=grpc:proto/gopherjs
|
||||
|
||||
|
@ -144,7 +144,6 @@ func cobraUsbSet(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
//ToDo: Implement detailed UMS settings
|
||||
if (cmd.Flags().Lookup("ums").Changed) {
|
||||
if tmpUseUMS == 0 {
|
||||
fmt.Println("Disabeling USB Mass Storage")
|
||||
@ -171,9 +170,9 @@ func cobraUsbSet(cmd *cobra.Command, args []string) {
|
||||
|
||||
|
||||
//Try to set the change config
|
||||
//ToDo: Adopt parsing of Error Message to other gRPC calls
|
||||
err = ClientSetGadgetSettings(StrRemoteHost, StrRemotePort, *gs)
|
||||
if err != nil {
|
||||
//ToDo: Adopt parsing of Error Message to other gRPC calls
|
||||
log.Printf("Error setting new gadget settings: %v\n", status.Convert(err).Message())
|
||||
return
|
||||
}
|
||||
|
@ -6,3 +6,6 @@ export PATH=$PATH:/usr/local/go/bin # put into ~/.profile
|
||||
echo export PATH=$PATH:/usr/local/go/bin >> ~/.profile
|
||||
sudo bash -c 'echo export PATH=\$PATH:/usr/local/go/bin >> ~/.profile'
|
||||
go get google.golang.org/grpc
|
||||
|
||||
go get -u github.com/improbable-eng/grpc-web/go/grpcweb
|
||||
go get -u github.com/gorilla/websocket
|
1515
proto/gopherjs/grpc.pb.gopherjs.go
Normal file
1515
proto/gopherjs/grpc.pb.gopherjs.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,12 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||
|
||||
"net/http"
|
||||
"strings"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
type server struct {}
|
||||
@ -108,3 +114,101 @@ func StartRpcServer(host string, port string) {
|
||||
log.Fatalf("Failed to serve: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func folderReader(fn http.Handler) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
if strings.HasSuffix(req.URL.Path, "/") {
|
||||
// Use contents of index.html for directory, if present.
|
||||
req.URL.Path = path.Join(req.URL.Path, "index.html")
|
||||
}
|
||||
fn.ServeHTTP(w, req)
|
||||
}
|
||||
}
|
||||
|
||||
func StartRpcWebServer(host string, port string) {
|
||||
//Create gRPC Server
|
||||
s := grpc.NewServer()
|
||||
pb.RegisterP4WNP1Server(s, &server{})
|
||||
|
||||
//grpc_web_srv := grpcweb.WrapServer(s, grpcweb.WithWebsockets(true)) //Wrap server to improbable grpc-web with websockets
|
||||
grpc_web_srv := grpcweb.WrapServer(s) //Wrap server to improbable grpc-web with websockets
|
||||
|
||||
/*
|
||||
http_handler := func(resp http.ResponseWriter, req *http.Request) {
|
||||
if req.ProtoMajor == 2 && strings.Contains(req.Header.Get("Content-Type"), "application/grpc") ||
|
||||
websocket.IsWebSocketUpgrade(req) {
|
||||
grpc_web_srv.ServeHTTP(resp, req)
|
||||
} else {
|
||||
//No gRPC request
|
||||
folderReader(http.FileServer(http.Dir("/home/pi/P4wnP1_go"))).ServeHTTP(resp, req)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
http_handler := func(resp http.ResponseWriter, req *http.Request) {
|
||||
grpc_web_srv.ServeHTTP(resp, req)
|
||||
}
|
||||
|
||||
listen_address := host + ":" + port
|
||||
http_srv := &http.Server{
|
||||
Addr: listen_address,
|
||||
Handler: http.HandlerFunc(http_handler),
|
||||
//ReadHeaderTimeout: 5*time.Second,
|
||||
//IdleTimeout: 120*time.Second,
|
||||
}
|
||||
|
||||
|
||||
//Open TCP listener
|
||||
log.Printf("P4wnP1 gRPC-web server listening on " + listen_address)
|
||||
log.Fatal(http_srv.ListenAndServe())
|
||||
}
|
||||
|
||||
func StartRpcServerAndWeb(host string, port string) {
|
||||
listen_address := host + ":" + port
|
||||
webserver_path := "/home/pi/P4wnP1_go/www" //ToDo: Change this to an absolute path which could be used after installation
|
||||
|
||||
//Create gRPC Server
|
||||
s := grpc.NewServer()
|
||||
pb.RegisterP4WNP1Server(s, &server{})
|
||||
|
||||
//Wrap the server into a gRPC-web server
|
||||
grpc_web_srv := grpcweb.WrapServer(s) //Wrap server to improbable grpc-web with websockets
|
||||
//define a handler for a HTTP web server using the gRPC-web proxy
|
||||
http_gRPC_web_handler := func(resp http.ResponseWriter, req *http.Request) {
|
||||
if strings.Contains(req.Header.Get("Content-Type"), "application/grpc") || req.Method == "OPTIONS" {
|
||||
fmt.Printf("gRPC-web req:\n %v\n", req)
|
||||
grpc_web_srv.ServeHTTP(resp, req) // if content type indicates grpc or REQUEST METHOD IS OPTIONS (pre-flight) serve gRPC-web
|
||||
} else {
|
||||
fmt.Printf("legacy web req:\n %v\n", req)
|
||||
http.FileServer(http.Dir((webserver_path))).ServeHTTP(resp, req)
|
||||
}
|
||||
}
|
||||
|
||||
//Open TCP listener
|
||||
log.Printf("P4wnP1 gRPC server listening on " + listen_address)
|
||||
lis, err := net.Listen("tcp", listen_address)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen: %v", err)
|
||||
}
|
||||
|
||||
// run gRPC server in go routine
|
||||
go func() {
|
||||
if err := s.Serve(lis); err != nil {
|
||||
log.Fatalf("Failed to serve: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
//Setup our HTTP server
|
||||
http_srv := &http.Server{
|
||||
Addr: host + ":80", //listen on port 80 with webservice
|
||||
Handler: http.HandlerFunc(http_gRPC_web_handler),
|
||||
ReadHeaderTimeout: 5*time.Second,
|
||||
IdleTimeout: 120*time.Second,
|
||||
}
|
||||
log.Printf("P4wnP1 gRPC-web server listening on " + http_srv.Addr)
|
||||
err_http := http_srv.ListenAndServe()
|
||||
if err_http != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
4
web_client/build.sh
Executable file
4
web_client/build.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# dependencies for the web app
|
||||
gopherjs build -o ../www/webapp.js main.go
|
4
web_client/deps.sh
Executable file
4
web_client/deps.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# dependencies for the web app
|
||||
go get -u honnef.co/go/js/dom
|
8
web_client/index.html
Normal file
8
web_client/index.html
Normal file
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>gRPC test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
9
web_client/install.sh
Executable file
9
web_client/install.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install gopherjs-gRPC plugin by Johan Brandhorst
|
||||
|
||||
# go and protoc have to be installed already
|
||||
# $GOPATH/bin has to be in path
|
||||
|
||||
go get -u github.com/gopherjs/gopherjs
|
||||
go get -u github.com/johanbrandhorst/protobuf/protoc-gen-gopherjs
|
42
web_client/main.go
Normal file
42
web_client/main.go
Normal file
@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
pb "../proto/gopherjs"
|
||||
dom "honnef.co/go/js/dom"
|
||||
)
|
||||
|
||||
var (
|
||||
document = dom.GetWindow().Document().(dom.HTMLDocument)
|
||||
serverAddr = "http://raspberrypi.local"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello")
|
||||
|
||||
client := pb.NewP4WNP1Client(
|
||||
"http://raspberrypi.local:80",
|
||||
)
|
||||
fmt.Printf("Address %v\n", strings.TrimSuffix(document.BaseURI(), "/"))
|
||||
fmt.Printf("Client %v\n", client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
|
||||
gs, err := client.GetDeployedGadgetSetting(ctx, &pb.Empty{})
|
||||
if err == nil {
|
||||
str:=fmt.Sprintf("Gs: %v\n", gs)
|
||||
fmt.Println(str)
|
||||
div_cont:= dom.GetWindow().Document().GetElementByID("content").(*dom.HTMLDivElement)
|
||||
new_div := dom.GetWindow().Document().CreateElement("div").(*dom.HTMLDivElement)
|
||||
new_div.SetTextContent("Result of GetDeployedGadgetSetting gRPC-web call: " + str)
|
||||
div_cont.AppendChild(new_div)
|
||||
} else {
|
||||
fmt.Printf("Error rpc call: %v\n", err)
|
||||
}
|
||||
|
||||
}
|
2
www/README.md
Normal file
2
www/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
The only file in this directory which isn't auto-generated is index.html.
|
||||
|
11
www/index.html
Normal file
11
www/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<head><title>Hello</title></head>
|
||||
<body>
|
||||
<script src="webapp.js"></script>
|
||||
|
||||
<h1>Testpage for P4wnP1 service</h1>
|
||||
<p>See Javascript console for details, entry script is webapp.js (generated by gopherjs)</p>
|
||||
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
30006
www/webapp.js
Normal file
30006
www/webapp.js
Normal file
File diff suppressed because one or more lines are too long
1
www/webapp.js.map
Normal file
1
www/webapp.js.map
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user