Fetch Request VS. WebSocket Which one is faster?

Viewed 1433

I'm sending a same data in both Fetch and WebSocket but :

  • HTTP takes 29 seconds to transfer around 200 MB.
  • WebSocket takes 6 seconds to transfer around 200 MB.

Question

Why WebSocket is faster than HTTP? It's related to encoding or technology or something else...?

Fetch

 async function postData(url = '', data) {
        const response = await fetch(url, {
            method: 'POST',
            mode: 'no-cors',
            cache: 'no-cache',
            credentials: 'same-origin',
            headers: {
                'Content-Type': 'application/octet-stream'
            },
            redirect: 'follow',
            referrerPolicy: 'no-referrer',
            body: data
        });
        return response; //.arrayBuffer();
    }

    postData('http://localhost:3800/buffer', arrU8)
        .then(data => {
            console.log(data);
        });

arrU8 is an Uint8Array by length : 185578200

WebSocket

  function connect() {
        return new Promise(function (resolve, reject) {
            var ws = new WebSocket('ws://127.0.0.1:8081/echo');
            ws.onopen = function () {
                resolve(ws);
            };
            ws.onerror = function (err) {
                reject(err);
            };
            ws.onclose = function (evt) {
                console.log("CLOSE SOCKET", new Date().toLocaleString());
            };
            ws.onmessage = function (evt) {
                console.log("RESPONSE SOCKET: " + "RECEIVED" /* evt.data */, new Date().toLocaleString());
            };
        });
    }

    connect().then(function (ws) {
        // onopen
        ws.binaryType = 'arraybuffer';
        ws.send(arrU8);
        ws.close();
    }).catch(function (err) {
        // onerror
        console.log("ERROR: " + evt.data, new Date().toLocaleString());
    });

Server Side is wrote by GO

HTTP

func process(w http.ResponseWriter, r *http.Request) {

    if r.URL.Path != "/buffer" {
        http.Error(w, "404 not found.", http.StatusNotFound)
        return
    }

    switch r.Method {
    case "GET":

        fmt.Fprintf(w, "GET request is received: %s \n", r.URL)
    case "POST":

        body, err := ioutil.ReadAll(r.Body)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        log.Println("Data length received = ", len(body))

        fmt.Fprintf(w, "Data length = %v \n", len(body))

    default:
        fmt.Fprintf(w, "Sorry, only GET and POST methods are supported.")
    }
}

WebSocket

package main

import (
    "flag"
    "log"
    "net/http"
    "text/template"

    "github.com/gorilla/websocket"
)

var addr = flag.String("addr", "localhost:8081", "http service address")
var upgrader = websocket.Upgrader{} // use default options
func main() {

    log.Println("Launching WebSocket server...", *addr)
    flag.Parse()
    log.SetFlags(log.LstdFlags | log.Lmicroseconds)
    http.HandleFunc("/echo", echo)
    http.HandleFunc("/", home)
    log.Fatal(http.ListenAndServe(*addr, nil))
}

func echo(w http.ResponseWriter, r *http.Request) {

    // To fix 403 error temporarily. It's unsafe:
    upgrader.CheckOrigin = func(r *http.Request) bool { return true }

    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Print("upgrade:", err)
        return
    }
    defer c.Close()
    for {
        mt, message, err := c.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            break
        }
        log.Println("recv: message type:", mt)
        log.Printf("recv: bytes count: %v", len(message))
        // // // Disable echo and log
        // log.Printf("recv: %s", message)
        // err = c.WriteMessage(mt, message)
        // if err != nil {
        //  log.Println("write:", err)
        //  break
        // }
    }
}

func home(w http.ResponseWriter, r *http.Request) {
    homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
}
1 Answers

Websocket is faster if you have to send more data over time, because you can keep the connection to the server open.

With http you have to make the 2-way handshake everytime and establish a connection every time you want to send something.

In your situation it would be because the http have to make the handshake multiple times, because it can't send everything in one session.

Related