Gorilla Websockets, golang simple websockets example

I previously posted a quick example of using the standard library websockets API in golang. Unfortunately there are a number of issues that make difficult to use in practice. Notably, it lacks support for PING/PONG packets which are often used to for KeepAlive functionality in websockets. This is particularly important, as browsers tend to be aggressive in killing off these connections.

So, here’s a quick complete example of Gorilla Websockets in golang, with similar functionality to that I posted previously. It simply echos everything it receives back to the client. First the golang code:

package main

import (
        "github.com/gorilla/websocket"
        "net/http"
        "fmt"
)

var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

func print_binary(s []byte) {
  fmt.Printf("Received b:");
  for n := 0;n < len(s);n++ {
    fmt.Printf("%d,",s[n]);
  }
  fmt.Printf("\n");
}

func echoHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        //log.Println(err)
        return
    }

    for {
        messageType, p, err := conn.ReadMessage()
        if err != nil {
            return
        }

        print_binary(p)

        err = conn.WriteMessage(messageType, p);
        if  err != nil {
            return
        }
    }
}

func main() {
  http.HandleFunc("/echo", echoHandler)
  http.Handle("/", http.FileServer(http.Dir(".")))
  err := http.ListenAndServe(":8080", nil)
  if err != nil {
    panic("Error: " + err.Error())
  }
}

And then the html used to interface with the websocket. Save it in the same directory as the golang program, and access it at: http://localhost:8080/filename.html


<html>
<head>
<meta charset="UTF-8" />
<script>
        var serversocket = new WebSocket("ws://localhost:8080/echo");

        serversocket.onopen = function() {
                serversocket.send("Connection init");
        }

        // Write message on receive
        serversocket.onmessage = function(e) {
                document.getElementById('comms').innerHTML += "Received: " + e.data + "<br>";
        };

        function senddata() {
                var data = document.getElementById('sendtext').value;
                serversocket.send(data);
                document.getElementById('comms').innerHTML += "Sent: " + data + "<br>";
        }

</script>
</head>

<body>
        <input id="sendtext" type="text" />
        <input type="button" id="sendBtn" value="send" onclick="senddata()"></input>
        <div id='comms'></div>
</body>
</html>

Getting to awa-kamogawa from Tokyo by train

To get to Awa-Kamogawa from Tokyo you can take the train from Yaesu (South exit). This is right next to where the Shikansen leaves from (on the left
facing in from the South exit). Follow signs for Yaesu central then south (not north).

IMG_1653.JPG

The train is called the Wakashio limited express and leaves from Yaesu Tokyo station. The entrance and ticket machines are to the left of the Shinkansen entrance.

The ticket machines and signs do not refer to the Wakashio line. The Wakashio train leaves from the Keiyo line so look for those signs. Outside the Keiyo line you can buy a ticket at the ticket machines. Select “English”, “Limited Express tickets” and then Sotobo, Awa-Kamogawa. The Wakashio train, runs on the Sotobo line, leaving from the Keiyo line platform! Confusing.

IMG_1654.JPG

IMG_1656.JPG

Once inside follow the directions to the Keiyo line. It’s quite a long way, but is well marked:

IMG_1655.JPG

IMG_1657.JPG

IMG_1658.JPG

IMG_1660.JPG

IMG_1659.JPG

Emscripten calling JS from C and returning by reference (pointer)

JS code can manipuate memory directly using setValue, here’s a quick example of returning by reference. The C code is as follows:

#include <stdio.h>
#include <emscripten.h>
#include <string.h>

int main() {

  char buffer[10];
  strcpy(buffer,"nothing");

  int ret = EM_ASM_INT({
    return js_receive($0,$1,$2,$3);
  }, 1,buffer,3,4);

  printf("returned: %d\n",ret);
  printf("buffer  : %s\n",buffer);

  char call[100];
  strcpy(call,"alert('");
  strcat(call,buffer);
  strcat(call,"')");
  emscripten_run_script(call);
}

And can be called using the following JS which modifies the contents of buffer:

 <!DOCTYPE html>
<html>
<body>

<script>

function js_receive(a,b,c,d) {


  var bstr = Pointer_stringify(b);
  document.write(a + " " + bstr + " " + c + " " + d);

  setValue(b  ,  84, 'i8');
  setValue(b+1,  87, 'i8');
  setValue(b+2,  79, 'i8');
  setValue(b+3,   0, 'i8');

  return 42;
}

</script>

<script src="calljs.js"></script>


</body>
</html>

Calling JS from C using EM_ASM in Emscripten

A very simple for calling JS from C and returning a value. Create the following C program, in the file calljs.c, it makes a single call to js_receive which will be our Javascript function:

#include <stdio.h>
#include <emscripten.h>

int main() {
  int ret = EM_ASM_INT({
    return js_receive($0,$1,$2,$3);
  }, 1,"two",3,4);

  printf("returned: %d\n",ret);
}

compile it with: <pre>emcc calljs.c -o calljs.js</pre>

It will then call the JS code which can access the variables and string. Here's an example complete html file:

[sourcecode language="html"]
 <!DOCTYPE html>
<html>
<body>

<script>

function js_receive(a,b,c,d) {

  var bstr = Pointer_stringify(b);
  document.write(a + " " + bstr + " " + c + " " + d);

  return 42;
}

</script>

<script src="calljs.js"></script>

</body>
</html>