Proses menghantar dan menerima mesej berbeza antara piawaian TCP dan WebSocket. Di bawah, kami menerangkan proses ini secara terperinci untuk kedua-dua jenis sambungan.
Untuk menghantar mesej melalui sambungan TCP, lakukan yang berikut:
Tukar mesej Protobuf kepada tatasusunan bait (menggunakan penyiratan Protobuf) dengan menggunakan SDK Google Protocol Buffer rasmi untuk bahasa pengaturcaraan pilihan anda.
Dapatkan panjang tatasusunan yang dicipta semasa langkah 1. Cipta tatasusunan bait baharu dari integer ini. Balikkan tatasusunan bait baharu.
Gabungkan tatasusunan bait baharu dan tatasusunan bait yang mengandungi mesej Protobuf asal.
Hantar tatasusunan yang digabungkan ke aliran sambungan.
Contoh di bawah menunjukkan bagaimana langkah-langkah ini dilakukan dalam SDK Open API rasmi.
client=Client(EndPoints.PROTOBUF_LIVE_HOSTifhostType.lower()=="live"elseEndPoints.PROTOBUF_DEMO_HOST,EndPoints.PROTOBUF_PORT,TcpProtocol)request=ProtoOAApplicationAuthReq()# Can be any messagedeferred=client.send(request)
Python example
Menggunakan Twisted, contoh Python melakukan hampir operasi yang sama seperti C#. client.send(request) boleh dijelaskan seperti berikut.
123
request=ProtoOAApplicationAuthReq()# Can be any messagerequestAsString=request.SerializeToString()# This method is a part of the Google Protobuf SDKrequestAsInt32String=struct.pack("!H",len(requestAsString))# The message is concatenated with the reversed array
Untuk menghantar mesej, SDK Python menggunakan kaedah Protocol.transport.write().
Semua SDK Open API bergantung pada pelaksanaan asinkron, bermaksud mereka tidak menunggu mesej tiba tetapi sebaliknya bertindak balas terhadap mesej yang tiba secara dinamik. Akibatnya, menerima mesej biasanya dilakukan melalui pengendali acara
Untuk membaca mesej, anda perlu melakukan urutan tindakan yang membalikkan langkah yang diperlukan untuk menghantar mesej.
Terima empat bait pertama dari tatasusunan bait (ingat, mereka menandakan panjang mesej). Balikkan empat bait ini dan tukarkannya kepada integer.
Baca X jumlah bait dari aliran di mana X adalah integer yang anda dapatkan dalam langkah 1.
Gunakan SDK Google Protobuf untuk menyahserialkan mesej menjadi ProtoMessage yang sah.
Gunakan medan payloadType dari objek ProtoMessage untuk mencari jenis sebenarnya. Melalui SDK Google Protobuf, tukar ProtoMessage kepada objek jenis ProtoOA... yang diperlukan.
Coretan kod di bawah menunjukkan bagaimana SDK Open API rasmi mendekati pembacaan mesej.
_tcpClient=newTcpClient{LingerState=newLingerOption(enable:true,10)};await_tcpClient.ConnectAsync(Host,Port).ConfigureAwait(continueOnCapturedContext:false);SslStream_sslStream=newSslStream(_tcpClient.GetStream(),leaveInnerStreamOpen:false);await_sslStream.AuthenticateAsClientAsync(Host).ConfigureAwait(continueOnCapturedContext:false);privateasyncvoidReadTcp(CancellationTokencancellationToken){byte[]dataLength=newbyte[4];byte[]data=null;try{while(!IsDisposed){intnum=0;do{intcount=dataLength.Length-num;intnum2=num;num=num2+await_sslStream.ReadAsync(dataLength,num,count,cancellationToken).ConfigureAwait(continueOnCapturedContext:false);if(num==0){thrownewInvalidOperationException("Remote host closed the connection");}}while(num<dataLength.Length);intlength=GetLength(dataLength);if(length<=0){continue;}data=ArrayPool<byte>.Shared.Rent(length);num=0;do{intcount2=length-num;intnum2=num;num=num2+await_sslStream.ReadAsync(data,num,count2,cancellationToken).ConfigureAwait(continueOnCapturedContext:false);if(num==0){thrownewInvalidOperationException("Remote host closed the connection");}}while(num<length);ProtoMessageprotoMessage=ProtoMessage.Parser.ParseFrom(data,0,length);ArrayPool<byte>.Shared.Return(data);OnNext(protoMessage);}}catch(ExceptioninnerException){if(data!=null){ArrayPool<byte>.Shared.Return(data);}ReceiveExceptionexception=newReceiveException(innerException);OnError(exception);}}privateintGetLength(byte[]lengthBytes){Span<byte>span=lengthBytes.AsSpan();span.Reverse();returnBitConverter.ToInt32(span);}
Python example
Dalam contoh Python, semua operasi dengan bait pada penerimaan mesej dikendalikan oleh kaedah dataReceived() seperti yang ditunjukkan di bawah.
1 2 3 4 5 6 7 8 910111213141516
defdataReceived(self,recd):""" Convert int prefixed strings into calls to stringReceived. """self.recvd=self.recvd+recdwhilelen(self.recvd)>=self.prefixLengthandnotself.paused:length,=struct.unpack(self.structFormat,self.recvd[:self.prefixLength])iflength>self.MAX_LENGTH:self.lengthLimitExceeded(length)returniflen(self.recvd)<length+self.prefixLength:breakpacket=self.recvd[self.prefixLength:length+self.prefixLength]self.recvd=self.recvd[length+self.prefixLength:]self.stringReceived(packet)
Untuk menghantar mesej melalui sambungan WebSocket, lakukan tindakan berikut:
Serialkan mesej ke dalam format data yang sesuai (contohnya, rentetan).
Tambahkan mesej yang diserialkan ke dalam barisan hantar anda.
Contoh di bawah menunjukkan bagaimana tindakan ini dilakukan dalam SDK Open API rasmi.
SDK C# menggunakan kelas WebsocketClient yang merupakan sebahagian daripada pakej Websocket.Client. Seperti yang ditunjukkan di bawah, kaedah WebsocketClient.Send() berfungsi seperti berikut.
Untuk menerima mesej melalui sambungan WebSocket, lakukan yang berikut:
Ambil data yang diterima dari backend cTrader.
Sahserialkan data menjadi mesej Protobuf yang sah.
Untuk ilustrasi bagaimana ini dilakukan dalam SDK Open API rasmi, lihat coretan di bawah.
Untuk menerima mesej, WebsocketClient perlu dilanggan kepada fungsi panggilan balik yang mengendalikan apa yang dilakukan klien pada penerimaan mesej baru.