Update data on client side by server push - c#

I'm using wcf. I have a simple method in web service that retrieves some string data from database and returns that string data to client.
public string getSomeStringfromDatabase(){
string s ="";
//retrieving from database logic into string s
return s;
}
Really simple method, nothing special..
Now I would like to learn how to use this method to update that string from database on my clients side by "server push" style or how it is called.
Can someone give me a simple example?
I read some topics on internet pushing vs polling, but couldn't find simple enough code to understand it.
Can you give an example of push with web service method and polling too if it's not too much?

have you looked at SignalR. Its a server Push Framework which uses HTML5 WWeb Socket beneath. I have created chat server here using SignalR.
https://github.com/omkarpanhalkar/AjaxChatRoom

Related

Client Creation using WebSocketSharpAPI - C#

Hi StackOverflow Members,
I have created an HTTP server using WebsocketsharpAPI https://github.com/sta/websocket-sharp.
Here I have created an HTTP address = "http://localhost:0001/MoviePage";
I am then, Initializing and creating the Httpserver and starting it under the
Subquery /MoviePage . Here to test if client is receiving data in first place, I am sending a string of movie name instead of movie object that I have
Server.WebSocketServices[DisplayCollimationPort].Sessions.Broadcast("Spider Man 2");
The Server works without any issue. However, the issue is - I am not sure, How to use this
Websocketsharp API to Create a client and receive the sent string via a broadcast function from the server.
The examples are given only harnessing(or maybe I am missing something) the Websocketserver and Websocket class for the Server and Client in the examples provides.
Now since my address is an HTTP one and not a (ws or wss) (WebSocket) one, I would like to know if I can still use this websocketsharp API to implement a client to fetch string sent in this URL and access it. This is also because I would not be able to receive the information from httpserver with Websocket class.
Any suggestions would be much appreciated.
Thanks in Advance !!

How to send updates from server to clients?

