Пример #1
0
        private async ValueTask ReceiveMessage(Server server, ClientMessageConnection connection, ClientMessage message)
        {
            HConsole.WriteLine(this, "Respond");
            var text = Encoding.UTF8.GetString(message.FirstFrame.Bytes);

#if NETSTANDARD2_1
            var responseText = text switch
            {
                "a" => "alpha",
                "b" => "bravo",
                _ => "??"
            };
#else
            var responseText =
                text == "a" ? "alpha" :
                text == "b" ? "bravo" :
                "??";
#endif
            // this is very basic stuff and does not respect HZ protocol
            // the 64-bytes header is nonsense etc
            var response = new ClientMessage()
                           .Append(new Frame(new byte[64])) // header stuff
                           .Append(new Frame(Encoding.UTF8.GetBytes(responseText)));

            response.CorrelationId = message.CorrelationId;
            response.MessageType   = 0x1; // 0x00 means exception

            // send in one fragment, set flags
            response.Flags |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;

            await connection.SendAsync(response).CfAwait();

            HConsole.WriteLine(this, "Responded");
        }
Пример #2
0
        private async Task HandleAsync(Server server, ClientMessageConnection connection, ClientMessage requestMessage,
                                       Func <Server, ClientMessageConnection, ClientMessage, ValueTask> handler)
        {
            var correlationId = requestMessage.CorrelationId;

            async Task SendResponseAsync(ClientMessage response)
            {
                response.CorrelationId = requestMessage.CorrelationId;
                response.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                await connection.SendAsync(response).CfAwait();
            }

            async Task SendEventAsync(ClientMessage eventMessage, long correlationId)
            {
                eventMessage.CorrelationId = correlationId;
                eventMessage.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                await connection.SendAsync(eventMessage).CfAwait();
            }

            switch (requestMessage.MessageType)
            {
            // handle authentication
            case ClientAuthenticationServerCodec.RequestMessageType:
            {
                var request         = ClientAuthenticationServerCodec.DecodeRequest(requestMessage);
                var responseMessage = ClientAuthenticationServerCodec.EncodeResponse(
                    0, server.Address, server.MemberId, SerializationService.SerializerVersion,
                    "4.0", 1, server.ClusterId, false);
                await SendResponseAsync(responseMessage).CfAwait();

                break;
            }

            // handle events
            case ClientAddClusterViewListenerServerCodec.RequestMessageType:
            {
                var request         = ClientAddClusterViewListenerServerCodec.DecodeRequest(requestMessage);
                var responseMessage = ClientAddClusterViewListenerServerCodec.EncodeResponse();
                await SendResponseAsync(responseMessage).CfAwait();

                _ = Task.Run(async() =>
                    {
                        await Task.Delay(500).CfAwait();
                        var eventMessage = ClientAddClusterViewListenerServerCodec.EncodeMembersViewEvent(1, new[]
                        {
                            new MemberInfo(server.MemberId, server.Address, new MemberVersion(4, 0, 0), false, new Dictionary <string, string>()),
                        });
                        await SendEventAsync(eventMessage, correlationId).CfAwait();
                    });
                break;
            }

            // handle others
            default:
                await handler(server, connection, requestMessage).CfAwait();

                break;
            }
        }
        public void ArgumentExceptions()
        {
            var endpoint = NetworkAddress.Parse("127.0.0.1:11000").IPEndPoint;
            var s        = new ClientSocketConnection(1, endpoint, new NetworkingOptions(), new SslOptions(), new NullLoggerFactory());
            var c        = new ClientMessageConnection(s, new NullLoggerFactory());

            Assert.ThrowsAsync <ArgumentNullException>(async() => _ = await c.SendAsync(null));
        }
        public async Task OnReceiveMessage()
        {
            var endpoint = NetworkAddress.Parse("127.0.0.1:11000").IPEndPoint;
            var s        = new ClientSocketConnection(1, endpoint, new NetworkingOptions(), new SslOptions(), new NullLoggerFactory());
            var c        = new ClientMessageConnection(s, new NullLoggerFactory())
            {
                OnReceiveMessage = OnReceiveMessageNotImplemented
            };

            Assert.That(c.OnReceiveMessage, Is.Not.Null);
            Assert.Throws <NotImplementedException>(() => c.OnReceiveMessage(default, default));
Пример #5
0
 private void ReceiveMessage(ClientMessageConnection connection, ClientMessage requestMessage)
 {
     lock (_handlerLock)
     {
         if (_handlerTask == null)
         {
             _handlerTask = _handler(this, connection, requestMessage).AsTask();
         }
         else
         {
             _handlerTask = _handlerTask.ContinueWith(_ => _handler(this, connection, requestMessage).AsTask()).Unwrap();
         }
     }
 }
Пример #6
0
        private async Task ReceiveMessageAsync(ClientMessageConnection connection, ClientMessage requestMessage)
        {
            var correlationId = requestMessage.CorrelationId;

            switch (requestMessage.MessageType)
            {
            // handle authentication
            case ClientAuthenticationServerCodec.RequestMessageType:
            {
                var request         = ClientAuthenticationServerCodec.DecodeRequest(requestMessage);
                var responseMessage = ClientAuthenticationServerCodec.EncodeResponse(
                    0, _address, _memberId, SerializationService.SerializerVersion,
                    "4.0", 1, _clusterId, false);
                await SendAsync(connection, responseMessage, correlationId).CAF();

                break;
            }

            // handle events
            case ClientAddClusterViewListenerServerCodec.RequestMessageType:
            {
                var request         = ClientAddClusterViewListenerServerCodec.DecodeRequest(requestMessage);
                var responseMessage = ClientAddClusterViewListenerServerCodec.EncodeResponse();
                await SendAsync(connection, responseMessage, correlationId).CAF();

                _ = Task.Run(async() =>
                    {
                        await Task.Delay(500).CAF();
                        var eventMessage = ClientAddClusterViewListenerServerCodec.EncodeMembersViewEvent(1, new[]
                        {
                            new MemberInfo(_memberId, _address, new MemberVersion(4, 0, 0), false, new Dictionary <string, string>()),
                        });
                        await SendAsync(connection, eventMessage, correlationId).CAF();
                    });
                break;
            }

            // handle others
            default:
                await _handler(this, connection, requestMessage).CAF();

                break;
            }
        }
Пример #7
0
        /// <summary>
        /// Handles new connections.
        /// </summary>
        /// <param name="serverConnection">The new connection.</param>
        private void AcceptConnection(ServerSocketConnection serverConnection)
        {
            // the connection we receive is not wired yet
            // must wire it properly before accepting

            lock (_openLock)
            {
                if (!_open)
                {
                    throw new InvalidOperationException("Cannot accept connections (closed).");
                }

                var messageConnection = new ClientMessageConnection(serverConnection, _loggerFactory)
                {
                    OnReceiveMessage = ReceiveMessage
                };
                HConsole.Configure(x => x.Configure(messageConnection).SetIndent(28).SetPrefix("SVR.MSG".Dot(_hcname)));
                serverConnection.OnShutdown = SocketShutdown;
                serverConnection.ExpectPrefixBytes(3, ReceivePrefixBytes);
                serverConnection.Accept();
                _connections[serverConnection.Id] = serverConnection;
            }
        }
        private async ValueTask ServerHandler(Server s, ClientMessageConnection conn, ClientMessage msg)
        {
            async Task SendResponseAsync(ClientMessage response)
            {
                response.CorrelationId = msg.CorrelationId;
                response.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                await conn.SendAsync(response).CfAwait();
            }

            async Task SendEventAsync(ClientMessage eventMessage, long correlationId)
            {
                eventMessage.CorrelationId = correlationId;
                eventMessage.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                await conn.SendAsync(eventMessage).CfAwait();
            }

            async Task SendErrorAsync(RemoteError error, string message)
            {
                var errorHolders = new List <ErrorHolder>
                {
                    new ErrorHolder(error, "?", message, Enumerable.Empty <StackTraceElement>())
                };
                var response = ErrorsServerCodec.EncodeResponse(errorHolders);

                await SendResponseAsync(response).CfAwait();
            }

            var state   = (ServerState)s.State;
            var address = s.Address;

            const int partitionsCount = 2;

            switch (msg.MessageType)
            {
            // must handle auth
            case ClientAuthenticationServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) Authentication");
                var authRequest  = ClientAuthenticationServerCodec.DecodeRequest(msg);
                var authResponse = ClientAuthenticationServerCodec.EncodeResponse(
                    0, address, s.MemberId, SerializationService.SerializerVersion,
                    "4.0", partitionsCount, s.ClusterId, false);
                await SendResponseAsync(authResponse).CfAwait();

                break;
            }

            // must handle events
            case ClientAddClusterViewListenerServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) AddClusterViewListener");
                var addRequest  = ClientAddClusterViewListenerServerCodec.DecodeRequest(msg);
                var addResponse = ClientAddClusterViewListenerServerCodec.EncodeResponse();
                await SendResponseAsync(addResponse).CfAwait();

                _ = Task.Run(async() =>
                    {
                        await Task.Delay(500).CfAwait();

                        const int membersVersion = 1;
                        var memberVersion        = new MemberVersion(4, 0, 0);
                        var memberAttributes     = new Dictionary <string, string>();
                        var membersEventMessage  = ClientAddClusterViewListenerServerCodec.EncodeMembersViewEvent(membersVersion, new[]
                        {
                            new MemberInfo(state.MemberIds[0], state.Addresses[0], memberVersion, false, memberAttributes),
                            new MemberInfo(state.MemberIds[1], state.Addresses[1], memberVersion, false, memberAttributes),
                        });
                        await SendEventAsync(membersEventMessage, msg.CorrelationId).CfAwait();

                        await Task.Delay(500).CfAwait();

                        const int partitionsVersion = 1;
                        var partitionsEventMessage  = ClientAddClusterViewListenerServerCodec.EncodePartitionsViewEvent(partitionsVersion, new[]
                        {
                            new KeyValuePair <Guid, IList <int> >(state.MemberIds[0], new List <int> {
                                0
                            }),
                            new KeyValuePair <Guid, IList <int> >(state.MemberIds[1], new List <int> {
                                1
                            }),
                        });
                        await SendEventAsync(partitionsEventMessage, msg.CorrelationId).CfAwait();
                    });

                break;
            }

            // create object
            case ClientCreateProxyServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) CreateProxy");
                var createRequest  = ClientCreateProxyServerCodec.DecodeRequest(msg);
                var createResponse = ClientCreateProxiesServerCodec.EncodeResponse();
                await SendResponseAsync(createResponse).CfAwait();

                break;
            }

            // subscribe
            case MapAddEntryListenerServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) AddEntryListener");
                var addRequest = MapAddEntryListenerServerCodec.DecodeRequest(msg);
                state.Subscribed = true;
                state.SubscriptionCorrelationId = msg.CorrelationId;
                var addResponse = MapAddEntryListenerServerCodec.EncodeResponse(state.SubscriptionId);
                await SendResponseAsync(addResponse).CfAwait();

                break;
            }

            // unsubscribe
            // server 1 removes on first try, server 2 removes on later tries
            case MapRemoveEntryListenerServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) RemoveEntryListener");
                var removeRequest = MapRemoveEntryListenerServerCodec.DecodeRequest(msg);
                var removed       = state.Subscribed && removeRequest.RegistrationId == state.SubscriptionId;
                removed &= state.Id == 0 || state.UnsubscribeCount++ > 0;
                if (removed)
                {
                    state.Subscribed = false;
                }
                HConsole.WriteLine(this, $"(server{state.Id}) Subscribed={state.Subscribed}");
                var removeResponse = MapRemoveEntryListenerServerCodec.EncodeResponse(removed);
                await SendResponseAsync(removeResponse).CfAwait();

                break;
            }

            // add to map & trigger event
            case MapSetServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) Set");
                var setRequest  = MapSetServerCodec.DecodeRequest(msg);
                var setResponse = MapSetServerCodec.EncodeResponse();
                await SendResponseAsync(setResponse).CfAwait();

                HConsole.WriteLine(this, $"(server{state.Id}) Subscribed={state.Subscribed}");

                if (state.Subscribed)
                {
                    HConsole.WriteLine(this, $"(server{state.Id}) Trigger event");
                    var key        = setRequest.Key;
                    var value      = setRequest.Value;
                    var addedEvent = MapAddEntryListenerServerCodec.EncodeEntryEvent(key, value, value, value, (int)MapEventTypes.Added, state.SubscriptionId, 1);
                    await SendEventAsync(addedEvent, state.SubscriptionCorrelationId).CfAwait();
                }
                break;
            }

            // unexpected message = error
            default:
            {
                // RemoteError.Hazelcast or RemoteError.RetryableHazelcast
                var messageName = MessageTypeConstants.GetMessageTypeName(msg.MessageType);
                await SendErrorAsync(RemoteError.Hazelcast, $"MessageType {messageName} (0x{msg.MessageType:X}) not implemented.").CfAwait();

                break;
            }
            }
        }
Пример #9
0
 protected async Task SendAsync(ClientMessageConnection connection, ClientMessage eventMessage, long correlationId)
 {
     eventMessage.CorrelationId = correlationId;
     eventMessage.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
     await connection.SendAsync(eventMessage).CfAwait();
 }