예제 #1
0
        private async Task CommandStreamLoop(CommandHanderStreamContext ctx)
        {
            lock (_streams)
                _streams.Add(ctx.StreamId, ctx);
            ctx.InitEvent.Set();
            try
            {
                while (!_disposed)
                {
                    int     commandId;
                    int     tag;
                    int     size;
                    Command command;
                    (command, commandId, tag, size) = await ctx.Stream.ReadCommand().ConfigureAwait(false);

                    if (command == null)
                    {
                        Log.InfoFormat($"End of stream {ctx.StreamId}");
                        return;
                    }
                    _stats.StatReceive(size);
                    if (tag == 0)
                    {
                        var handle = GetHandlerMethod(command.GetType());
                        ThreadPool.QueueUserWorkItem((_) => handle.Invoke(this, new object[] { command, ctx.Stream, commandId, ctx.Stream.Id }));
                    }
                    else
                    {
                        var uId = CommandStream.GetCommandId(ctx.StreamId, tag);
                        lock (_unansweredRequests)
                        {
                            RequestBase req;
                            if (!_unansweredRequests.TryGetValue(uId, out req))
                            {
                                Log.Warn($"No unanswered requests with tag {tag}. Uniq command id: {uId}");
                            }
                            else
                            {
                                req.SetResult(command, ctx.StreamId);
                                _unansweredRequests.TryRemove(uId, out var t);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
                ctx.Stream.Close();
                lock (_streams)
                    _streams.Remove(ctx.StreamId);
                OnClose(ctx.StreamId);
            }
        }
예제 #2
0
        public int AddSource(TcpClient client)
        {
            var streamId = Interlocked.Increment(ref _streamCount);
            var s        = new CommandStream(streamId, client, _serializer);
            var ctx      = new CommandHanderStreamContext
            {
                StreamId  = streamId,
                Stream    = s,
                InitEvent = new ManualResetEventSlim(false)
            };
            var t = CommandStreamLoop(ctx);

            _tasks.Add(t);
            ctx.InitEvent.Wait();
            return(streamId);
        }