I am building a c#/wpf project.
It's architecture is this:
A console application which will be on a virtual machine (or my home computer) that will be the server side.
A wpf application that will be the client app.
Now my problem is this - I want the server to be able to send changes to the clients. If for example I have a change for client ABC, I want the server to know how to call a service on the clients computer.
The problem is, that I don't know how the server will call the clients.
A small example in case I didn't explain it well:
The server is on computer 1, and there are two clients, on computers 2 and 3.
Client 2 has a Toyota car and client 3 has a BMW car.
The server on computer 1 wants to tell client 2 that it has a new car, an Avenger.
How do I keep track and call services on the clients?
I thought of saving their ip address (from calling ipconfig from the cmd) in the DB - but isn't that based on the WI-FI/network they are connected to?
Thanks for any help!
You could try implementing SignalR. It is a great library that uses web sockets to push data to clients.
Edit:
SignalR can help you solve your problem by allowing you to set up Hubs on your console app (server) that WPF application (clients) can connect to. When the clients start up you will register them with a specified Hub. When something changes on the server, you can push from the server Hub to the client. The client will receive the information from the server and allow you to handle it as you see fit.
Rough mockup of some code:
namepsace Server{}
public class YourHub : Hub {
public void SomeHubMethod(string userName) {
//clientMethodToCall is a method in the WPF application that
//will be called. Client needs to be registered to hub first.
Clients.User(userName).clientMethodToCall("This is a test.");
//One issue you may face is mapping client connections.
//There are a couple different ways/methodologies to do this.
//Just figure what will work best for you.
}
}
}
namespace Client{
public class HubService{
public IHubProxy CreateHubProxy(){
var hubConnection = new HubConnection("http://serverAddress:serverPort/");
IHubProxy yourHubProxy = hubConnection.CreateHubProxy("YourHub");
return yourHubProxy;
}
}
}
Then in your WPF window:
var hubService = new HubService();
var yourHubProxy = hubService.CreateHubProxy();
yourHubProxy.Start().Wait();
yourHubProxy.On("clientMethodToCall", () => DoSometingWithServerData());
You need to create some kind of subscription model for the clients to the server to handle a Publish-Subscribe channel (see http://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html). The basic architecture is this:
Client sends a request to the messaging channel to register itself as a subscriber to a certain kind of message/event/etc.
Server sends messages to the channel to be delivered to subscribers to that message.
There are many ways to handle this. You could use some of the Azure services (like Event hub, or Topic) if you don't want to reinvent the wheel here. You could also have your server application track all of these things (updates to IP addresses, updates to subscription interest, making sure that messages don't get sent more than once; taking care of message durability [making sure messages get delivered even if the client is offline when the message gets created]).
In general, whatever solution you choose is plagued with a common problem - clients hide behind firewalls and have dynamic IP addresses. This makes it difficult (I've heard of technologies claiming to overcome this but haven't seen any in action) for a server to push to a client.
In reality, the client talks and the server listens and response. However, you can use this approach to simulate a push by;
1. polling (the client periodically asks for information)
2. long polling (the client asks for information and the server holds onto the request until information arrives or a timeout occurs)
3. sockets (the client requests server connection that is used for bi-directional communication for a period of time).
Knowing those terms, your next choice is to write your own or use a third-party service (azure, amazon, other) to deliver messages for you. I personally like long polling because it is easy to implement. In my application, I have the following setup.
A web API server on Azure with and endpoint that listens for message requests
A simple loop inside the server code that checks the database for new messages every 100ms.
A client that calls the API, handling the response.
As mentioned, there are many ways to do this. In your particular case, one way would be as follows.
Client A calls server API to listen for message
Server holds onto call, waiting for new message entry in database
Client B calls server API to post new message
Server saves message to database
Server instance from step 2 sees new message
Server returns message to Client A.
Also, the message doesn't have to be stored in a database - it just depends on your needs.
Sounds like you want to track users à la https://www.simple-talk.com/dotnet/asp.net/tracking-online-users-with-signalr/ , but in a desktop app in the sense of http://www.codeproject.com/Articles/804770/Implementing-SignalR-in-Desktop-Applications or damienbod.wordpress.com/2013/11/20/signalr-a-complete-wpf-client-using-mvvm/ .

Push Notifications in SignalR from multiple Databases

I am relatively new to SignalR, What I have done so far are example chat applications on it to get started.
We have a project that includes multiple databases, it's a machine data collection app. I have created a web control in ASP.NET MVC to view data of multiple machines at one place.
We have multiple users and they can access machines related to their projects. The current solution have a jQuery observer on the mvc page which refreshes the machine controls in a specific time.
I am thinking of making it a Push Notification solution. But as I am a beginner on SignalR I don't know how to approach this.
The goal is to notify the user of changes in data for machines that the user has access to (Not all machines).
Also how can I send messages from a database server to SignalR notifying of changes in the data?
I need some guidance getting started on this.
SignalR Send method allows you to send data to user! It may use push, frame, server events or websocket techniques. You developer don't care about the technique! It depends on server and client handshake.
What you really need is to retrieve data from your databases and then to users, without worries
// Server side:
protected override Task OnConnected(IRequest request,
string connectionId)
{
var db = new allEntities();
var db2 =new allEntities2();
var data1 = db.Tables.Where(e=>e.LastUpdate<=datetime.now.AddDays(-1));
var data2=db2.Tables.Where(e=>e.Something==someRef);
var data=combine(data1,data2);//combine logic goes here
return Connection.Send(connectionId, data.ToList());
}

WCF service Multiple Users at same time

