SignalR on Azure sends message to SignalR client within a LAN - windows-services

We have the following mixed-environment scenario (Azure and LAN):
Azure Web App calls a method in the Azure API (triggered by some user action in the web app).
This Azure API then establishes a SignalR HubContext connection .
The HubContext broadcasts a message.
The SignalR client (consuming the message) is a Windows Service installed on a machine on the LAN, behind the firewall.
Our client is complaining that the connection often breaks, and therefore several messages are missing on a daily basis.
Here is a test method in the Azure API, which attempts to broadcast a message:
using Microsoft.AspNet.SignalR;
using System;
using System.IO;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.Caching;
using System.Text;
using System.Web.Http;
using System.Xml;
...
namespace MyTestAPI.Controllers
[AllowCrossSiteJson]
[RoutePrefix("api/Test")]
public class HL7Controller : ApiController
[HttpGet]
[Route("TestSignalR")]
public IHttpActionResult TestSignalR()
{
string reportData = $"<TestReport>This is a test message generated on { DateTime.Now }.</TestReport>";
var hubContext = GlobalHost.ConnectionManager.GetHubContext<HL7Hub>();
hubContext.Clients.All.SendReportData(reportData);
return Ok(reportData);
}
...
}
And in the client's environment, there's a Win Service installed - it acts as the SignalR Client
And here's a snippet of our H..NotificationsService solution (vs2019, Framework 4.6.1)
using log4net.Ext.EventID;
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Configuration;
using System.Diagnostics;
using System.Net;
using System.ServiceProcess;
using System.Threading;
namespace H_NotificationSrv
{
public partial class H_NotificationService : ServiceBase
public async void StartListner()
{
try
{
var hubConnection = new HubConnection(hl7APIUrl);
hubConnection.Credentials = CredentialCache.DefaultNetworkCredentials;
var hubProxy = hubConnection.CreateHubProxy("MyTestHub");
hubProxy.On<string>("SendReportData", reportData =>
{
SendReportDataToSomeone(reportData);
});
await hubConnection.Start();
}
catch (Exception ex)
{
string errorMessage = ex.Message;
if (ex.InnerException != null)
errorMessage += " Inner Exception: " + ex.InnerException.Message;
applog.Error(errorMessage);
}
}
}
}

Related

Push Notifications using signalR in ASP.NET MVC

I'm still learning ASP.NET MVC architecture and if any of my questions parts seem awful, sorry for the inconvenience that happened.
I want to add push notifications to my ASP.NET MVC web application which I have never used before.
I followed this article:
http://demo.dotnetawesome.com/push-notification-system-with-signalr
I'm using Entity Framework, and added the database connection string to my web.config file.
I used to create database connection via a class:
public class zSqlDb: DbContext
{
public zSqlDb(): base("Data Source=YEA-LAPTOP;Initial Catalog=db_ptweb;Integrated Security=True")
{
}
}
So in this article, he creates a class and there writes code to save data changes in the database.
This is the code:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using Microsoft.AspNet.SignalR;
namespace PushNotification
{
public class NotificationComponent
{
//Here we will add a function for register notification (will add sql dependency)
public void RegisterNotification(DateTime currentTime)
{
string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
string sqlCommand = #"SELECT [ContactID],[ContactName],[ContactNo] from [dbo].[Contacts] where [AddedOn] > #AddedOn";
//you can notice here I have added table name like this [dbo].[Contacts] with [dbo], it's mandatory when you use Sql Dependency
using (SqlConnection con = new SqlConnection(conStr))
{
SqlCommand cmd = new SqlCommand(sqlCommand, con);
cmd.Parameters.AddWithValue("#AddedOn", currentTime);
if (con.State != System.Data.ConnectionState.Open)
{
con.Open();
}
cmd.Notification = null;
SqlDependency sqlDep = new SqlDependency(cmd);
sqlDep.OnChange += sqlDep_OnChange;
//we must have to execute the command here
using (SqlDataReader reader = cmd.ExecuteReader())
{
// nothing need to add here now
}
}
}
void sqlDep_OnChange(object sender, SqlNotificationEventArgs e)
{
//or you can also check => if (e.Info == SqlNotificationInfo.Insert) , if you want notification only for inserted record
if (e.Type == SqlNotificationType.Change)
{
SqlDependency sqlDep = sender as SqlDependency;
sqlDep.OnChange -= sqlDep_OnChange;
//from here we will send notification message to client
var notificationHub = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
notificationHub.Clients.All.notify("added");
//re-register notification
RegisterNotification(DateTime.Now);
}
}
public List<Contact> GetContacts(DateTime afterDate)
{
using (MyPushNotificationEntities dc = new MyPushNotificationEntities())
{
return dc.Contacts.Where(a => a.AddedOn > afterDate).OrderByDescending(a => a.AddedOn).ToList();
}
}
}
}
But I did to add records to the database by using the controller. So will this change the definition of the push notification process? If yes then I want to know how to match this code with mine.

logic apps web hook to chalkboard API timeout error

