Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Cara menggunakan Websocket golang untuk membangunkan fungsi peta masa nyata

Cara menggunakan Websocket golang untuk membangunkan fungsi peta masa nyata

WBOY
WBOYasal
2023-12-02 13:49:41769semak imbas

Cara menggunakan Websocket golang untuk membangunkan fungsi peta masa nyata

Cara menggunakan Websocket Golang untuk membangunkan fungsi peta masa nyata

Dalam pembangunan aplikasi web hari ini, keperluan masa nyata semakin tinggi dan lebih tinggi, terutamanya yang melibatkan aplikasi berkaitan lokasi geografi, seperti fungsi peta masa nyata . Teknologi Websocket Golang boleh menyediakan komunikasi dua hala yang pantas dan masa nyata, yang sesuai untuk pembangunan fungsi peta masa nyata. Dalam artikel ini, saya akan memperkenalkan anda cara menggunakan Websocket Golang untuk membangunkan fungsi peta masa nyata, sambil memberikan contoh kod khusus.

1. Konsep asas

1.1 Websocket

Websocket ialah protokol baharu yang diperkenalkan oleh HTML5 Ia adalah teknologi yang mewujudkan komunikasi dua hala pada protokol HTTP tradisional. Websocket menggunakan port standard HTTP/HTTPS untuk mewujudkan sambungan yang panjang antara klien dan pelayan, supaya pelayan boleh menolak data kepada klien dalam masa nyata. Pada masa yang sama, Websocket juga menyokong komunikasi dua hala yang serupa dengan protokol TCP, membolehkan pelanggan dan pelayan menghantar data pada masa yang sama.

1.2 Golang

Golang ialah bahasa pengaturcaraan yang pantas, cekap dan selamat, terutamanya sesuai untuk pembangunan web. Pembangunan Websocket Golang boleh menggunakan modul websocket yang disediakan oleh perpustakaan net/http standard, yang sangat mudah dan ringkas.

2. Langkah-langkah pelaksanaan

2.1 Persediaan persekitaran

Pertama, anda perlu memasang Golang, yang boleh dimuat turun dan dipasang dari laman web rasmi. Kemudian, masukkan arahan berikut pada baris arahan untuk memasang modul websocket:

pergi dapatkan github.com/gorilla/websocket

2.2 Pelaksanaan Backend

Di Golang, menulis pelayan Websocket agak mudah. Anda boleh menggunakan fungsi HandleFunc pustaka http untuk mencipta penghala dan menentukan fungsi pemprosesan permintaan. Dalam fungsi pemprosesan, gunakan fungsi Penaik taraf perpustakaan websocket untuk menukar protokol HTTP kepada protokol Websocket dan gunakan fungsi ReadMessage dan WriteMessage untuk melaksanakan komunikasi dua hala. Berikut ialah contoh mudah:

package main

