Esempio n. 1
0
        public async Task Serve(Session session)
        {
            // Yield to get rid of the sync section.
            await Task.Yield();

            if (_tls != null)
            {
                await _tls.Stream.AuthenticateAsServerAsync(_tls.Certificate);
            }

            var preamble = new Preamble
            {
                InstanceId   = _config.InstanceId,
                MessageIdMap = _dispatcher
                               .MessageMap
                               .Enumerate()
                               .Select(entry => {
                    string typeName    = entry.Type.AssemblyQualifiedName;
                    (long lo, long hi) = MessageName.GetHash(typeName);

                    _logger.Trace("Hash {0} calculated for the message type '{1}'.", MessageName.HashToString(lo, hi), typeName);

                    return(new MessageIdMapEntry()
                    {
                        MessageTypeHashLo = lo,
                        MessageTypeHashHi = hi,
                        MessageId = entry.Id
                    });
                })
                               .ToArray(),
                RequestResponseMap = _dispatcher
                                     .GetRequestResponseMap()
                                     .Select(entry => new RequestResponseMapEntry {
                    RequestId   = entry.RequestId,
                    ResponsetId = entry.ResponseId
                })
                                     .ToArray()
            };

            await _messageWriter.Write(preamble);

            _hostStatusSenderTask = SendHostStatus();

            while (true)
            {
                var requestHeader = await _messageReader.Read <RequestHeader>();

                if (requestHeader.MessageId == 0)
                {
                    _requestLogger.Log(requestHeader, null, false);
                    break;
                }

                session.SetRequestNo(requestHeader.RequestNo);

                object?requestBody = null;
                if ((requestHeader.Flags & RequestFlags.NoBody) == RequestFlags.None)
                {
                    Type requestType = _dispatcher.MessageMap.GetMessageTypeById(requestHeader.MessageId);
                    requestBody = await _messageReader.Read(requestType);
                }

                _requestLogger.Log(requestHeader, requestBody, false);

                _counters.PendingProcessing.Increment();

                Task requestHandlerTask;
                if ((requestHeader.Flags & RequestFlags.NoResponse) == RequestFlags.None)
                {
                    if ((requestHeader.Flags & RequestFlags.OpenChannel) == RequestFlags.OpenChannel)
                    {
                        requestHandlerTask = HandleChannel(requestHeader, requestBody);
                    }
                    else
                    {
                        requestHandlerTask = HandleWithResponse(requestHeader, requestBody);
                    }
                }
                else
                {
                    requestHandlerTask = HandleWithoutResponse(requestHeader, requestBody);
                }

                _requestHanderTasks.TryAdd(requestHandlerTask, null);

                CompleteRequestHandlerTask(requestHeader.RequestNo, requestHandlerTask);
            }

            foreach (Task requestHandlerTask in _requestHanderTasks.Keys.ToArray())
            {
                await requestHandlerTask;
            }
        }