I will be deploying my first application based on WCF and would like to know the best way to deploy. Here is my architecture. Please see the attached image.
We have a WCF written using 4.0 framework and has 3 methods. A front end ASP.NET website (www.site.com) calls the WCF to save data as well as read data. In figure method1 is saving to data and method2 and 3 are for reading the data from SQL server 2008 R2 database.
In my ASP.Net webstie...
I am calling the Method1 and closing the connection...like this..
ServiceClient client = new ServiceClient();
client.Method1(data to be saved)
client.close();
I am calling method 2 and 3 as follows
ServiceClient client = new ServiceClient();
dropDown1list.datasource = client.Method2()
dropDown2list.datasource = client.Method3()
client.close();
Multiple users could be using the website at the same time to submit the data. Considering this architecture..what would be the best way to deploy the WCF so that it could handle multiple users at same time?. I read the article http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and and http://www.codeproject.com/Articles/86007/ways-to-do-WCF-instance-management-Per-call-Per.
I now believe I need to have my WCF service as
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple , InstanceContextMode = InstanceContextMode.PerCall )]
public class Service : IService
{
public bool Method1(data to be saved)
{
}
public List<string> Method2()
{
}
public List<string> Method2()
{
}
}
Am I right ?. Any suggestions ?.
Just answered a similar question yesterday. Based on your description and the picture, I don't see a need to change your architecture. If you're using one of the main WCF bindings (webHttpBinding, wsHttpBinding or BasicHTTPBinding), the service you deploy should easily be able handle dozens of concurrent users, all saving and reading at the same time.
Each client request will generate its own connection and web service objects, each of which can communicate concurrently with your database, whether that request is to read data or write data. When the response is sent back to the client, your WCF service will destroy the objects and clean up the memory for you as long as you're not doing something strange.
I've spent the last two years working on WCF web services on and industrial scale. Lately I've been working on a load testing / benchmarking project that spins up hundreds of concurrent users, each of which is slamming our WCF test server with XML artifacts that get loaded into the database. We've managed to load up to 160 packages (about 110kb - each per client) per second. WCF is not perfect, but it's quick, clean and scales really well.
My experience has been that your database will be your bottleneck, not your WCF web service. If your client wants to scale this archtecture up to an Amazon size web service, then you bring in an F5 load balancer and scale it up that way.

What is the best (widely accepted) way for sending data (messages) to server

I have a C# application (which is the client) and I have a server. Now the server gets and sends all sorts of messages which are strings to the client, I am using StreamWriter for this, now the sending message on the client and the server looks pretty the same, I take the string encode it to UTF-8 and then send it
public void SendMessage(String p)
{
if (p != "")
{
string StringMessage = HttpUtility.UrlEncode(p, System.Text.Encoding.UTF8);
try
{
swSender.WriteLine(StringMessage);
swSender.Flush();
}
catch (IOException e)
{
//do some stuff
}
}
}
now,the strings I send is something like this:
"SUBJECT####SOMEDATA1<><>SOMEDATA2<><>SOMEDATA3
This causes some problems, and makes me think. Is this the way big applications send/ receive data? Because it looks pretty silly. If no, then can some one provide an example on how big applications send messages?
Also: my way of sending messages makes me make big nested if
For example:
if(Subject="something")
do something
else if(subject="something else")
do something else
How can I fix this?
It all greatly depends on your application's needs.
Generally speaking: no, inventing your own protocol is not a good idea.
There are quite a few ways to send messages from client to server.
I'd suggest you to do some reading on WCF, or if you are in .NET 2.0 than .NET Remoting.
Also, you might want to consider to send HTTP messages, as there are a shitload of frameworks to do that.
One way is to use XML-RPC. I used this for .NET. I followed the instructions w/o modifying it and got the client/server working within 30mins and another 10 to modify it to my liking. Essentially you call functions normally and through the magic of the library it will block for the server to execute the code and it will return results. RPC = remote procedure call.
If your using asp.net use the instructions labeled IIS even if your on linux using fastcgi or apache. I ignored that which was a mistake because it was labeled IIS. There is a .NET Remoting option (if the server isnt asp.net but another app) thats available.
A not as good option is to learn webclient and post json strings to the server. Then read the response as json. XML-RPC is pretty standard and suggested.
try to use HttpUtility.HtmlEncode Method
instead UrlEncode()

Categories

Resources