Comunicação com Worker Roles via Endpoints
Olá pessoal, tudo certo?
Esses últimos meses, participei de alguns projetos na plataforma Azure. Alguns cenários foram muito comuns, como o desenho abaixo, onde temos interfaces Web Roles com ASP.NET MVC e processos implementados em Worker Roles. A comunicação entre esses processos vem sendo feita via filas ou tabelas e blobs para usos gerais, dependendo do projeto.
Outro mecanismo disponível para comunicação com Web Roles e Worker Roles é o Endpoint. A atualização de Fevereiro do Training Kit oferece alguns exercícios sobre a comunicação com Worker Roles, veja:
Worker Role Communication
Ref.: https://msdn.microsoft.com/en-us/gg457887
Podemos criar Endpoints para comunicação via TCP, HTTP e HTTPS. Em seu projeto Worker Role, entre na página de propriedades e na aba Endpoints, você encontrará a lista de Endpoints em uso. Através do botão Add Endpoint, você poderá adicionar suas novas entradas.
Veja o exemplo de Worker Role completo abaixo. Esse código utiliza um Endpoint de nome “TelnetServiceEndpoint” para implementar o tratamento de uma conexão Telnet Client. Através desse canal, podemos obter informações sobre o funcionamento do Worker, por exemplo.
1: using System;
2: using System.Collections.Generic;
3: using System.Diagnostics;
4: using System.Linq;
5: using System.Net;
6: using System.Threading;
7: using Microsoft.WindowsAzure;
8: using Microsoft.WindowsAzure.Diagnostics;
9: using Microsoft.WindowsAzure.ServiceRuntime;
10: using Microsoft.WindowsAzure.StorageClient;
11:
12: using System.IO;
13: using System.Net.Sockets;
14:
15: namespace HelloWorkerRole
16: {
17: public class WorkerRole : RoleEntryPoint
18: {
19: private readonly AutoResetEvent _connectionWait = new AutoResetEvent(false);
20:
21: /// <summary>
22: ///
23: /// </summary>
24: /// <returns></returns>
25: public override bool OnStart()
26: {
27: ServicePointManager.DefaultConnectionLimit = 12;
28: DiagnosticMonitor.Start("DiagnosticsConnectionString");
29: RoleEnvironment.Changing += RoleEnvironmentChanging;
30: return base.OnStart();
31: }
32:
33:
34: /// <summary>
35: ///
36: /// </summary>
37: public override void Run()
38: {
39: Trace.WriteLine("Starting Telnet Service...", "Information");
40: TcpListener listener;
41: try
42: {
43: listener = new TcpListener(
44: RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["TelnetServiceEndpoint"].IPEndpoint) { ExclusiveAddressUse = false };
45: listener.Start();
46:
47: Trace.WriteLine("Started Telnet Service.", "Information");
48: }
49: catch (SocketException se)
50: {
51: Trace.Write("Telnet Service could not start.", "Error");
52: return;
53: }
54: while (true)
55: {
56: listener.BeginAcceptTcpClient(HandleAsyncConnection, listener);
57: _connectionWait.WaitOne();
58: }
59: }
60:
61:
62: /// <summary>
63: ///
64: /// </summary>
65: /// <param name="clientId"></param>
66: /// <param name="writer"></param>
67: private static void WriteRoleInformation(Guid clientId, StreamWriter writer)
68: {
69: writer.WriteLine("--- Current Client ID, Date & Time ----");
70: writer.WriteLine("Current date: " + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString());
71: writer.WriteLine("Connection ID: " + clientId);
72: writer.WriteLine();
73:
74: writer.WriteLine("--- Current Role Instance Information ----");
75: writer.WriteLine("Role ID: " + RoleEnvironment.CurrentRoleInstance.Id);
76: writer.WriteLine("Role Count: " + RoleEnvironment.Roles.Count);
77: writer.WriteLine("Deployment ID: " + RoleEnvironment.DeploymentId);
78: writer.WriteLine();
79:
80: writer.WriteLine("--- Instance Endpoints ----");
81:
82: foreach (KeyValuePair<string, RoleInstanceEndpoint> instanceEndpoint in RoleEnvironment.CurrentRoleInstance.InstanceEndpoints)
83: {
84: writer.WriteLine("Instance Endpoint Key: " + instanceEndpoint.Key);
85:
86: RoleInstanceEndpoint roleInstanceEndpoint = instanceEndpoint.Value;
87:
88: writer.WriteLine("Instance Endpoint IP: " + roleInstanceEndpoint.IPEndpoint);
89: writer.WriteLine("Instance Endpoint Protocol: " + roleInstanceEndpoint.Protocol);
90: writer.WriteLine("Instance Endpoint Type: " + roleInstanceEndpoint);
91: writer.WriteLine();
92: }
93: }
94:
95:
96: /// <summary>
97: ///
98: /// </summary>
99: /// <param name="result"></param>
100: private void HandleAsyncConnection(IAsyncResult result)
101: {
102: var listener = (TcpListener)result.AsyncState;
103: var client = listener.EndAcceptTcpClient(result);
104: _connectionWait.Set();
105:
106: var clientId = Guid.NewGuid();
107: Trace.WriteLine("Connection ID: " + clientId, "Information");
108:
109: var netStream = client.GetStream();
110: var reader = new StreamReader(netStream);
111: var writer = new StreamWriter(netStream);
112: writer.AutoFlush = true;
113:
114: var input = string.Empty;
115: while (input != "3")
116: {
117: writer.WriteLine(" 1) Display Worker Role Information");
118: writer.WriteLine(" 2) Recycle");
119: writer.WriteLine(" 3) Quit");
120: writer.Write("Enter your choice: ");
121:
122: input = reader.ReadLine();
123: writer.WriteLine();
124:
125: switch (input)
126: {
127: case "1":
128: WriteRoleInformation(clientId, writer);
129: break;
130: case "2":
131: RoleEnvironment.RequestRecycle();
132: break;
133: }
134:
135: writer.WriteLine();
136: }
137:
138: client.Close();
139: }
140:
141:
142: /// <summary>
143: ///
144: /// </summary>
145: /// <param name="sender"></param>
146: /// <param name="e"></param>
147: private static void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
148: {
149: if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
150: {
151: e.Cancel = true;
152: }
153: }
154:
155: }
156: }
Para o Endpoint TCP, veja a propriedade da Worker Role, abaixo:
Retirei o código acima a partir do artigo a seguir:
Gritty Technical Info on Windows Azure Worker Roles
Ref.: https://compositecode.com/2011/01/17/gritty-technical-info-on-windows-azure-worker-roles/
Vale conferir! Boa leitura!
Por enquanto é só! Até o próximo post :)
Waldemir.