FRAME_TOO_LONG"!Frame size exceeds allowed limit.

Created at 04 Nov 2024, 15:00
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
AL

alshdavid

Joined 27.10.2024

FRAME_TOO_LONG"!Frame size exceeds allowed limit.
04 Nov 2024, 15:00


I have tried implementing a client in Nodejs and Golang however both clients are unable to send the ptotobuf auth request

Nodejs:

const root = protobuf.loadSync(path.join(__dirname, '..', 'protobuf', 'OpenApiMessages.proto'))
const ProtoOAApplicationAuthReq = root.lookupType("ProtoOAApplicationAuthReq");

const client = new net.Socket();

await new Promise<void>(res => client.connect(5035, "demo.ctraderapi.com", res))
console.log('Connected')

const socket = new tls.TLSSocket(client)

const msg = ProtoOAApplicationAuthReq.create({
  clientId: CLIENT_ID,
  clientSecret: CLIENT_SECRET,
});

let bytes = ProtoOAApplicationAuthReq.encode(msg).finish()
socket.write(bytes)

socket.on('data', function(data) {
  console.log('Received: ' + data);
});

This occurs with or without the LE length header

function len(x: number) {
  return [x,(x<<8),(x<<16),(x<<24)].map(z=> z>>>24).reverse()
}

console.log(bytes.length)      // 110
console.log(len(bytes.length)) // [110, 0, 0, 0]

// +--------------------------+-----------------------------------------+  
// | Message Length (4 bytes) | Serialized ProtoMessage object (byte[]) |  
// +--------------------------+-----------------------------------------+  
//                            |<---------- Message Length ------------->|
const b = Buffer.from([...len(bytes.length),...bytes])

console.log(b)  // [110, 0, 0, 0, ...proto bytes]

socket.write(b)

Golang

func main() {
	var HOST string = "demo.ctraderapi.com"
	var PORT uint32 = 5035
	var CLIENT_ID string = "<x>"
	var CLIENT_SECRET string = "<x>"

	addr := fmt.Sprintf("%s:%d", HOST, PORT)
	tcpAddr, _ := net.ResolveTCPAddr("tcp", addr)
	iconn, _ := net.DialTCP("tcp", nil, tcpAddr)

	cfg := tls.Config{
		InsecureSkipVerify: true,
	}
	conn := tls.Client(iconn, &cfg)

	req := &openapi.ProtoOAApplicationAuthReq{
		PayloadType:  nil,
		ClientId:     &CLIENT_ID,
		ClientSecret: &CLIENT_SECRET,
	}

	out, _ := proto.Marshal(req)

	length := make([]uint8, 5)
	binary.LittleEndian.PutUint32(length[0:4], uint32(len(out)))
	out = append(length, out...)

	conn.Write(out)

	for {
		buffer := make([]byte, 1024)
		conn.Read(buffer)
		fmt.Print("Response:", string(buffer))
	}

}

@alshdavid
Replies

bolatfx
19 Nov 2024, 03:51

It seems possible with the following code.

package main

import (
	"crypto/tls"
	"demo/openapi"
	"encoding/binary"
	"fmt"
	"net"
	"time"

	"google.golang.org/protobuf/proto"
)

func main() {
	var HOST string = "live.ctraderapi.com"
	var PORT uint32 = 5035
	var CLIENT_ID string = "x"
	var CLIENT_SECRET string = "x"

	addr := fmt.Sprintf("%s:%d", HOST, PORT)
	tcpAddr, _ := net.ResolveTCPAddr("tcp", addr)
	iconn, _ := net.DialTCP("tcp", nil, tcpAddr)

	cfg := tls.Config{
		InsecureSkipVerify: true,
	}
	conn := tls.Client(iconn, &cfg)

	req := &openapi.ProtoOAApplicationAuthReq{
		PayloadType:  nil,
		ClientId:     &CLIENT_ID,
		ClientSecret: &CLIENT_SECRET,
	}

	out, _ := proto.Marshal(req)

	//add
	msg := openapi.ProtoMessage{
		Payload:     out,
		PayloadType: proto.Uint32(uint32(2100)),
	}

	data, _ := proto.Marshal(&msg)

	lentgh := make([]byte, 4)
	binary.BigEndian.PutUint32(lentgh, uint32(len(data)))
	//out = append(length, out...)

	conn.Write(lentgh)
	conn.Write(data)

	for {
		head := make([]byte, 4)
		_, err := conn.Read(head)
		if err != nil {
			return
		}
		data = make([]byte, binary.BigEndian.Uint32(head))
		_, err = conn.Read(data)
		if err != nil {
			return
		}
		var res openapi.ProtoMessage
		err = proto.Unmarshal(data, &res)
		if err != nil {
			return
		}
		//buffer := make([]byte, 1024)
		//conn.Read(buffer)
		fmt.Println("Response:", &res)
		time.Sleep(time.Second)
	}
}

@bolatfx

alshdavid
07 Dec 2024, 04:04

RE: FRAME_TOO_LONG"!Frame size exceeds allowed limit.

bolatfx said: 

[..]

Thanks, that worked for me!


@alshdavid