在未绘制的界面中获取值

发布于 2025-02-06 16:20:20 字数 2816 浏览 2 评论 0原文

我有一个接收多种数据类型的WebSocket客户端。根据接收到的数据,函数将从服务器接收到不同结构的函数。然后,该结构通过通道作为接口返回到我的主文件。由于我从服务器接收多种数据类型,因此我无法指定解析功能的确切返回值。

有了我的主文件中的数据,我希望有一种方法能够浏览数据中的不同值。由于我要返回一个界面,因此这似乎是不可能的。每当我尝试索引接口时,我都会收到一个错误,说c.Value undefined(type接口{}没有字段或方法值)

我觉得我在这里没有做任何事情。到目前为止,我想到的两个解决方案是:

  1. 让我的频道价值成为通用的,并且我的聆听& JSON解码器函数(所有这些都放在下面)都返回通用或
  2. 使用方法创建接口。我的频道将是这种类型的,我的聆听& JSON解码器功能将返回此接口。

不过,我不确定这两种方法是否真的可以解决我的问题。我也不知道与其他方式相比,是否有一种表现更多的方法。

这是我更好地理解问题的代码

func main() {
    // check if in production or testing mode
    var testing bool = true // default to testing
    args := os.Args
    isTesting(args, &testing, &stored_data.Base_currency)

    // go routine handler
    comms := make(chan os.Signal, 1)
    signal.Notify(comms, os.Interrupt, syscall.SIGTERM)
    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    var wg sync.WaitGroup

    // set ohlc interval and pairs
    OHLCinterval := 5
    pairs := []string{"BTC/" + stored_data.Base_currency, "EOS/" + stored_data.Base_currency}

    // create ws connections
    pubSocket, err := ws_client.ConnectToServer("public", testing)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    // create websocket channels
    pubCh := make(chan interface{})
    defer close(pubCh)

    // listen to websocket connections
    wg.Add(1)
    go pubSocket.PubListen(ctx, &wg, pubCh, testing)

    // connect to data streams
    pubSocket.SubscribeToOHLC(pairs, OHLCinterval)

    // listen to public socket
    go func() {
        for c := range pubCh {
            fmt.Println(c) // This is where I would like to be able to go through my data more thoroughly
        }
    }()

    <-comms
    cancel()
    wg.Wait()
}

,这是Publisten函数中发生的事情,而我的JSON解码功能

func (socket *Socket) PubListen(ctx context.Context, wg *sync.WaitGroup, ch chan interface{}, testing bool) {
    defer wg.Done()
    defer socket.Close()
    var res interface{}

    socket.OnTextMessage = func(message string, socket Socket) {
        res = pubJsonDecoder(message, testing)
        ch <- res
    }
    <-ctx.Done()
    log.Println("closing public socket")
    return
}

func pubJsonDecoder(response string, testing bool) interface{} {
    var resp interface{}
    byteResponse := []byte(response)

    resp, err := ohlcResponseDecoder(byteResponse, testing)
    if err != nil {
        resp, err = heartBeatResponseDecoder(byteResponse, testing)
        if err != nil {
            resp, err = serverConnectionStatusResponseDecoder(byteResponse, testing)
            if err != nil {
                resp, err = ohlcSubscriptionResponseDecoder(byteResponse, testing)
            }
        }
    }
    return resp
}

感谢您的任何帮助

I have a websocket client that receives multiple data types. A function unmarshals json received from the server into different structs depending on the data received. The struct is then returned as an interface through a channel to my main file. Since i receive multiple data types from the server, I am not able to specify the exact return value of my parsing function.

With the data in my main file, I would like to have a way to be able to then go through the different values in the data. Since I am returning an interface, this seems impossible to do. Whenever i try to index the interface, I receive an error saying c.VALUE undefined (type interface{} has no field or method VALUE).

I feel like I'm not doing something right here. The 2 solutions I've thought about so far are:

  1. having my channel value be a generic and my listen & JSON decoder funcs (these are all put below) all return a generic or
  2. create an interface with methods. My channel would be of this type and again, my listen & JSON decoder funcs would return this interface.

I'm not sure if either of these ways would actually solve my issue, though. I also don't know if there is one way that would be more performant compared to other ways.

Here is my code to better understand the issue

func main() {
    // check if in production or testing mode
    var testing bool = true // default to testing
    args := os.Args
    isTesting(args, &testing, &stored_data.Base_currency)

    // go routine handler
    comms := make(chan os.Signal, 1)
    signal.Notify(comms, os.Interrupt, syscall.SIGTERM)
    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    var wg sync.WaitGroup

    // set ohlc interval and pairs
    OHLCinterval := 5
    pairs := []string{"BTC/" + stored_data.Base_currency, "EOS/" + stored_data.Base_currency}

    // create ws connections
    pubSocket, err := ws_client.ConnectToServer("public", testing)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    // create websocket channels
    pubCh := make(chan interface{})
    defer close(pubCh)

    // listen to websocket connections
    wg.Add(1)
    go pubSocket.PubListen(ctx, &wg, pubCh, testing)

    // connect to data streams
    pubSocket.SubscribeToOHLC(pairs, OHLCinterval)

    // listen to public socket
    go func() {
        for c := range pubCh {
            fmt.Println(c) // This is where I would like to be able to go through my data more thoroughly
        }
    }()

    <-comms
    cancel()
    wg.Wait()
}

Here is what happens in the PubListen function and my JSON decoding function

func (socket *Socket) PubListen(ctx context.Context, wg *sync.WaitGroup, ch chan interface{}, testing bool) {
    defer wg.Done()
    defer socket.Close()
    var res interface{}

    socket.OnTextMessage = func(message string, socket Socket) {
        res = pubJsonDecoder(message, testing)
        ch <- res
    }
    <-ctx.Done()
    log.Println("closing public socket")
    return
}

func pubJsonDecoder(response string, testing bool) interface{} {
    var resp interface{}
    byteResponse := []byte(response)

    resp, err := ohlcResponseDecoder(byteResponse, testing)
    if err != nil {
        resp, err = heartBeatResponseDecoder(byteResponse, testing)
        if err != nil {
            resp, err = serverConnectionStatusResponseDecoder(byteResponse, testing)
            if err != nil {
                resp, err = ohlcSubscriptionResponseDecoder(byteResponse, testing)
            }
        }
    }
    return resp
}

Thanks for any help you may have

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

能怎样 2025-02-13 16:20:21

由于您似乎控制了可以脱颖而出的类型的完整列表,因此可以使用 type swicth ::

swich v := c.(type) {
case *ohlcResponse:
   // in this block, v is a *ohlcRrsponse
case *heartBeatResponse:
   // in this block, v is a *heartBeatResponse
case *serverConnectionStatusResponse:
   // in this block, v is a *serverConnectionStatus
case *ohlcSubscriptionResponse:
   // in this block, v is a *ohlcSubscriptionResponse

default:
   // choose some way to report unhandled types:
   log.Fatalf("unhandled response type: %T", c)
}

Since you seem to control the complete list of types which can be unesrialized, you can use a type swicth :

swich v := c.(type) {
case *ohlcResponse:
   // in this block, v is a *ohlcRrsponse
case *heartBeatResponse:
   // in this block, v is a *heartBeatResponse
case *serverConnectionStatusResponse:
   // in this block, v is a *serverConnectionStatus
case *ohlcSubscriptionResponse:
   // in this block, v is a *ohlcSubscriptionResponse

default:
   // choose some way to report unhandled types:
   log.Fatalf("unhandled response type: %T", c)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文