Skip to content

wsjson.Write write in a single frame always #315

Closed
@dar7man

Description

@dar7man

Hi,

I have a weird problem using this package with Binance WebSocket API. Just after I got stream subscription confirmation, connection is closed (code 1008). At the beginning I was thinking about contacting with Binance support, but then I tried the same code but using Gorilla WebSockets package and... it worked fine.

Here is code nhooyr package version (not working):

package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"time"

	"nhooyr.io/websocket"
	"nhooyr.io/websocket/wsjson"
)

type subscribeMessage struct {
	Method string   `json:"method"`
	Params []string `json:"params"`
	Id     int      `json:"id"`
}

func main() {
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
	defer cancel()

	c, _, err := websocket.Dial(ctx, "wss://stream.binance.com:9443/stream", nil)
	if err != nil {
		log.Println("dial:", err)
		return
	}
	defer func() { _ = c.Close(websocket.StatusNormalClosure, "") }()

	if err = wsjson.Write(ctx, c, subscribeMessage{
		Method: "SUBSCRIBE",
		Params: []string{"wavesbtc@depth@100ms"},
		Id:     100,
	}); err != nil {
		log.Println("write:", err)
		return
	}

	done := make(chan struct{})

	go func() {
		defer close(done)
		for {
			_, message, err := c.Read(ctx)
			if err != nil {
				log.Println("read:", err)
				return
			}
			log.Printf("recv: %s", message)
		}
	}()

	select {
	case <-interrupt:
		log.Println("interrupt")
	case <-done:
		return
	}

	err = c.Close(websocket.StatusNormalClosure, "")
	if err != nil {
		log.Println("write close:", err)
		return
	}
	<-done
}

And here is Gorilla version:

package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"time"

	"github.com/gorilla/websocket"
)

type subscribeMessage struct {
	Method string   `json:"method"`
	Params []string `json:"params"`
	Id     int      `json:"id"`
}

func main() {
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
	defer cancel()

	c, _, err := websocket.DefaultDialer.DialContext(ctx, "wss://stream.binance.com:9443/stream", nil)
	if err != nil {
		log.Println("dial:", err)
		return
	}
	defer func() { _ = c.Close() }()
	err = c.WriteJSON(subscribeMessage{
		Method: "SUBSCRIBE",
		Params: []string{"wavesbtc@depth@100ms"},
		Id:     100,
	})
	if err != nil {
		log.Println("write:", err)
		return
	}
	done := make(chan struct{})

	go func() {
		defer close(done)
		for {
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Println("read:", err)
				return
			}
			log.Printf("recv: %s", message)
		}
	}()

	select {
	case <-interrupt:
		log.Println("interrupt")
	case <-done:
		return
	}

	err = c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
	if err != nil {
		log.Println("write close:", err)
		return
	}
	<-done
	return
}

Any ideas what's wrong?
Thanks!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions