public async Task BeginAsync() { try { await messageClient.ConnectAsync(definition.TcpHost, definition.TcpPort); Log.Info($"Connected to Agent '{definition.Name}'."); } catch (Exception error) { Log.Error($"Failed to connect to Agent '{definition.Name}'!", error); throw new ApplicationException($"Failed to connect to Agent '{definition.Name}'! {error.Message}"); } var message = new BuildSessionBeginRequest { ServerSessionId = context.ServerSessionId, Project = context.Project, AssemblyFile = context.AssemblyFilename, PreBuild = context.PreBuild, GitRefspec = context.GitRefspec, BuildNumber = context.BuildNumber, }; try { var response = await messageClient.Send(message) .GetResponseAsync <BuildSessionBeginResponse>(); AgentSessionId = response.SessionId; } catch (Exception error) { throw new ApplicationException($"Failed to start Agent Session! {error.Message}"); } BuildTasks.Start(); }
private async Task <MessageClient> Reconnect(ServerAgentDefinition agent, TimeSpan timeout) { var client = new MessageClient(PhotonServer.Instance.MessageRegistry) { //Context = sessionBase, }; //MessageClient.ThreadException += MessageClient_OnThreadException; var tokenSource = new CancellationTokenSource(timeout); while (!tokenSource.IsCancellationRequested) { try { await client.ConnectAsync(agent.TcpHost, agent.TcpPort, tokenSource.Token); } catch (SocketException) { await Task.Delay(1000, tokenSource.Token); continue; } var versionRequest = new AgentGetVersionRequest(); var versionResponse = await client.Send(versionRequest) .GetResponseAsync <AgentGetVersionResponse>(tokenSource.Token); if (versionResponse.Version == UpdateVersion) { return(client); } } client.Dispose(); return(null); }
private async Task UpdateAgent(ServerAgent agent, MessageClient messageClient, CancellationToken token) { var message = new AgentUpdateRequest { Filename = UpdateFilename, }; try { await messageClient.Send(message) .GetResponseAsync(token); await messageClient.DisconnectAsync(); } finally { messageClient?.Dispose(); } await Task.Delay(3000, token); // TODO: Verify update was successful by polling for server and checking version messageClient = null; try { messageClient = await Reconnect(agent, TimeSpan.FromMinutes(2)); } finally { messageClient?.Dispose(); } }
public void Sending_message_should_succeed_when_packet_types_are_preloaded() { var c = new MessageClient(framedClient, serializer.Object, messageHandler.Object); c.PreLoadTypesFromAssemblyOfType <TestData>(); serializer.Setup(s => s.Serialize(It.IsAny <TestData>(), It.IsAny <MemoryStream>())) .Callback((TestData d, MemoryStream ms) => { ms.Write(new byte[] { 0, 1, 2, 3, 4 }, 0, 5); }); rawClient.Setup(rc => rc.Send(It.IsAny <byte[]>())).Callback((byte[] b) => { var length = BitConverter.ToInt32(b, 0); var messageId = BitConverter.ToInt32(b, 4); Assert.Equal(4 + 4 + 5, length); Assert.Equal(4 + 4 + 5, b.Length); Assert.Equal(3, messageId); Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, new ArraySegment <byte>(b, 8, 5)); }); c.Send(CreateSampleTestData()); }
private async Task <MessageClient> Reconnect(ServerAgent agent, TimeSpan timeout) { var client = new MessageClient(PhotonServer.Instance.MessageRegistry); client.ThreadException += (o, e) => { var error = (Exception)e.ExceptionObject; Output.AppendLine("An error occurred while messaging the client!", ConsoleColor.DarkRed) .AppendLine(error.UnfoldMessages()); Log.Error("Message Client error after update!", error); }; var tokenSource = new CancellationTokenSource(timeout); var token = tokenSource.Token; while (true) { token.ThrowIfCancellationRequested(); try { await client.ConnectAsync(agent.TcpHost, agent.TcpPort, tokenSource.Token); var handshakeRequest = new HandshakeRequest { Key = Guid.NewGuid().ToString(), ServerVersion = Configuration.Version, }; var handshakeTimeout = TimeSpan.FromSeconds(HandshakeTimeoutSec); var handshakeResponse = await client.Handshake <HandshakeResponse>(handshakeRequest, handshakeTimeout, TokenSource.Token); if (!string.Equals(handshakeRequest.Key, handshakeResponse.Key, StringComparison.Ordinal)) { throw new ApplicationException("Handshake Failed! An invalid key was returned."); } if (!handshakeResponse.PasswordMatch) { throw new ApplicationException("Handshake Failed! Unauthorized."); } var versionRequest = new AgentGetVersionRequest(); var versionResponse = await client.Send(versionRequest) .GetResponseAsync <AgentGetVersionResponse>(token); if (!VersionTools.HasUpdates(versionResponse.Version, UpdateVersion)) { break; } } catch (SocketException) { await Task.Delay(1000, tokenSource.Token); } } return(client); }
protected override async Task OnReleaseSessionAsync() { var message = new BuildSessionReleaseRequest { AgentSessionId = AgentSessionId, }; await MessageClient.Send(message) .GetResponseAsync(); }
public void Sending_message_should_throw_data_exception_if_sent_message_has_no_MessageId() { var c = new MessageClient(framedClient, serializer.Object, messageHandler.Object); Assert.Throws(typeof(InvalidDataException), () => { c.Send(new TestDataWithoutMessageId()); }); }
public async Task Run(string taskName, CancellationToken token = default(CancellationToken)) { var runRequest = new TaskRunRequest { AgentSessionId = agentSessionId, TaskSessionId = SessionId, TaskName = taskName ?? throw new ArgumentNullException(nameof(taskName)), }; await messageClient.Send(runRequest) .GetResponseAsync <TaskRunResponse>(token); }
public async Task Run(string taskName, CancellationToken token) { var runRequest = new TaskRunRequest { AgentSessionId = agentSessionId, TaskSessionId = SessionId, TaskName = taskName, }; await messageClient.Send(runRequest) .GetResponseAsync <TaskRunResponse>(token); }
/// <summary> /// 向服务端发送消息,并接收消息 /// </summary> /// <param name="protocol">协议对象</param> /// <returns></returns> public static MessageProtocol SendAndReceiveMessage(MessageProtocol protocol) { if (mc == null) { mc = new MessageClient(_ip, _port); } MessageProtocol _protocol = null; try { if (!protocol.SerialNumberLock) { protocol.SerialNumber = serialNumber.ToString(); //流水号递增 serialNumber++; if (serialNumber > 1000000) { serialNumber = 0; } } if (mc.Connect()) { //发送命令 string message = ProtocolTranslator.SerilizeMessage(protocol); mc.Send(message); Thread.Sleep(100); string str = mc.Receive(ProtocolTranslator.StartFlag, ProtocolTranslator.EndFlag); _protocol = ProtocolTranslator.DeserilizeMessage(str); } } catch (Exception ex) { Log.writeLineToLog(ex.Message, "云支撑平台文件通讯故障"); } return(_protocol); }
public async Task BeginAsync() { try { await messageClient.ConnectAsync(definition.TcpHost, definition.TcpPort); context.Output .Append("Connected to Agent ", ConsoleColor.DarkGreen) .AppendLine(definition.Name, ConsoleColor.Green); } catch (Exception error) { context.Output .Append("Failed to connect to Agent ", ConsoleColor.DarkYellow) .Append(definition.Name, ConsoleColor.Yellow) .AppendLine($"! {error.Message}", ConsoleColor.DarkYellow); throw new ApplicationException($"Failed to connect to Agent '{definition.Name}'! {error.Message}"); } var message = new DeploySessionBeginRequest { ServerSessionId = context.ServerSessionId, ProjectPackageId = context.ProjectPackageId, ProjectPackageVersion = context.ProjectPackageVersion, }; try { var response = await messageClient.Send(message) .GetResponseAsync <DeploySessionBeginResponse>(); AgentSessionId = response.AgentSessionId; } catch (Exception error) { throw new ApplicationException($"Failed to start Agent Session! {error.Message}"); } //if (string.IsNullOrEmpty(AgentSessionId)) // throw new ApplicationException("Failed to begin agent session!"); }
public void Run(int serverPort) { client = new MessageClient( new FramedClient(new SocketClient(useIPv6: true)), new ProtoBufStacksSerializer(), new ClientMessageHandler()); client.PreLoadTypesFromAssemblyOfType <TemperatureResponse>(); client.Connect(new IPEndPoint(IPAddress.IPv6Loopback, serverPort)) .Subscribe(_ => { Console.WriteLine("Querying for temperature in London, Warsaw, Madrid"); client.Send(new TemperatureRequest { City = "London" }); client.Send(new TemperatureRequest { City = "Warsaw" }); client.Send(new TemperatureRequest { City = "Madrid" }); }); }
private async Task AgentAction(ServerAgent agent) { using (var messageClient = new MessageClient(PhotonServer.Instance.MessageRegistry)) { try { Output.WriteLine($"[{agent.Name}] Connecting...'", ConsoleColor.White); await messageClient.ConnectAsync(agent.TcpHost, agent.TcpPort, TokenSource.Token); await ClientHandshake.Verify(messageClient, TokenSource.Token); Output.WriteLine($"[{agent.Name}] Connected.", ConsoleColor.DarkCyan); } catch (Exception error) { using (var block = Output.WriteBlock()) { block.WriteLine($"[{agent.Name}] Connection Failed!", ConsoleColor.DarkRed); block.WriteLine(error.UnfoldMessages(), ConsoleColor.DarkYellow); } return; } var userMgr = PhotonServer.Instance.UserMgr; var securityConfig = PhotonServer.Instance.ServerConfiguration.Value.Security; var message = new SecurityPublishRequest { Users = userMgr.AllUsers.ToArray(), UserGroups = userMgr.AllGroups.ToArray(), SecurityEnabled = securityConfig.Enabled, SecurityDomainEnabled = securityConfig.DomainEnabled, }; Output.WriteLine($"[{agent.Name}] Publishing security configuration...", ConsoleColor.White); await messageClient.Send(message) .GetResponseAsync(); Output.WriteLine($"[{agent.Name}] security configuration published.", ConsoleColor.DarkGreen); try { Output.WriteLine($"[{agent.Name}] Disconnecting...", ConsoleColor.White); messageClient.Disconnect(); } catch {} } }
protected override async Task OnBeginSession() { var message = new DeploySessionBeginRequest { DeploymentNumber = session.DeploymentNumber, ServerSessionId = session.SessionId, SessionClientId = SessionClientId, ProjectPackageId = session.ProjectPackageId, ProjectPackageVersion = session.ProjectPackageVersion, Variables = session.Variables, EnvironmentName = session.EnvironmentName, }; var response = await MessageClient.Send(message) .GetResponseAsync <DeploySessionBeginResponse>(); AgentSessionId = response.AgentSessionId; }
private async Task <MessageClient> Reconnect(ServerAgent agent, TimeSpan timeout, CancellationToken token) { using (var timeoutTokenSource = new CancellationTokenSource(timeout)) using (var mergedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutTokenSource.Token, token)) { while (true) { mergedTokenSource.Token.ThrowIfCancellationRequested(); var client = new MessageClient(PhotonServer.Instance.MessageRegistry); try { using (var connectionTimeoutTokenSource = new CancellationTokenSource(20_000)) using (var connectTokenSource = CancellationTokenSource.CreateLinkedTokenSource(mergedTokenSource.Token, connectionTimeoutTokenSource.Token)) { await client.ConnectAsync(agent.TcpHost, agent.TcpPort, connectTokenSource.Token); await ClientHandshake.Verify(client, connectTokenSource.Token); var versionRequest = new AgentGetVersionRequest(); var versionResponse = await client.Send(versionRequest) .GetResponseAsync <AgentGetVersionResponse>(connectTokenSource.Token); if (string.IsNullOrEmpty(versionResponse.Version)) { Log.Warn("An empty version response was received!"); continue; } if (!VersionTools.HasUpdates(versionResponse.Version, UpdateVersion)) { return(client); } } } catch (SocketException) {} catch (OperationCanceledException) {} catch (Exception error) { Log.Warn("An unhandled exception occurred while attempting to reconnect to an updating agent.", error); } client.Dispose(); await Task.Delay(3_000, mergedTokenSource.Token); } } }
private async Task UpdateAgent(ServerAgent agent, MessageClient messageClient, CancellationToken token) { var message = new AgentUpdateRequest { Filename = UpdateFilename, }; try { await messageClient.Send(message) .GetResponseAsync(token); try { messageClient.Disconnect(); } catch {} } finally { messageClient?.Dispose(); messageClient = null; } Output.WriteBlock(block => block .Write("Agent update started on ", ConsoleColor.DarkCyan) .Write(agent.Name, ConsoleColor.Cyan) .WriteLine("...", ConsoleColor.DarkCyan)); await Task.Delay(6_000, token); var reconnectTimeout = TimeSpan.FromMinutes(2); try { messageClient = await Reconnect(agent, reconnectTimeout, token); } catch (OperationCanceledException) { throw new ApplicationException($"A timeout occurred after {reconnectTimeout} while waiting for the update to complete."); } finally { if (messageClient != null) { messageClient.Disconnect(); messageClient.Dispose(); } } }
private async Task AgentAction(ServerAgentDefinition agent) { using (var messageClient = new MessageClient(PhotonServer.Instance.MessageRegistry)) { await messageClient.ConnectAsync(agent.TcpHost, agent.TcpPort, CancellationToken.None); var agentVersionRequest = new AgentGetVersionRequest(); var agentVersionResponse = await messageClient.Send(agentVersionRequest) .GetResponseAsync <AgentGetVersionResponse>(); if (!HasUpdates(agentVersionResponse.Version, LatestAgentVersion)) { // TODO: Print Up-To-Date message return; } await UpdateAgent(agent, messageClient); } }
protected override async Task OnBeginSession() { var message = new BuildSessionBeginRequest { ServerSessionId = session.SessionId, SessionClientId = SessionClientId, Project = session.Project, AssemblyFile = session.AssemblyFilename, PreBuild = session.PreBuild, GitRefspec = session.GitRefspec, BuildNumber = session.BuildNumber, Variables = session.Variables, Commit = session.Commit, }; var response = await MessageClient.Send(message) .GetResponseAsync <BuildSessionBeginResponse>(); AgentSessionId = response.AgentSessionId; }
private static async Task <string> GetAgentVersion(ServerAgent agent, CancellationToken token) { MessageClient messageClient = null; try { messageClient = new MessageClient(PhotonServer.Instance.MessageRegistry); await messageClient.ConnectAsync(agent.TcpHost, agent.TcpPort, token); var handshakeRequest = new HandshakeRequest { Key = Guid.NewGuid().ToString(), ServerVersion = Configuration.Version, }; var timeout = TimeSpan.FromSeconds(30); var handshakeResponse = await messageClient.Handshake <HandshakeResponse>(handshakeRequest, timeout, token); if (!string.Equals(handshakeRequest.Key, handshakeResponse.Key, StringComparison.Ordinal)) { throw new ApplicationException("Handshake Failed! An invalid key was returned."); } if (!handshakeResponse.PasswordMatch) { throw new ApplicationException("Handshake Failed! Unauthorized."); } var agentVersionRequest = new AgentGetVersionRequest(); var agentVersionResponse = await messageClient.Send(agentVersionRequest) .GetResponseAsync <AgentGetVersionResponse>(token); return(agentVersionResponse.Version); } catch (Exception error) { throw new ApplicationException($"Failed to retrieve version of agent '{agent.Name}'!", error); } finally { messageClient?.Dispose(); } }
public void Sending_packet_should_send_serialized_data_with_proper_header() { var c = new MessageClient(framedClient, serializer.Object, messageHandler.Object); serializer.Setup(s => s.Serialize(It.IsAny <TestData>(), It.IsAny <MemoryStream>())) .Callback((TestData d, MemoryStream ms) => { ms.Write(new byte[] { 0, 1, 2, 3, 4 }, 0, 5); }); rawClient.Setup(rc => rc.Send(It.IsAny <byte[]>())).Callback((byte[] b) => { var length = BitConverter.ToInt32(b, 0); var messageId = BitConverter.ToInt32(b, 4); Assert.Equal(4 + 4 + 5, length); Assert.Equal(4 + 4 + 5, b.Length); Assert.Equal(3, messageId); Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, new ArraySegment <byte>(b, 8, 5)); }); c.Send(CreateSampleTestData()); }
public async Task ClientDisconnectWaitsForMessages() { var registry = new MessageProcessorRegistry(); registry.Register(typeof(DelayedTestProcessor)); using (var listener = new MessageListener(registry)) using (var client = new MessageClient(registry)) { listener.Listen(IPAddress.Loopback, Port); await client.ConnectAsync(Host, Port, CancellationToken.None); DelayedTestProcessor.Complete = false; var message = new DelayedTestRequest(); var _ = client.Send(message).GetResponseAsync <DelayedTestResponse>(); client.Disconnect(); //await task; Assert.That(DelayedTestProcessor.Complete, Is.True); listener.Stop(); } }
public void Sending_message_should_succeed_if_message_was_declared_imperatively() { var c = new MessageClient(framedClient, serializer.Object, new Mock <TestDataWithoutMessageIdHandler>().Object, r => r.RegisterMessage <TestDataWithoutMessageId>(3)); serializer.Setup(s => s.Serialize(It.IsAny <TestDataWithoutMessageId>(), It.IsAny <MemoryStream>())) .Callback((TestDataWithoutMessageId d, MemoryStream ms) => { ms.Write(new byte[] { 0, 1, 2, 3, 4 }, 0, 5); }); rawClient.Setup(rc => rc.Send(It.IsAny <byte[]>())).Callback((byte[] b) => { var length = BitConverter.ToInt32(b, 0); var messageId = BitConverter.ToInt32(b, 4); Assert.Equal(4 + 4 + 5, length); Assert.Equal(4 + 4 + 5, b.Length); Assert.Equal(3, messageId); Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, new ArraySegment <byte>(b, 8, 5)); }); c.Send(new TestDataWithoutMessageId()); }
private static async Task <string> GetAgentVersion(ServerAgent agent, CancellationToken token) { MessageClient messageClient = null; try { messageClient = new MessageClient(PhotonServer.Instance.MessageRegistry); await messageClient.ConnectAsync(agent.TcpHost, agent.TcpPort, token); await ClientHandshake.Verify(messageClient, token); var agentVersionRequest = new AgentGetVersionRequest(); var agentVersionResponse = await messageClient.Send(agentVersionRequest) .GetResponseAsync <AgentGetVersionResponse>(token); return(agentVersionResponse.Version); } catch (Exception error) { throw new ApplicationException($"Failed to retrieve version of agent '{agent.Name}'!", error); } finally { messageClient?.Dispose(); } }
public async Task Update(ServerAgentDefinition agent, CancellationToken token) { //Output // .Append("Checking Agent ", ConsoleColor.DarkCyan) // .Append(agent.Name, ConsoleColor.Cyan) // .AppendLine(" for updates...", ConsoleColor.DarkCyan); //MessageClient client = null; try { //client = new MessageClient(PhotonServer.Instance.MessageRegistry) { // //Context = sessionBase, //}; //MessageClient.ThreadException += MessageClient_OnThreadException; //await client.ConnectAsync(agent.TcpHost, agent.TcpPort, token); //var versionRequest = new AgentGetVersionRequest(); //var versionResponse = await client.Send(versionRequest) // .GetResponseAsync<AgentGetVersionResponse>(token); //if (!HasUpdates(versionResponse.Version, UpdateVersion)) { // Output // .Append("Agent ", ConsoleColor.DarkBlue) // .Append(agent.Name, ConsoleColor.Blue) // .AppendLine(" is up-to-date. Version: ", ConsoleColor.DarkBlue) // .AppendLine(versionResponse.Version, ConsoleColor.Blue); // return; //} //Output // .Append("Updating Agent ", ConsoleColor.DarkCyan) // .Append(agent.Name, ConsoleColor.Cyan) // .AppendLine("...", ConsoleColor.DarkCyan); var message = new AgentUpdateRequest { Filename = MsiFilename, }; await MessageClient.Send(message) .GetResponseAsync(token); await MessageClient.DisconnectAsync(); } finally { MessageClient?.Dispose(); } await Task.Delay(3000, token); // TODO: Verify update was successful by polling for server and checking version client = null; try { client = await Reconnect(agent, TimeSpan.FromSeconds(60)); await client.DisconnectAsync(); } finally { client?.Dispose(); } Output .Append("Agent ", ConsoleColor.DarkGreen) .Append(agent.Name, ConsoleColor.Green) .AppendLine(" updated successfully.", ConsoleColor.DarkGreen); }