C# Azure VM上Azure web应用程序与windows窗体应用程序之间的通信
这是我第一个使用Azure的项目。所以,如果我问的是一个非常基本的问题,请耐心等待 我有一个在Azure服务器上运行的web应用程序。我还有一个windows窗体应用程序,它托管在Azure VM上。根据要求,web应用程序将在需要时与windows窗体应用程序建立连接,向窗体应用程序发送通知,接收响应并切断连接。所以在这里,Web应用程序就像客户端,而Windows窗体应用程序就像服务器 我试着用信号器。已在Azure portal上激活Windows窗体应用程序的端点和端口。我能够建立连接,但从未从Windows窗体应用程序获得连接确认 我使用的是正确的技术还是有更好的方法?我希望有人能提出一个合适的解决方案 这是我试过的 Windows窗体应用程序中的服务器端代码C# Azure VM上Azure web应用程序与windows窗体应用程序之间的通信,c#,azure,asp.net-mvc-4,signalr,C#,Azure,Asp.net Mvc 4,Signalr,这是我第一个使用Azure的项目。所以,如果我问的是一个非常基本的问题,请耐心等待 我有一个在Azure服务器上运行的web应用程序。我还有一个windows窗体应用程序,它托管在Azure VM上。根据要求,web应用程序将在需要时与windows窗体应用程序建立连接,向窗体应用程序发送通知,接收响应并切断连接。所以在这里,Web应用程序就像客户端,而Windows窗体应用程序就像服务器 我试着用信号器。已在Azure portal上激活Windows窗体应用程序的端点和端口。我能够建立连接,
public partial class FormsServer : Form
{
private IDisposable SignalR { get; set; }
const string ServerURI = "http://abc.xyz.net:12345";
private void btnStart_Click(object sender, EventArgs e)
{
btnStart.Enabled = false;
Task.Run(() => StartServer());
}
private void StartServer()
{
try
{
SignalR = WebApp.Start<Startup>(ServerURI);
}
catch (TargetInvocationException)
{ }
}
}
公共类CalcHub:Hub
{
公共异步任务地址编号(整数编号1,整数编号2)
{
MessageBox.Show(“添加数字”);
返回no1+no2;
}
}
public class NotificationAppClient
{
Microsoft.AspNet.SignalR.Client.HubConnection connectionFr;
IHubProxy userHubProxy;
public void InitiateServerConnection()
{
connectionFr = new Microsoft.AspNet.SignalR.Client.HubConnection("http:// abc.xyz.net:12345/CalcHub", useDefaultUrl: false);
connectionFr.TransportConnectTimeout = new TimeSpan(0, 0, 60);
connectionFr.DeadlockErrorTimeout = new TimeSpan(0, 0, 60);
userHubProxy = connectionFr.CreateHubProxy("CalcHub");
userHubProxy.On<string>("addMessage", param => {
Console.WriteLine(param);
});
connectionFr.Error += async (error) =>
{
await Task.Delay(new Random().Next(0, 5) * 1000);
await connectionFr.Start();
};
}
public async Task<int> AddNumbers()
{
try
{
int result = -1;
connectionFr.Start().Wait(30000);
if (connectionFr.State == ConnectionState.Connecting)
{
connectionFr.Stop();
}
else
{
int num1 = 2;
int num2 = 3;
result = await userHubProxy.Invoke<int>("AddNumbers", num1, num2);
}
connectionFr.Stop();
return result;
}
catch (Exception ex)
{ }
return 0;
}
公共类NotificationAppClient
{
Microsoft.AspNet.signal.Client.HubConnection connectionFr;
IHubProxy用户hubproxy;
public void InitiateServerConnection()
{
connectionFr=new Microsoft.AspNet.signar.Client.HubConnection(“http://abc.xyz.net:12345/CalcHub”,useDefaultUrl:false);
connectionFr.TransportConnectTimeout=新的时间跨度(0,0,60);
connectionFr.DeadlockErrorTimeout=新的时间跨度(0,0,60);
userHubProxy=connectionFr.CreateHubProxy(“CalcHub”);
userHubProxy.On(“addMessage”,参数=>{
控制台写入线(参数);
});
connectionFr.Error+=异步(错误)=>
{
等待任务。延迟(新随机()。下一个(0,5)*1000);
等待连接fr.Start();
};
}
公共异步任务AddNumbers()
{
尝试
{
int结果=-1;
connectionFr.Start().Wait(30000);
if(connectionFr.State==ConnectionState.Connecting)
{
连接fr.Stop();
}
其他的
{
int num1=2;
int num2=3;
结果=等待userHubProxy.Invoke(“AddNumbers”,num1,num2);
}
连接fr.Stop();
返回结果;
}
捕获(例外情况除外)
{ }
返回0;
}
}感谢您的回复,因此即使代码很凌乱,也能正常工作。通常这是一个防火墙问题,所以我会绝对确保两个服务之间的端口一直处于打开状态。检查Windows防火墙和Azure网络安全组中的防火墙,以确保端口已打开。我建议再次检查“有效的安全规则”。如果存在多个安全组,则很容易在一个组中打开端口,而忽略另一个 为了排除DNS问题,您可以更改
const string ServerURI=”http://abc.xyz.net:12345";代码>到“http://*:12345”,然后尝试通过公共IP连接
最后,如果catch块实际上是空的,而不仅仅是缩短代码,那么可以删除它们,或者在其中添加允许您看到错误的内容。正如现在一样,任何错误都只是被吞没,而不知道它们是否正在发生。我没有得到任何运行你的代码,但这将是很好的,以确保
就通信方法而言,如果您要坚持使用Signal,我会将打开客户端上的连接移动到InitiateServerConnection()
中,并在客户端处于活动状态时保持打开状态。这是hoq信号器的设计工作,而不是每次打开和关闭连接。如果您的最终目标是将信息从表单应用程序实时推送到web应用程序,而不是web应用程序拉取数据,那么这很好。对于你目前正在做的事情来说,这并不理想
对于这种用例,我强烈建议使用WebAPI而不是signar。如果您打算添加更多的端点,那么与WebApi相比,使用SignalR将变得越来越困难。如果您需要将数据推送到web客户机,但也希望能够按需请求信息,则完全可以并行使用这两种方法
服务器上的Startup
方法略有变化,因为正在设置的是Microsoft.AspNet.WebApi,而不是Signal:
class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(config);
}
}
您创建的不是集线器,而是控制器
public class AddController : ApiController
{
// GET api/add?num1=1&num2=2
public HttpResponseMessage Get(int num1, int num2)
{
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new StringContent((num1 + num2).ToString());
return response;
}
}
在客户端,事情变得简单多了,因为您不再需要管理通常是持久连接的东西<代码>InitiateServerConnection()
可以完全消失AddNumbers()
成为一个简单的http调用:
public static async Task<int> AddNumbers(int num1, int num2)
{
try
{
using(var client = new HttpClient())
{
return Int32.Parse(await client.GetStringAsync($"http://<sitename>:12345/api/add?num1={num1}&num2={num2}"));
}
}
catch (Exception e)
{
//Do something with the exception
}
return 0;
}
公共静态异步任务AddNumbers(int num1,int num2)
{
尝试
{
使用(var client=new HttpClient())
{
返回Int32.Parse(wait client.GetStringAsync($“http://:12345/api/add?num1={num1}&num2={num2}”);
}
}
捕获(例外e)
{
//做一些例外的事情
}
返回0;
}
如果最终无法解决问题,请告诉我,我们可以继续进行故障排除。因此,即使代码很混乱,代码也可以正常工作。通常这是一个防火墙问题,所以我会绝对确保两个服务之间的端口一直处于打开状态。检查Windows防火墙和Azure网络安全组中的防火墙,以确保端口已打开。我推荐
public class AddController : ApiController
{
// GET api/add?num1=1&num2=2
public HttpResponseMessage Get(int num1, int num2)
{
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Content = new StringContent((num1 + num2).ToString());
return response;
}
}
public static async Task<int> AddNumbers(int num1, int num2)
{
try
{
using(var client = new HttpClient())
{
return Int32.Parse(await client.GetStringAsync($"http://<sitename>:12345/api/add?num1={num1}&num2={num2}"));
}
}
catch (Exception e)
{
//Do something with the exception
}
return 0;
}