/// <summary> /// If the component is connected to LOC server, it sends a new GetNeighbourNodesByDistanceLocalRequest request /// to get fresh information about the profile server's neighborhood. /// </summary> public async Task RefreshLocAsync() { log.Trace("()"); if (locServerInitialized) { try { LocProtocolMessage request = client.MessageBuilder.CreateGetNeighbourNodesByDistanceLocalRequest(); if (await client.SendMessageAsync(request)) { log.Trace("GetNeighbourNodesByDistanceLocalRequest sent to LOC server to get fresh neighborhood data."); } else { log.Warn("Unable to send message to LOC server."); } } catch (Exception e) { log.Warn("Exception occurred: {0}", e.ToString()); } } else { log.Debug("LOC server not initialized yet, can not refresh."); } log.Trace("(-)"); }
/// <summary> /// Processing of a message received from a client. /// </summary> /// <param name="Client">TCP client who received the message.</param> /// <param name="IncomingMessage">Full ProtoBuf message to be processed.</param> /// <returns>true if the conversation with the client should continue, false if a protocol violation error occurred and the client should be disconnected.</returns> public async Task <bool> ProcessMessageAsync(ClientBase Client, IProtocolMessage IncomingMessage) { LocClient client = (LocClient)Client; LocProtocolMessage incomingMessage = (LocProtocolMessage)IncomingMessage; log.Debug("()"); bool res = false; try { log.Trace("Received message type is {0}, message ID is {1}.", incomingMessage.MessageTypeCase, incomingMessage.Id); switch (incomingMessage.MessageTypeCase) { case Message.MessageTypeOneofCase.Request: { LocProtocolMessage responseMessage = client.MessageBuilder.CreateErrorProtocolViolationResponse(incomingMessage); Request request = incomingMessage.Request; SemVer version = new SemVer(request.Version); log.Trace("Request type is {0}, version is {1}.", request.RequestTypeCase, version); switch (request.RequestTypeCase) { case Request.RequestTypeOneofCase.LocalService: { log.Trace("Local service request type is {0}.", request.LocalService.LocalServiceRequestTypeCase); switch (request.LocalService.LocalServiceRequestTypeCase) { case LocalServiceRequest.LocalServiceRequestTypeOneofCase.NeighbourhoodChanged: { responseMessage = await ProcessMessageNeighbourhoodChangedNotificationRequestAsync(client, incomingMessage); break; } default: log.Warn("Invalid local service request type '{0}'.", request.LocalService.LocalServiceRequestTypeCase); break; } break; } default: log.Warn("Invalid request type '{0}'.", request.RequestTypeCase); break; } if (responseMessage != null) { // Send response to client. res = await client.SendMessageAsync(responseMessage); if (res) { // If the message was sent successfully to the target, we close the connection only in case of protocol violation error. if (responseMessage.MessageTypeCase == Message.MessageTypeOneofCase.Response) { res = responseMessage.Response.Status != Status.ErrorProtocolViolation; } } } else { // If there is no response to send immediately to the client, // we want to keep the connection open. res = true; } break; } case Message.MessageTypeOneofCase.Response: { Response response = incomingMessage.Response; log.Trace("Response status is {0}, details are '{1}', response type is {2}.", response.Status, response.Details, response.ResponseTypeCase); // The only response we should ever receive here is GetNeighbourNodesByDistanceResponse in response to our refresh request that we do from time to time. bool isGetNeighbourNodesByDistanceResponse = (response.Status == Status.Ok) && (response.ResponseTypeCase == Response.ResponseTypeOneofCase.LocalService) && (response.LocalService.LocalServiceResponseTypeCase == LocalServiceResponse.LocalServiceResponseTypeOneofCase.GetNeighbourNodes); if (!isGetNeighbourNodesByDistanceResponse) { log.Error("Unexpected response type {0} received, status code {1}.", response.ResponseTypeCase, response.Status); break; } // Process the response. res = await ProcessMessageGetNeighbourNodesByDistanceResponseAsync(incomingMessage, false); break; } default: log.Error("Unknown message type '{0}', connection to the client will be closed.", incomingMessage.MessageTypeCase); await SendProtocolViolation(client); // Connection will be closed in ReceiveMessageLoop. break; } } catch (Exception e) { log.Error("Exception occurred, connection to the client will be closed: {0}", e.ToString()); await SendProtocolViolation(client); // Connection will be closed in ReceiveMessageLoop. } log.Debug("(-):{0}", res); return(res); }