How do I change the timeout duration in logic apps web hook and also in chalkboard API.
The error message I get is.
"message": "Http request failed: the server did not respond within the timeout limit. Please see logic app limits at https://aka.ms/logic-apps-limits-and-config#http-limits"
You can refer to Perform long-running tasks with the webhook action pattern.
After understanding the webhook pattern, you need to design some code, you can refer to the following sample:
using System.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;
using System.Threading;
using System.Net.Http;
using System;
namespace HttpToQueueWebhook
{
public static class HttpTrigger
{
[FunctionName("HttpTrigger")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "post")]HttpRequest req,
TraceWriter log,
[Queue("process")]out ProcessRequest process)
{
log.Info("Webhook request from Logic Apps received.");
string requestBody = new StreamReader(req.Body).ReadToEnd();
dynamic data = JsonConvert.DeserializeObject(requestBody);
string callbackUrl = data?.callbackUrl;
//This will drop a message in a queue that QueueTrigger will pick up
process = new ProcessRequest { callbackUrl = callbackUrl, data = "some data" };
return new AcceptedResult();
}
public static HttpClient client = new HttpClient();
/// <summary>
/// Queue trigger function to pick up item and do long work. Will then invoke
/// the callback URL to have logic app continue
/// </summary>
[FunctionName("QueueTrigger")]
public static void Run([QueueTrigger("process")]ProcessRequest item, TraceWriter log)
{
log.Info($"C# Queue trigger function processed: {item.data}");
//Thread.Sleep(TimeSpan.FromMinutes(3));
//ProcessResponse result = new ProcessResponse { data = "some result data" };
//handle your business here.
client.PostAsJsonAsync<ProcessResponse>(item.callbackUrl, result);
}
}
public class ProcessRequest
{
public string callbackUrl { get; set; }
public string data { get; set; }
}
public class ProcessResponse
{
public string data { get; set; }
}
}
The above code will first save your callbackUrl and the passed data to the queue, and then return the result of 202 to the logic app.
The QueueTrigger function will be triggered, and you can handle your business here.
You can call your http function like this in Azure logic app:
This solution can help you solve the http timeout problem. For more details, you can refer to this article.

How to detect IIS events in windows event logs and detemine its application pool according to this code?

I try to make a listener on windows event logs, but I need to recognize IIS events in it and determine its application pool.
could I do that according to this code ??? by process id for example or any thing else.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
using System.DirectoryServices;
using Microsoft.Web;
using Microsoft.Web.Administration;
namespace EventLogEnt
{
class Program
{
static AutoResetEvent signal;
static void Main(string[] args)
{
// create new log
signal = new AutoResetEvent(false);
EventLog myNewLog = new EventLog("Application", "TIS3", "Outlook");
myNewLog.EntryWritten += new EntryWrittenEventHandler(MyOnEntryWritten);
myNewLog.EnableRaisingEvents = true;
myNewLog.WriteEntry("Test message", EventLogEntryType.Information);
signal.WaitOne();
Console.ReadKey();
}
public static void MyOnEntryWritten(object source, EntryWrittenEventArgs e)
{
Console.WriteLine(e.Entry.Message);
Console.WriteLine("the entry type: " + e.Entry.EntryType);
Console.WriteLine("---------------------------------------------");
signal.Set();
}
}
}

EdgeJS calls in C# Web API causing AccessViolation Exception

using System.Threading.Tasks;
using System.Web.Http;
using EdgeJs;
namespace edge2.Controllers
{
public class ValuesController : ApiController
{
public async Task<object> Get(int id)
{
var func = Edge.Func(#"
return function (data, callback) {
callback(null, 'Node.js welcomes ' + data);
}
");
return await func(".NET");
}
}
}
I'm looking at trying to call node.js from C#. I have the above example code that is documented on their GitHub page, but when the code is moved over to a C# Web API project I get a consistent error.
AccessViolation Exception. The error only happens on the first run, and only after a rebuild of the project. All subsequent runs work perfectly.
Tooling:
VS2015
.NET 4.5.2
EdgeJS 4.0.0

Webservice not working in visual studio 2010

I have created a webservice in Visual studio 2010.I have created a database with a table which contains commands and their description.My program is:
My class:-DataHelper.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data;
using System.Data.SqlClient;
/// <summary>
/// Summary description for DataHelper
/// </summary>
public class DataHelper
{
public static string GetData(string Command)
{
string Explanation = " ";
SqlConnection con = new SqlConnection(#"Data Source=CSS-L3-D008;Initial Catalog=works1;Integrated Security=true;");
SqlCommand cmd = new SqlCommand("Select Explanation from Data1 where Command= '" + Command.ToUpper() + "'", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Explanation = dr["Explanation"].ToString();
}
dr.Close();
con.Close();
return Explanation;
}
}
And Service1.asmx
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class Service1
Inherits System.Web.Services.WebService
Private Property DataHelper As Object
<WebMethod()>
Public Function HelloWorld() As String
Return "Hello World"
End Function
<WebMethod()>
Public Function GetData(Command) As String
Return DataHelper.GetData(Command)
End Function
End Class
the problem is that wen i run it i am getting both webmethods HelloWorld and GetData but GetData is not working.When i click HelloWorld() i get invoke method and it runs properly.But when i click GetData() i get invoke button but then it shows
"The test form is only available for methods with primitive types as parameters."
Actually it should give a box where i can enter the command and the description should be returned from the sql server.Please help me.
Should that GetData method in the service declare the type of the Command parameter?:
<WebMethod()>
Public Function GetData(Command As String) As String
Return DataHelper.GetData(Command)
End Function

Resources