public unsafe Task <byte[]> SendMessageWithResponseAsync(byte[] message)
        {
            MessageBuff buff = new MessageBuff();

            fixed(byte *p = message)
            {
                buff.Buffer = p;
                buff.Length = (uint)message.Length;
                m_dispatcher(&buff);
            }

            try
            {
                int len = *(int *)buff.Buffer;
                if (len < 0)
                {
                    return(Task.FromException <byte[]>(new IOException("Error occured while processing the message")));
                }
                byte[] buf = new byte[len];
                fixed(byte *p = buf)
                {
                    Memory.memcpy(p, buff.Buffer + TrinityProtocol.SocketMsgHeader, (uint)len);
                }
                return(Task.FromResult(buf));
            }
            finally
            {
                Memory.free(buff.Buffer);
            }
        }
        public unsafe Task SendMessageAsync(byte[] message)
        {
            fixed(byte *p = message)
            {
                MessageBuff buff = new MessageBuff {
                    Buffer = p, Length = (uint)message.Length
                };

                m_dispatcher(&buff);
                try
                {
                    int errorCode = *(int *)buff.Buffer;
                    if (errorCode < 0)
                    {
                        return(Task.FromException(new IOException("Error occured while processing the message")));
                    }
                    else
                    {
                        return(Task.FromResult(0));
                    }
                }
                finally
                {
                    Memory.free(buff.Buffer);
                }
            }
        }
Exemplo n.º 3
0
        private unsafe void _PollImpl(TrinityMessage poll_req)
        {
            m_mod.SendMessage(m_client, poll_req.Buffer, poll_req.Size, out var poll_rsp);
            var sp = PointerHelper.New(poll_rsp.Buffer + poll_rsp.Offset);
            //HexDump.Dump(poll_rsp.ToByteArray());
            //Console.WriteLine($"poll_rsp.Size = {poll_rsp.Size}");
            //Console.WriteLine($"poll_rsp.Offset = {poll_rsp.Offset}");
            var payload_len = poll_rsp.Size - TrinityProtocol.TrinityMsgHeader;

            if (payload_len < sizeof(long) + sizeof(int))
            {
                throw new IOException("Poll response corrupted.");
            }
            var errno = *(sp.ip - 1);

            try
            {
                if (errno == 2)
                {
                    Log.WriteLine(LogLevel.Warning, $"{nameof(TrinityClient)}: server drops our connection. Registering again.");
                    RestartPolling();
                    return;
                }
                if (errno != 0)
                {
                    return;
                }

                var pctx    = *sp.lp++;
                var msg_len = *sp.ip++;
                if (msg_len < 0)
                {
                    return;              // no events
                }
                MessageBuff msg_buff = new MessageBuff {
                    Buffer = sp.bp, Length = (uint)msg_len
                };
                MessageDispatcher(&msg_buff);
                // !Note, void-response messages are not acknowledged.
                // Server would not be aware of client side error in this case.
                // This is by-design and an optimization to reduce void-response
                // message delivery latency. In streaming use cases this will be
                // very useful.
                try { if (pctx != 0)
                      {
                          _PostResponseImpl(pctx, &msg_buff);
                      }
                }
                finally { Memory.free(msg_buff.Buffer); }
            }
            finally
            {
                poll_rsp.Dispose();
            }
        }
        /// <inheritdoc/>
        public void SendMessage(byte *message, int size, out TrinityResponse response)
        {
            MessageBuff buff = new MessageBuff();

            buff.Buffer = message;
            buff.Length = (uint)size;

            LocalSendMessage(&buff);

            int response_len = *(int *)buff.Buffer;

            if (buff.Length != response_len + sizeof(int))
            {
                throw new IOException("Local message handler throws an exception.");
            }
            else
            {
                TrinityMessage rsp_message = new TrinityMessage(buff.Buffer, (int)buff.Length);
                response = new TrinityResponse(rsp_message);
            }
        }
        /// <inheritdoc/>
        public void SendMessage(byte *message, int size)
        {
            MessageBuff buff = new MessageBuff();

            buff.Buffer = message;
            buff.Length = (uint)size;

            LocalSendMessage(&buff);

            if (buff.Length != sizeof(TrinityErrorCode))
            {
                throw new IOException("LocalSendMessage responds with unexpected payload");
            }

            TrinityErrorCode msgProcessResult = *(TrinityErrorCode *)buff.Buffer;

            if (msgProcessResult != TrinityErrorCode.E_SUCCESS)
            {
                throw new IOException("Local message handler throws an exception.");
            }
        }