import (
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

func main() {
    http.HandleFunc("/", serveHome)
    http.HandleFunc("/ws", handleWebSocket)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func serveHome(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "index.html")
}

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

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

    for {
        messageType, p, err := conn.ReadMessage()
        if err != nil {
            log.Println(err)
            return
        }
        log.Printf("Received message: %s", p)

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

2.3 Pelaksanaan bahagian hadapan

Di bahagian hadapan, gunakan JavaScript untuk mewujudkan sambungan Websocket, kemudian gunakan fungsi hantar untuk menghantar maklumat kepada pelayan, dan gunakan fungsi onmessage untuk menerima mesej yang ditolak oleh pelayan. Berikut ialah contoh mudah:

var socket = new WebSocket("ws://localhost:8080/ws");

socket.onopen = function(event) {
    socket.send("Hello, server!");
};

socket.onmessage = function(event) {
    console.log("Received message: " + event.data);
};

3. Contoh peta masa nyata

Di bawah, kami akan menggabungkan dua bahagian di atas dan menggunakan teknologi Websocket Golang untuk melaksanakan fungsi peta masa nyata.

3.1 Pelaksanaan Bahagian Belakang

Di bahagian pelayan, kami boleh menggunakan perpustakaan standard "net/http" Golang dan pustaka pihak ketiga "gorila/soket web" untuk melaksanakan komunikasi Websocket. Kod khusus adalah seperti berikut:

package main

import (
    "encoding/json"
    "flag"
    "fmt"
    "html/template"
    "log"
    "net/http"
    "sync"

    "github.com/gorilla/websocket"
)

const (
    MapWidth  = 800
    MapHeight = 600
)

var (
    port         = flag.Int("port", 8888, "http listen port")
    addr         = flag.String("addr", "localhost", "http server address")
    mu           sync.Mutex
    connections map[*websocket.Conn]bool
)

func init() {
    connections = make(map[*websocket.Conn]bool)
}

type Position struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}

type Location struct {
    Name     string   `json:"name"`
    Position Position `json:"position"`
}

type Map struct {
    Name      string     `json:"name"`
    ImageURL  string     `json:"image_url"`
    Locations []Location `json:"locations"`
}

var (
    maps = []Map{
        Map{
            Name:     "Campus Map",
            ImageURL: "/static/campus_map.png",
            Locations: []Location{
                Location{
                    Name: "Library",
                    Position: Position{
                        X: 400,
                        Y: 300,
                    },
                },
                Location{
                    Name: "Dormitory Building",
                    Position: Position{
                        X: 300,
                        Y: 200,
                    },
                },
                Location{
                    Name: "Teaching Building",
                    Position: Position{
                        X: 500,
                        Y: 400,
                    },
                },
            },
        },
    }
)

func main() {
    flag.Parse()
    http.HandleFunc("/", indexPageHandler)
    http.HandleFunc("/ws", wsHandler)

    staticHandler := http.FileServer(http.Dir("static"))
    http.Handle("/static/", http.StripPrefix("/static/", staticHandler))

    addr := fmt.Sprintf("%s:%d", *addr, *port)
    log.Printf("Starting server on %s", addr)
    err := http.ListenAndServe(addr, nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func indexPageHandler(w http.ResponseWriter, r *http.Request) {
    indexTemplate := template.Must(template.ParseFiles("templates/index.html"))
    indexTemplate.ExecuteTemplate(w, "index.html", maps)
}

type Message struct {
    Action   string `json:"action"`
    Location string `json:"location"`
}

func wsHandler(w http.ResponseWriter, r *http.Request) {
    ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
    if err != nil {
        http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
        return
    }
    defer ws.Close()

    mu.Lock()
    connections[ws] = true
    mu.Unlock()

    for {
        msgType, msg, err := ws.ReadMessage()
        if err != nil {
            delete(connections, ws)
            return
        } else {
            log.Printf("Received: %s
", msg)
            m := &Message{}
            if err := json.Unmarshal(msg, m); err != nil {
                log.Printf("Failed to unmarshal message %s: %v", msg, err)
            } else {
                switch m.Action {
                case "move":
                    sendUpdate(ws, m.Location)
                    updateMap(m.Location)
                case "logout":
                    delete(connections, ws)
                }
            }
        }

        for c := range connections {
            err = c.WriteMessage(msgType, msg)
            if err != nil {
                delete(connections, c)
                log.Printf("Error writing to user [%s]: %v
", c.RemoteAddr(), err)
            }
        }
    }
}

func updateMap(loc string) {
    for i := range maps {
        for j := range maps[i].Locations {
            if maps[i].Locations[j].Name == loc {
                maps[i].Locations[j].Position.X += 20
                maps[i].Locations[j].Position.Y += 20
            }
        }
    }
}

func sendUpdate(ws *websocket.Conn, loc string) {
    for i := range maps {
        if maps[i].Name == "Campus Map" {
            msg := &Message{
                Action: "update",
                Location: loc,
            }
            for j := range maps[i].Locations {
                location := maps[i].Locations[j]
                msgBody, _ := json.Marshal(location)
                if err := ws.WriteMessage(websocket.TextMessage, msgBody); err != nil {
                    log.Printf("Could not send message: %v", err)
                }
            }
            break
        }
    }
}

3.2 Pelaksanaan bahagian hadapan

Di bahagian hadapan, gunakan JavaScript untuk mewujudkan sambungan Websocket, kemudian gunakan fungsi hantar untuk menghantar maklumat ke pelayan, dan gunakan fungsi onmessage untuk menerima mesej yang ditolak oleh pelayan. Peta langsung HTML5 boleh dilukis menggunakan teg SVG. Berikut ialah contoh mudah:

<!doctype html>
<html>

<head>
  <title>Realtime Map</title>

  <style>
    #map {
      width: 800px;
      height: 600px;
    }
  </style>
</head>

<body>
  <svg id="map">
    <image xlink:href="{{ .ImageURL }}" width="{{ .Width }}" height="{{ .Height }}" />
    {{ range $location := .Locations }}
      <circle id="{{ $location.Name }}" cx="{{ $location.Position.X }}" cy="{{ $location.Position.Y }}" r="5" fill="red" />
    {{ end }}
  </svg>

  <script>
    var ws = new WebSocket("ws://localhost:8888/ws");

    ws.onopen = function(event) {
      console.log("WebSocket connected");
    };

    ws.onmessage = function(event) {
      var data = JSON.parse(event.data);

      if (data.action === "update") {
        var location = data.location;
        var $circle = document.getElementById(location.name);
        var x = parseFloat($circle.getAttribute("cx"));
        var y = parseFloat($circle.getAttribute("cy"));
        $circle.setAttribute("cx", x + location.position.x);
        $circle.setAttribute("cy", y + location.position.y);
      }
    };

    window.addEventListener("load", function() {
      var $circles = document.querySelectorAll("#map circle");
      for (var i = 0; i < $circles.length; i++) {
        $circles[i].addEventListener("click", function() {
          var location = this.id;
          var msg = {
            action: "move",
            location: location
          };
          ws.send(JSON.stringify(msg));
        });
      }
    });
  </script>
</body>

</html>

IV. Ringkasan

Selepas memperkenalkan konsep asas teknologi Websocket Golang, artikel ini menyediakan contoh pembangunan fungsi peta masa nyata. Contoh di atas boleh melukis peta melalui teg HTML5 dan SVG, menggunakan teknologi Websocket untuk mencapai komunikasi dua hala masa nyata dan merealisasikan fungsi peta masa nyata. Sudah tentu, perkara di atas hanyalah contoh Dalam senario sebenar, penambahbaikan dan pengoptimuman yang sesuai perlu dibuat mengikut keperluan aplikasi tertentu.

Atas ialah kandungan terperinci Cara menggunakan Websocket golang untuk membangunkan fungsi peta masa nyata. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn