Maison  >  Article  >  développement back-end  >  Comment implémenter http.Hijacker à l'aide de Gorilla Websockets et alexedwards/scs/v2

Comment implémenter http.Hijacker à l'aide de Gorilla Websockets et alexedwards/scs/v2

PHPz
PHPzavant
2024-02-10 13:21:081243parcourir

如何使用 Gorilla Websockets 和 alexedwards/scs/v2 实现 http.Hijacker

L'éditeur de PHP Apple vous présente aujourd'hui une méthode pour implémenter http.Hijacker à l'aide de Gorilla Websockets et de la bibliothèque alexedwards/scs/v2. Cette méthode peut aider les développeurs à implémenter des fonctions de communication en temps réel dans leurs propres applications, qu'il s'agisse d'un salon de discussion ou de mises à jour en temps réel, etc., elle peut être implémentée de cette manière. Ensuite, nous expliquerons en détail comment utiliser ces deux bibliothèques pour implémenter http.Hijacker afin de rendre votre application plus puissante et flexible.

Contenu de la question

L'excellent alexedwards/scs/v2 dans les applications Web Go a été récemment mis à niveau de 2.5.0 à 2.7.0 pour permettre à Go 1.20+ de prendre en charge http.NewResponseController(). Autorisez ensuite le délai d'expiration du serveur spécifique au gestionnaire d'extension pour les téléchargements de fichiers volumineux. C'est bon. Une conséquence malheureuse de cette mise à niveau nécessaire est la perte de la fonctionnalité Websocket, qui utilise actuellement Gorilla Websockets v1.5.1 (la dernière). Je reçois une erreur courante lorsque j'essaie de me connecter pour mettre à niveau... websocket : réponse non implémentée http.Hijacker J'ai consulté quelques discussions à ce sujet, certaines sur SO, mais je n'ai pas réussi à résoudre quoi que ce soit de spécifique à ce cas. J'ai essayé quelques choses pour essayer d'implémenter http.Hijacker dans mon gestionnaire de point de terminaison Websocket avec mon autre code middleware (exemple commenté, ci-joint "trompeur" à titre d'illustration)... Je pense juste que je comprends cela Pas assez bien. ..

type WebsocketConnection struct {
    *websocket.Conn
}

type WebsocketPayload struct {
    Action      string              `json:"action"`
    Message     string              `json:"message"`
    AdminName   string              `json:"admin_name"`
    MessageType string              `json:"message_type"`
    AdminID     int                 `json:"admin_id"`
    Connection  WebsocketConnection `json:"-"`
}

type WebsocketJSONResponse struct {
    Action        string   `json:"action"`
    Message       string   `json:"message"`
    AdminName     string   `json:"admin_name"`
    AdminID       int      `json:"admin_id"`
    CurrentLogins []string `json:"current_logins"`
}

var upgradeConnection = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
    CheckOrigin:     func(r *http.Request) bool { return true },
}

var webClients = make(map[WebsocketConnection]string)

var websocketChannel = make(chan WebsocketPayload)

func (app *application) WebsocketEndPoint(w http.ResponseWriter, r *http.Request) {
    // rc := http.NewResponseController(w)
    // netConn, _, err := rc.Hijack()
    // if err != nil {
    //  app.errorLog.Println(err)
    //  return
    // }
    // defer netConn.Close()

    app.debugLog.Printf("w's type is %T\n", w)

    ws, err := upgradeConnection.Upgrade(w, r, nil)
    if err != nil {
        app.errorLog.Println(err)  <= ERROR HERE
        return
    }

    app.infoLog.Printf("Web client connected from %s", r.RemoteAddr)
    var response WebsocketJSONResponse
    response.Message = "Connected to server..."

    err = ws.WriteJSON(response)
    if err != nil {
        app.errorLog.Println(err)
        return
    }

    conn := WebsocketConnection{Conn: ws}
    webClients[conn] = ""

    go app.ListenForWebsocket(&conn)
}

Le « w » dans cet exemple est *scs.sessionResponseWriter. Comment puis-je implémenter http.Hijacker dans la réponse sans rompre la connexion ni effectuer la mise à niveau ? Quelle est la bonne approche ?

Solution de contournement

Le package alexedwards/scs/v2 version 2.5.0 prend en charge l'interface du pirate de l'air. La version 2.7.0 ne prend pas en charge l'interface Hijacker, mais prend en charge prend en charge le contrôleur de réponse. Le package gorilla websocket n'utilise pas de contrôleurs de réponse.

Option 1

Utilisation de la version 2.5.0 du package alexedwards/scs/v2.

Option 2

Corrigez la faille du package gorilla en décompressant le rédacteur de réponse dans le code de votre application :

func (app *application) WebsocketEndPoint(w http.ResponseWriter, r *http.Request) {

    wupgrade := w
    if u, ok := w.(interface{ Unwrap() http.ResponseWriter }); ok {
        wupgrade = u.Unwrap()
    }

    app.debugLog.Printf("w's type is %T\n", w)

    ws, err := upgradeConnection.Upgrade(wupgrade, r, nil)
    if err != nil {
        app.errorLog.Println(err)
        return
    }

    app.infoLog.Printf("Web client connected from %s", r.RemoteAddr)
    var response WebsocketJSONResponse
    response.Message = "Connected to server..."

    err = ws.WriteJSON(response)
    if err != nil {
        app.errorLog.Println(err)
        return
    }

    conn := WebsocketConnection{Conn: ws}
    webClients[conn] = ""

    go app.ListenForWebsocket(&conn)
}

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer