Golang中如何通过反向代理连接crossbar.io

Golang中如何通过反向代理连接crossbar.io 我有一个运行在反向代理后容器中的Crossbar消息队列。要连接到Crossbar,我需要将连接从HTTP升级到TCP WebSocket(通过Upgrade/Connect头部)。然后我想订阅一个主题。有没有实现这个功能的基础代码示例?我卡在这里了…

1 回复

更多关于Golang中如何通过反向代理连接crossbar.io的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中通过反向代理连接Crossbar.io,可以使用gorilla/websocket库处理WebSocket升级和连接。以下是基础实现示例:

package main

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

// WebSocket连接配置
var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true // 生产环境应严格验证
    },
}

func connectToCrossbar() (*websocket.Conn, error) {
    // 设置请求头,包含必要的WebSocket升级头部
    header := http.Header{}
    header.Set("Upgrade", "websocket")
    header.Set("Connection", "Upgrade")
    header.Set("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==")
    header.Set("Sec-WebSocket-Version", "13")
    
    // 通过反向代理地址连接
    url := "ws://your-reverse-proxy/ws" // 替换为实际代理地址
    
    // 建立WebSocket连接
    conn, _, err := websocket.DefaultDialer.Dial(url, header)
    if err != nil {
        return nil, err
    }
    
    return conn, nil
}

func subscribeToTopic(conn *websocket.Conn, topic string) error {
    // WAMP协议订阅消息格式(简化示例)
    subscribeMsg := []interface{}{
        5,           // SUBSCRIBE消息类型
        123456789,   // 请求ID
        map[string]interface{}{}, // 选项
        topic,       // 主题URI
    }
    
    // 发送订阅消息
    err := conn.WriteJSON(subscribeMsg)
    if err != nil {
        return err
    }
    
    return nil
}

func main() {
    // 连接Crossbar
    conn, err := connectToCrossbar()
    if err != nil {
        log.Fatal("连接失败:", err)
    }
    defer conn.Close()
    
    log.Println("成功连接到Crossbar")
    
    // 订阅主题
    err = subscribeToTopic(conn, "com.example.topic")
    if err != nil {
        log.Fatal("订阅失败:", err)
    }
    
    log.Println("成功订阅主题")
    
    // 接收消息的goroutine
    go func() {
        for {
            _, message, err := conn.ReadMessage()
            if err != nil {
                log.Println("读取错误:", err)
                return
            }
            log.Printf("收到消息: %s\n", message)
        }
    }()
    
    // 保持连接
    for {
        // 发送心跳或保持连接活跃
        err := conn.WriteMessage(websocket.PingMessage, []byte{})
        if err != nil {
            log.Println("心跳失败:", err)
            break
        }
        time.Sleep(30 * time.Second)
    }
}

如果需要完整的WAMP协议实现,可以使用专门的WAMP客户端库:

// 使用nexus-wamp-client库的示例
package main

import (
    "log"
    
    "github.com/gammazero/nexus/v3/client"
    "github.com/gammazero/nexus/v3/wamp"
)

func main() {
    cfg := client.Config{
        Realm: "realm1",
    }
    
    // 通过反向代理连接
    cl, err := client.ConnectNet(
        "ws://your-reverse-proxy/ws",
        cfg,
    )
    if err != nil {
        log.Fatal(err)
    }
    defer cl.Close()
    
    // 订阅主题
    err = cl.Subscribe("com.example.topic", 
        func(event *wamp.Event) {
            log.Printf("收到事件: %v\n", event.Arguments)
        }, 
        nil,
    )
    if err != nil {
        log.Fatal(err)
    }
    
    // 保持连接
    select {}
}

确保反向代理配置正确传递WebSocket升级头部:

# Nginx配置示例
location /ws {
    proxy_pass http://crossbar-container:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

第一个示例展示了手动处理WebSocket连接和WAMP协议消息,第二个示例使用成熟的WAMP客户端库简化了实现。根据你的具体需求选择适合的方式。

回到顶部