ASP .NET MVC websocket client to save data in DB - asp.net-mvc

I am struggling to achieve the following:
I have created a Java websocket server which publishes data every 1 sec.
In ASP MVC projest I would like to receive the data and save them in database only so no JS involved here.
I am able to read the websocket data using console application method below :
using WebSocketSharp;
List<string> readoutList = new List<string>();
public void receiveMessage() {
using (var ws = new WebSocket("ws://localhost:4567/socket/"))
{
ws.OnMessage += (sender, e) =>
{
if (e.IsText)
{
readoutList.Add(e.Data.ToString());
Console.WriteLine(e.Data.ToString());
}
};
ws.Connect();
Console.ReadKey(true);
}
}`
How to create a service of this kind within the ASP MVC project? I need some direction here.

MVC is stateless so you have to request back to the server to initiate the request (such as from a form post) but within the MVC controller response, you can kick off the request to the server (as an example using a different technology). The problem is there isn't necessarily a 1 to 1 translation in MVC; initiating the request using client-side JavaSvcript would be the option here. Initiating these types of requests within MVC may cause issues with timeouts too that you have to be aware of.
OR, you can consider a scheduled windows program or a windows service that is installed, which can manage itself and initiate the request every so often. I think this is the better option.

Related

Breeze.Sharp Cannot Import Metadata from Breeze Server for ASP.NET Core 3

I am trying to use breeze sharp with Blazor Webassembly.
I have been able to recompile breeze sharp for .Net Standard 2.0 and 2.1 that has shown positive results reading data from the server.
However when trying to load Metadata from script I have noticed that MetadaStore.ImportMetadata method fails to load metadata.
When I followed up I found that there Breeze.Sharp expects metadataVersion property and namingConvention node from the metadata json returned by the breeze server.
What I can see is that First the metadata format has changed and those properties are no longer present in the generated metadata.
But if I FetchMetadata using DataService then the metadata is loaded into the metadatastore.
My Question is ...Is there a plan to update breeze sharp to be aligned with recent developments in the dotnet platform?
Kindly consider it as it aligns very well with Blazor. Actually my experiment went very fine expect for loading metadata stored locally instead of loading it from the server every time.
private void DeserializeFrom(JNode jNode, bool isFromServer) {
MetadataVersion = jNode.Get<String>("metadataVersion");
// may be more than just a name
var ncNode = jNode.GetJNode("namingConvention");
if (ncNode != null) {
var nc = Configuration.Instance.FindOrCreateNamingConvention(ncNode);
if (nc == null) {
OnMetadataMismatch(null, null, MetadataMismatchTypes.MissingCLRNamingConvention, ncNode.ToString());
} else {
// keep any preexisting ClientServerNamespaceMap info
NamingConvention = nc.WithClientServerNamespaceMapping(this.NamingConvention.ClientServerNamespaceMap);
}
}
// localQueryComparisonOptions
jNode.GetJNodeArray("dataServices").Select(jn => new DataService(jn)).ForEach(ds => {
if (GetDataService(ds.ServiceName) == null) {
AddDataService(ds);
}
});
jNode.GetJNodeArray("structuralTypes")
.ForEach(jn => UpdateStructuralTypeFromJNode(jn, isFromServer));
jNode.GetMap<String>("resourceEntityTypeMap").ForEach(kvp => {
var stName = kvp.Value;
if (isFromServer) {
stName = TypeNameInfo.FromStructuralTypeName(stName).ToClient(this).StructuralTypeName;
}
// okIfNotFound because metadata may contain refs to types that were already excluded earlier in
// UpdateStructuralTypeFromJNode
var et = GetEntityType(stName, true);
if (et != null) {
SetResourceName(kvp.Key, et);
}
});
}
I have been following up very closely new developments and this is what I have noticed so far.
Microsoft is reviving the product called Microsoft Restier.
First it was developed on the .Net Framework Platform but now they are rewriting it to run on the .Net Core and is expected to go RTM in the first half 0f the year 2020. A good thing about this Microsoft Restier is that your Full Entity Context is exposed as OData endpoint with your entity lists exposed without the need for creating Controllers on Actions.
This way it reduces the tedious work of writing an action for each entity that you want to expose as an OData resource different from the current case with plain OData and Breeze Server.
There are so many areas for configurations and extensibility.
Microsoft is remaking RIA Data Services in the form of OData Connected Service.
This creates a Proxy in the same way as RIA Data Services.
With the Proxy generated there is no need to create a client data model. The model created on the server will suffice... not as the case for breeze sharp where you need to create a model on the client although there are signs that at DevForce they are exploring using PostSharp to make it possible to use POCO objects sharable between breeze server and clients. We however do not know when will this be available.
OData Connected Service works seamlessly with Blazor Server (On the Client Side there some bugs that are being worked on ) and removes the headache of working with bare bone HttpClient.
As for breeze sharp it currently works well with both Blazor Server and Web Assembly versions (Breeze Sharp Standard). I think they will rework their product and enable it to work with OData the same way Breezejs does. This combined with Microsoft.Restier will make life very easy.
Actually breeze has very nice features especially when it comes to caching.
Lets wait and see.

How can I store and persist multiple remoting sessions in an MVC application?

Imagine a monitoring website that connects to 50 services via .net remoting and polls them to check they are working and find out what they're up to, and display it.
The page uses ajax to hit the backend and the backend then connects to each one.
Ideally, I don't want it to open a connection, do the request, close the connection, for 50 connections, on a 5 second interval (unless this is the best practice way?). So I'd like MVC to persist the connections.
I can make a ConnectionManager static singleton to handle this (not sure where?), opening and closing connections as required/idling.
You could even have a ConnectionManager handle the server status, so if multiple people load the status webpage, the results are cached.
But is there a better way, especially one that is scaleable? You could have multiple ConnectionManager classes in a webfarm scenario as they won't clash afaik (you can have multiple connections open).
ATM I am doing this in my ajax methods:
TcpChannel tcpChannel = new TcpChannel();
ChannelServices.RegisterChannel(tcpChannel, false);
Type requiredType = typeof(ICatServerMarshaller);
ICatServerMarshaller remoteObject = (ICatServerMarshaller)Activator.GetObject(requiredType,
"tcp://localhost:4567/CatServerMarshaller");
string catStatus;
try
{
catStatus = remoteObject.GetCatStatus().ToString();
}
catch (SocketException ex)
{
catStatus = "Offline";
}
finally
{
ChannelServices.UnregisterChannel(tcpChannel);
}
return Json(new { catStatus = catStatus});

ASP .Net MVC and WCF Identity (Claims) Integration

We're building a platform where the client is an ASP .Net MVC one, using ASP Net Identity 2.0 for authentication and authorization (using Claims), which works great on the web side.
We also have a WCF service which allows CRUD operations on the database (for multiple client applications), which gets requests from this ASP .Net MVC client.
As we want to validate (authenticate & authorize) the user before making specific CRUD actions in the WCF side, we need to get the claims of the user from the client, and perform the validations (preferably in a very clean manner using headers or any binding that WCF will be able to support for this matter).
I've been searching the different forums but with no simple answer\tutorial to this specific scenario. Can anyone assist on this matter?
Thanks,
Nir.
I love this:
in your IEndpointBehavior implementation do this on the client end:
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
request.Headers.Add(MessageHeader.CreateHeader("token", "http://myurl.com/service/token", _theToken));
return null;
}
then on the service end add this to your ServiceAuthenticationManager
public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(
ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message)
{
IPrincipal user = new MyUserPrincipal(null);
if(_currentServiceContractType.GetInterfaces()
.Any(x => x == typeof(IMySecuredService)))
{
var tokenPosition = message.Headers.FindHeader("token", "http://myurl.com/service/token");
if (tokenPosition >= 0 && tokenPosition <= 5)
{
var encryptedToken = message.Headers.GetHeader<string>(tokenPosition);
if (!string.IsNullOrWhiteSpace(encryptedToken))
{
var serializedToken = new MyEncryptionUtility().Decrypt(encryptedToken);
var token = MyTokenSerializer.Deserialize(serializedToken);
var expire = new DateTime(token.ValidToTicks);
if (expire > DateTime.Now)
{
user = new MyUserPrincipal(token);
}
}
}
}
message.Properties["Principal"] = user;
Thread.CurrentPrincipal = user;
return authPolicy;
}
This gives you then the ability to use the built in claims or WIF claims authentication. Eitherway, this is very simple. The token is created by the service and sent to the client (web) and stored in the cookie. then when there are any requests, the token is grabbed from a cookie and then sent along to the service, where, inevitably you can start adding permissions service side, versus doing them on the web/mvc side, making a much cleaner code base using everyone's favorite friend, SOA >= :)

How to make screen client updates whenever an event occurred (MVC)?

I'am new in MVC. I'am currently working to transform a desktop to a web application.
I need to make an update to the user view when an event of an object occurred. I have an object that observe a humidity sensor. Let say This object will trigger an event when the humidity above 70%. The code might be like this:
Private Sub Humidity_Alert(sender As Object) Handles objSensor.Alert
'Update user chart
End Sub
In desktop application, I just make an update to the view as usual in realtime, but I don't have any idea yet how to return this event to the client in MVC, without using javascript timer to make an ajax call to request if there is any alert. How to solve my problem?
I would suggest using ASP.NET SignalR library: signalr.net
You can use it for real-time updates from server to client.
ASP.NET SignalR is a new library for ASP.NET developers that makes it incredibly simple to add real-time web functionality to your applications. What is "real-time web" functionality? It's the ability to have your server-side code push content to the connected clients as it happens, in real-time.
Some pseudo-code example:
SignalR Hub:
public class HumidityHub : Hub
{
public void RefreshChart(string data)
{
Clients.All.refreshChart(data);
}
}
ClientCode:
var hub = $.connection.humidityHub;
hub.client.refreshChart= function (data) {
//refresh your chart
};
$.connection.hub.start();
ServerCode:
var hubContext = GlobalHost.ConnectionManager.GetHubContext<HumidityHub >();
hubContext.Clients.All.refreshChart(data);

OWIN asynchronous startup (using Hangfire)

I am using Hangfire with SQL Storage on a remote SQL server and running it alongside my existing MVC site. My startup class is very simple:
public void Configuration(IAppBuilder app)
{
app.UseHangfire(config =>
{
config.UseSqlServerStorage("MY_CONNECTION_STRING");
config.UseServer();
});
}
The problem is that any delay in connecting to the remote server delays my MVC site from spinning up. Is there a way to start OWIN asynchronously so that the project is able to respond to requests regardless of what happens during the OWIN startup, including fatal errors?
Hangfire initialization logic is performed in a dedicated thread to decrease the start-up time of your application. So, UseServer method creates a new thread only, without any additional logic.
UseSqlServerStorage method connects to your database to check your current schema to run automatic migrations if necessary (one simple query to the Hangfire.Schema table). This is the default behavior, however you are able to disable it:
var options = new SqlServerStorageOptions
{
PrepareSchemaIfNecessary = false
};
var storage = new SqlServerStorage("<name or connection string>", options);
After performing this step, Hangfire will not connect to your database at startup (and no other class will do it). But keep an eye on release notes, they will contain information about database storage changes.

Resources