Maison  >  Article  >  développement back-end  >  Comment utiliser le Websocket de Golang pour développer des fonctions cartographiques en temps réel

Comment utiliser le Websocket de Golang pour développer des fonctions cartographiques en temps réel

WBOY
WBOYoriginal
2023-12-02 13:49:41770parcourir

Comment utiliser le Websocket de Golang pour développer des fonctions cartographiques en temps réel

Comment utiliser le Websocket de Golang pour développer des fonctions de cartographie en temps réel

Dans le développement d'applications Web d'aujourd'hui, les exigences en temps réel sont de plus en plus élevées, en particulier celles impliquant des applications liées à la localisation géographique, telles que les fonctions de cartographie en temps réel . La technologie Websocket de Golang peut fournir une communication bidirectionnelle rapide et en temps réel, adaptée au développement de fonctions cartographiques en temps réel. Dans cet article, je vais vous présenter comment utiliser le Websocket de Golang pour développer des fonctions cartographiques en temps réel, tout en fournissant des exemples de code spécifiques.

1. Concepts de base

1.1 Websocket

Websocket est un nouveau protocole introduit par HTML5. C'est une technologie qui établit une communication bidirectionnelle sur le protocole HTTP traditionnel. Websocket utilise le port standard HTTP/HTTPS pour établir une longue connexion entre le client et le serveur, afin que le serveur puisse transmettre des données au client en temps réel. Dans le même temps, Websocket prend également en charge la communication bidirectionnelle similaire au protocole TCP, permettant au client et au serveur de transmettre des données en même temps.

1.2 Golang

Golang est un langage de programmation rapide, efficace et sûr, particulièrement adapté au développement Web. Le développement Websocket de Golang peut utiliser le module websocket fourni par la bibliothèque standard net/http, ce qui est très pratique et simple.

2. Étapes de mise en œuvre

2.1 Configuration de l'environnement

Tout d'abord, vous devez installer Golang, qui peut être téléchargé et installé à partir du site officiel. Ensuite, entrez la commande suivante sur la ligne de commande pour installer le module websocket :

allez chercher github.com/gorilla/websocket

2.2 Implémentation du backend

Dans Golang, écrire le serveur Websocket est relativement simple. Vous pouvez utiliser la fonction HandleFunc de la bibliothèque http pour créer un routeur et spécifier la fonction de traitement des requêtes. Dans la fonction de traitement, utilisez la fonction Upgrader de la bibliothèque websocket pour basculer le protocole HTTP vers le protocole Websocket et utilisez les fonctions ReadMessage et WriteMessage pour implémenter une communication bidirectionnelle. Voici un exemple simple :

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 Implémentation du front-end

Dans le front-end, utilisez JavaScript pour établir une connexion Websocket, puis utilisez la fonction send pour envoyer des informations au serveur et utilisez la fonction onmessage pour recevoir messages poussés par le serveur. Voici un exemple simple :

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. Exemple de carte en temps réel

Ci-dessous, nous allons combiner les deux parties ci-dessus et utiliser la technologie Websocket de Golang pour implémenter une fonction de carte en temps réel.

3.1 Implémentation du backend

Côté serveur, nous pouvons utiliser la bibliothèque standard de Golang « net/http » et la bibliothèque tierce « gorilla/websocket » pour implémenter la communication Websocket. Le code spécifique est le suivant :

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 Implémentation du front-end

Dans le front-end, utilisez JavaScript pour établir une connexion Websocket, puis utilisez la fonction send pour envoyer des informations au serveur et utilisez la fonction onmessage pour recevoir messages poussés par le serveur. Des cartes en direct HTML5 peuvent être dessinées à l'aide de balises SVG. Voici un exemple simple :

<!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. Résumé

Après avoir présenté les concepts de base de la technologie Websocket de Golang, cet article fournit un exemple de développement de la fonction de carte en temps réel. L'exemple ci-dessus peut dessiner une carte via des balises HTML5 et SVG, utiliser la technologie Websocket pour réaliser une communication bidirectionnelle en temps réel et réaliser la fonction de carte en temps réel. Bien entendu, ce qui précède ne sont que des exemples. Dans des scénarios réels, des améliorations et des optimisations appropriées doivent être apportées en fonction des exigences spécifiques de l'application.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn