getting channel value from a webscoket client

Issue

I’m running a websocket client and want to pass the response(s) from the client to a channel that i can work with in my main file. Currently, the channel just returns a nil value once and then nothing else. I seem to have an issue when passing a value to the channel. Any help? Here is what I’ve done so far

package main

import (
    "context"
    "fmt"
    "kraken_client/stored_data"
    "kraken_client/ws_client"
    "os"
    "os/signal"
    "strings"
    "sync"
    "syscall"
)

func main() {
    // check if in production or testing mode & find base curency
    var testing bool = true
    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)
    }

    // listen to websocket connections
    ch := make(chan interface{})
    wg.Add(1)
    go pubSocket.PubListen(ctx, &wg, ch, testing)

    // subscribe to a stream
    pubSocket.SubscribeToOHLC(pairs, OHLCinterval)

    go func() {
        for c := range ch {
            fmt.Println(c)
        }
    }()

    <-comms
    cancel()
    wg.Wait()
    defer close(ch)
}

Here is how the PubListen function works

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) {
        //log.Println(message)
        res = pubJsonDecoder(message, testing) // this function decodes the message and returns an interface
        log.Println(res) // this is printing the correctly decoded value.

    }

    ch <- res
    log.Println(res) // does not print a value
    log.Println(ch) // does not print a value

    <-ctx.Done()
    log.Println("closing public socket")
    return
}

What am I doing wrong?

Solution

The code in the question executes the statement ch <- res once from PubListen before the res is set by the OnTextMessage function.

To send a value to ch on each message, move the line ch <- res to the OnTextMessage function. That function is called once for each message.

func (socket *Socket) PubListen(ctx context.Context, wg *sync.WaitGroup, ch chan interface{}, testing bool) {
    defer wg.Done()
    defer socket.Close()
    socket.OnTextMessage = func(message string, socket Socket) {
        res := pubJsonDecoder(message, testing)
        ch <- res
        log.Println(res)
    }
    <-ctx.Done()
    log.Println("closing public socket")
    return
}

Answered By – RedBlue

Answer Checked By – Gilberto Lyons (GoLangFix Admin)

Leave a Reply

Your email address will not be published.