🛡️
Hogosuru
  • What is Hogosuru?
    • How it works?
    • Minimal requirements to load a wasm
    • Repositories
  • Guides
    • Configure your environment
    • Web API support
    • Create your first project
    • Load and parse a JSON data
    • Create HTML entities and manipulating DOM
      • Create some dynamic content
      • Attach to existing content
      • Modify CSS and attributes
      • Repeat content using template
    • Async work with Promise
    • Network IO: An example with gofiber
    • Observers: Your data always up to date
    • Create a single app with hogosuru
      • Example
Powered by GitBook
On this page
  • XMLHTTPRequest
  • Fetch
  • Websockets
  1. Guides

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/bulma@0.9.3/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.

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/

 ┌───────────────────────────────────────────────────┐ 
 │                   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/bulma@0.9.3/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:

PreviousAsync work with PromiseNextObservers: Your data always up to date

Last updated 3 years ago

It's normal there is no WebServer available. Now if can build or wasm and loaded it on a true webserver like GoFiber

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!

👍
🎉
https://github.com/realPy/websocket-tester