Bir mesaj gönderme ve alma süreci, TCP ve WebSocket standartları arasında farklılık gösterir. Aşağıda, bu süreci her iki bağlantı türü için ayrıntılı olarak açıklıyoruz.
Bir TCP bağlantısı aracılığıyla mesaj göndermek için aşağıdakileri yapın:
Seçtiğiniz programlama dili için resmi Google Protocol Buffer SDK'sını kullanarak Protobuf mesajını bir bayt dizisine (Protobuf kodlamasını kullanarak) dönüştürün.
adımda oluşturulan dizinin uzunluğunu alın. Bu tam sayıdan yeni bir bayt dizisi oluşturun. Yeni bayt dizisini ters çevirin.
Yeni bayt dizisini ve orijinal Protobuf mesajını içeren bayt dizisini birleştirin.
Birleştirilmiş diziyi bağlantı akışına gönderin.
Aşağıdaki örnekler, bu adımların resmi Open API SDK'larında nasıl gerçekleştirildiğini göstermektedir.
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 örneği
Twisted kullanarak, Python örneği C# örneğiyle neredeyse aynı işlemleri gerçekleştirir. client.send(request) aşağıdaki gibi açıklanabilir.
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
Mesajı göndermek için Python SDK'sı Protocol.transport.write() yöntemini kullanır.
Tüm Open API SDK'ları asenkron yürütmeye dayanır, yani mesajların gelmesini beklemezler, bunun yerine dinamik olarak gelen mesajlara tepki verirler. Sonuç olarak, mesaj almak genellikle olay işleyicileri aracılığıyla yapılır.
Bir mesajı okumak için, mesaj göndermek için gereken adımları tersine çeviren bir dizi eylem gerçekleştirmeniz gerekecektir.
Bir bayt dizisinin ilk dört baytını alın (unutmayın, bunlar mesaj uzunluğunu belirtir). Bu dört baytı ters çevirin ve bir tam sayıya dönüştürün.
adımda elde ettiğiniz tam sayı olan X kadar baytı bir akıştan okuyun.
Mesajı geçerli bir ProtoMessage'a seri durumdan çıkarmak için Google Protobuf SDK'sını kullanın.
ProtoMessage nesnesinin payloadType alanını kullanarak gerçek türünü bulun. Google Protobuf SDK aracılığıyla, ProtoMessage'ı gerekli ProtoOA... türünde bir nesneye dönüştürün.
Aşağıdaki kod parçacıkları, resmi Open API SDK'larının mesaj okumaya nasıl yaklaştığını göstermektedir.
_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 örneği
Python örneğinde, mesaj alırken baytlarla yapılan tüm işlemler, aşağıda gösterildiği gibi dataReceived() yöntemi tarafından ele alınır.
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)
Bir WebSocket bağlantısı üzerinden mesaj göndermek için aşağıdaki eylemleri gerçekleştirin:
Mesajı uygun herhangi bir veri biçimine (örneğin, bir dize) seri hale getirin.
Seri hale getirilmiş mesajı gönderme kuyruğunuza ekleyin.
Aşağıdaki örnekler, bu eylemlerin resmi Open API SDK'larında nasıl gerçekleştirildiğini göstermektedir.
C# SDK'sı, Websocket.Client paketinin bir parçası olan WebsocketClient sınıfını kullanır. Aşağıda gösterildiği gibi, WebsocketClient.Send() yöntemi aşağıdaki gibi çalışır.
Bir WebSocket bağlantısı üzerinden mesaj almak için aşağıdakileri yapın:
cTrader arka ucundan alınan verileri alın.
Verileri geçerli bir Protobuf mesajına seri durumdan çıkarın.
Bunun resmi Open API SDK'larında nasıl yapıldığına dair bir örnek için aşağıdaki kod parçacıklarına bakın.
Mesaj almak için, bir WebsocketClient'ın, istemcinin yeni bir mesajı kabul ettiğinde ne yapacağını yöneten bir geri arama işlevine abone olması gerekir.