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