/// <summary>Push message async to multiple client
        /// </summary>
        public async ValueTask PushMultipleAsync(RequestPush request, Func <ISocketSession, bool> predicate)
        {
            if (_boundChannel == null)
            {
                throw new ArgumentNullException("Socket server should run first!");
            }

            var sessions = _sessionFactory.GetSessions(predicate);

            if (!sessions.Any())
            {
                throw new ArgumentException("Can't find any session!");
            }

            foreach (var session in sessions)
            {
                if (_channelDict.TryGetValue(session.SessionId, out IChannel channel))
                {
                    var sequence      = Interlocked.Increment(ref _sequence);
                    var pushReqPacket = new PushReqPacket()
                    {
                        Sequence = sequence,
                        PushType = PushType.NoReply,
                        Code     = request.Code,
                        Body     = request.Body,
                    };
                    await channel.WriteAndFlushAsync(pushReqPacket);
                }
                else
                {
                    _logger.LogError("Can't find channel by session id:{0}", session.SessionId);
                }
            }
        }
        /// <summary>Push message async
        /// </summary>
        public async ValueTask <ResponsePush> PushAsync(RequestPush request, string sessionId, int timeoutMillis = 5000)
        {
            if (_boundChannel == null)
            {
                throw new ArgumentNullException("Socket server should run first!");
            }

            //Get channel from dict
            if (!_channelDict.TryGetValue(sessionId, out IChannel channel))
            {
                throw new ArgumentNullException("Can't find channel by session id {0}.", sessionId);
            }

            var sequence      = Interlocked.Increment(ref _sequence);
            var pushReqPacket = new PushReqPacket()
            {
                Sequence = sequence,
                PushType = PushType.Reply,
                Code     = request.Code,
                Body     = request.Body,
            };
            var tcs        = new TaskCompletionSource <ResponsePush>();
            var pushFuture = new PushFuture(request.Code, timeoutMillis, tcs);

            if (!_pushFutureDict.TryAdd(sequence, pushFuture))
            {
                throw new Exception($"Add 'PushFuture' failed. Sequence:{sequence}");
            }
            await channel.WriteAndFlushAsync(pushReqPacket);

            return(await tcs.Task);
        }
Beispiel #3
0
        public ValueTask <ResponsePush> HandlePushAsync(RequestPush request)
        {
            var timeRequestMessage = _binarySerializer.Deserialize <TimeRequestMessage>(request.Body);

            var timeResponseMessage = new TimeResponseMessage()
            {
                CreateTime = timeRequestMessage.CreateTime,
                HandleTime = DateTime.Now,
                Content    = Encoding.UTF8.GetBytes($"Hello Server!")
            };

            var responsePush = new ResponsePush()
            {
                Code = request.Code,
                Body = _binarySerializer.Serialize(timeResponseMessage)
            };

            _performanceService.IncrementKeyCount("PushHandleAsync", (DateTime.Now - timeRequestMessage.CreateTime).TotalMilliseconds);
            return(new ValueTask <ResponsePush>(responsePush));
        }
Beispiel #4
0
        /// <summary>Handle the 'ReqPushPacket' received from server
        /// </summary>
        private async ValueTask HandleReqPushPacketAsync()
        {
            var pushReqPacket = await _reqPushChannel.Reader.ReadAsync(_cts.Token);

            if (!_pushMessageHandlerDict.TryGetValue(pushReqPacket.Code, out IPushMessageHandler handler))
            {
                _logger.LogWarning("Can't find any 'IPushMessageHandler' from the dict by code '{0}'! ", pushReqPacket.Code);
                return;
            }

            var request = new RequestPush()
            {
                Code = pushReqPacket.Code,
                Body = pushReqPacket.Body
            };

            var response = await handler.HandlePushAsync(request);

            switch (pushReqPacket.PushType)
            {
            case PushType.NoReply:
            case PushType.Unknow:
                break;

            case PushType.Reply:
                var respPushMessagePacket = new PushRespPacket()
                {
                    Sequence = pushReqPacket.Sequence,
                    PushType = pushReqPacket.PushType,
                    Code     = response.Code,
                    Body     = response.Body
                };
                await _clientChannel.WriteAndFlushAsync(respPushMessagePacket);

                break;

            default:
                break;
            }
        }