Network IO: An example with gofiber
There are several way to catch and update your data in your app. I will cover some basic example with go fiber with embbed wasm and assets. You can off course set the assets on the filesystem.
XMLHTTPRequest
We build a page with one button design with bulma.
On click we use a POST request on /app/data with form data set with username=test
func OnClickButton() {
endpoint, _ := url.Parse("app/data")
if xhr, err := xmlhttprequest.New(); err == nil {
xhr.Open("POST", endpoint.String())
f, _ := formdata.New()
f.Append("username", "test")
xhr.SetOnload(func(i interface{}) {
if text, err := xhr.ResponseText(); err == nil {
fmt.Printf("Resultat: %s\n", text)
}
if header, err := xhr.GetResponseHeader("Content-Type"); err == nil {
fmt.Printf("Resultat: %s\n", header)
}
})
xhr.Send(f)
}
}
func main() {
hogosuru.Init()
// we get the current document
if doc, err := document.New(); hogosuru.AssertErr(err) {
//we got the head
if head, err := doc.Head(); hogosuru.AssertErr(err) {
if link, err := htmllinkelement.New(doc); hogosuru.AssertErr(err) {
link.SetRel("stylesheet")
link.SetHref("https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css")
head.AppendChild(link.Node)
}
}
//we get the current body
if body := doc.Body_(); hogosuru.AssertErr(err) {
if div, err := htmldivelement.New(doc); hogosuru.AssertErr(err) {
if list, err := div.ClassList(); hogosuru.AssertErr(err) {
list.Add("buttons")
}
if buttonprimary, err := htmlbuttonelement.New(doc); hogosuru.AssertErr(err) {
buttonprimary.SetTextContent("Primary")
//we get the class list attribute
if list, err := buttonprimary.ClassList(); hogosuru.AssertErr(err) {
list.Add("button")
list.Add("is-primary")
}
buttonprimary.OnClick(func(e event.Event) {
OnClickButton()
})
div.Append(buttonprimary.Element)
}
body.Append(div.Element)
}
}
}
ch := make(chan struct{})
<-ch
}
We can test with our example with wasmbrowsertest:
WASM_HEADLESS=off GOOS=js GOARCH=wasm go run ioxmlhttprequest/front/main.go
This work! if we click on button ,the httprequest is executed but return 404.
It's normal there is no WebServer available. Now if can build or wasm and loaded it on a true webserver like GoFiber π
We build our wasm and output to the assets directory of server with command:
WASM_HEADLESS=off GOOS=js GOARCH=wasm go build -o ioxmlhttprequest/server/assets/app.wasm ioxmlhttprequest/front/main.go
We copy the "glue wasm_exec.js" correspondant to your compiler
cp $(go env GOROOT)/misc/wasm/wasm_exec.js ioxmlhttprequest/server/assets/
We can now write the backend parts. We listen a HTTP servers on port 8080, serve the index.hml , app.wasm and wasm_exec.js
We handle the "/app/data" routing on POST. We log the username value of post.
//go:embed assets/*
var Dist embed.FS
func ServerAssets(app *fiber.App) {
app.Get("app.wasm", func(c *fiber.Ctx) error {
wasm, _ := Dist.ReadFile("assets/app.wasm")
c.Set(fiber.HeaderContentType, "application/wasm")
return c.Send(wasm)
})
app.Use("/", filesystem.New(filesystem.Config{
Root: http.FS(Dist),
PathPrefix: "assets",
}))
}
func SetData(c *fiber.Ctx) error {
if username := c.FormValue("username"); username != "" {
fmt.Printf("Receive POST with %s\n", username)
}
return c.Send([]byte("OK"))
}
func Routing(app *fiber.App) {
approute := app.Group("/app")
approute.Post("/data", SetData)
}
func main() {
app := fiber.New(fiber.Config{
ServerHeader: "hogosuruserver",
})
Routing(app)
ServerAssets(app)
app.Listen(":8080")
}
Its ok we just need test with:
go run ioxmlhttprequest/server/main.go
And go to:
http://localhost:8080/
πWe have our front page with a button, when we click on button a post is done and we can that value is send and receive by our backend!
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Fiber v2.29.0 β
β http://127.0.0.1:8080 β
β (bound on host 0.0.0.0 and port 8080) β
β β
β Handlers ............. 4 Processes ........... 1 β
β Prefork ....... Disabled PID ............. 36099 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
Receive POST with test
Fetch
The Fetch method is more complicated to use than xmlhttprequest but allow you control more things. A fetch is Promise, so you can use it in the same way and chained it.
The same behaviour will be result to:
func OnClickButton() {
dataPost := url.Values{}
var headers map[string]interface{} = map[string]interface{}{"Content-Type": "application/x-www-form-urlencoded"}
var fetchOpts map[string]interface{} = map[string]interface{}{"method": "POST", "headers": headers, "body": dataPost.Encode()}
//Start promise and wait result
if f, err := fetch.New("app/data", fetchOpts); hogosuru.AssertErr(err) {
f.Then(func(r response.Response) *promise.Promise {
return nil
}, func(e error) {
fmt.Printf("An error occured: %s\n", e.Error())
})
}
}
func main() {
hogosuru.Init()
// we get the current document
if doc, err := document.New(); hogosuru.AssertErr(err) {
//we got the head
if head, err := doc.Head(); hogosuru.AssertErr(err) {
if link, err := htmllinkelement.New(doc); hogosuru.AssertErr(err) {
link.SetRel("stylesheet")
link.SetHref("https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css")
head.AppendChild(link.Node)
}
}
//we get the current body
if body := doc.Body_(); hogosuru.AssertErr(err) {
if div, err := htmldivelement.New(doc); hogosuru.AssertErr(err) {
if list, err := div.ClassList(); hogosuru.AssertErr(err) {
list.Add("buttons")
}
if buttonprimary, err := htmlbuttonelement.New(doc); hogosuru.AssertErr(err) {
buttonprimary.SetTextContent("Primary")
//we get the class list attribute
if list, err := buttonprimary.ClassList(); hogosuru.AssertErr(err) {
list.Add("button")
list.Add("is-primary")
}
buttonprimary.OnClick(func(e event.Event) {
OnClickButton()
})
div.Append(buttonprimary.Element)
}
body.Append(div.Element)
}
}
}
ch := make(chan struct{})
<-ch
}
We build our wasm and output to the assets directory of server with command:
WASM_HEADLESS=off GOOS=js GOARCH=wasm go build -o iofetch/server/assets/app.wasm iofetch/front/main.go
We copy the "glue wasm_exec.js" correspondant to your compiler
cp $(go env GOROOT)/misc/wasm/wasm_exec.js ioxmlhttprequest/server/assets/
Its ok we just need test with:
go run iofetch/server/main.go
And go to:
http://localhost:8080/
Click on button:
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Fiber v2.29.0 β
β http://127.0.0.1:8080 β
β (bound on host 0.0.0.0 and port 8080) β
β β
β Handlers ............. 4 Processes ........... 1 β
β Prefork ....... Disabled PID ............. 41014 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
Receive POST with testfetch
Websockets
My wesocket-tester is a good example how to manipulate websockets:
Last updated