How the ilusion of causing site to change content from server side is done? Let the example be gmail chat or chat on facebook. Or even new message sign on stack overflow.
Is it done by http://en.wikipedia.org/wiki/Comet_(programming)) ?
Thanks for help
That sort of things is usually done with a block of JavaScript firing again and again according to a timer. It will check the state of the things in the database and adjust something in the markup. For instance, change the CSS class of some element to introduce a different color or a bold font, replace a picture with the one done in a brighter color etc. Quite simple really. No magic involved.
The client side has to 'poll' the server for changes. i.e. a timer based Ajax call that checks the server every 15 seconds for new data, and takes action based on the result.
very loose example:
setTimeout('checkMessages()',15000);
function checkMessages() {
//using jquery
$.get( .......... , function (data) { if (data == "newmsg") { $('#newmsgind').blink(); });
setTimeout('checkMessages()',15000);
}
Web browsers don't really maintain a connection to the server. You pull a page and that's it. Ajax allows continuous asynchronous communication, but it's always the client that initiates.
If you really don't like the javascript approach, you can write a Java applet that works the way you seem to prefer, maintaining an open connection to the server. But that's a heavyweight solution to what is usually a lightweight problem.
Related
I'm building a fairly simple single page app. It's basically a list of items, where each item has some details, an activity log, and a current status along with some buttons to trigger actions on the server to advance the status along a workflow.
It was originally written using MVC and REST/Web API but I got stuck on the problem of keeping concurrent users up to date. For example, if User A adds an item, we want the list on User B's screen to now update to include it.
To solve this I looked into SignalR which works great. But I had a problem.
When adding an item (using POST) the callback adds the item on the requesting client. This is fine.
I then triggered a SignalR broadcast on the server to tell all clients about the new item. This worked fine except the local client, who now has 2 items.
I was looking into filtering the duplicate id client-side, or sending the connection id with the POST, then broadcast to all clients except the requester but it seems a bit needlessly complicated.
Instead I'm just doing this.
public class UpdateHub : Hub
{
public void AddNewItem(NewItem item)
{
// and some server-side stuff, persist in the data store, etc
item.trackingID = new Guid();
item.addLogEntry("new item");
// ...
dataStore.addItem(item);
// send message type and data payload
Clients.All.broadcastMessage("add", item);
}
}
It seems a lot simpler to just get rid of all the REST stuff altogether, so am I missing anything important?
It'll run on an intranet for a handful of users using IE11+ and I guess we do lose some commonly-understood semantics around HTTP response codes for error handling, but I don't think that's a huge deal in this situation.
In order to solve duplicate you can try to use Clients.Others inside Hub class, or AllExcept(id) if you not in the Hub class.
Clients.Others.broadcastMessage("add", item);
In your case using SignalR shouldn`t have any downsides.
I'm developing a web application with C# MVC and using Session to persist data between multiple requests.
Sometimes the session timed out so I looked for way to keep it alive and found some solutions here in stackoverflow. Being reluctant to simply copy-paste code into my project I attempted to rewrite the code to fit my needs and understand it better.
At first I attempted to keep the session alive using the following code:
JS + jQuery - client side:
function keepAliveFunc(){
setTimeout("keepAlive()", 300000);
};
function keepAlive() {
$.get("/Account/KeepAlive", null, function () { keepAliveFunc(); });
};
$(keepAliveFunc());
C# - server side:
[HttpGet]
public bool KeepAlive()
{
return true;
}
This however did not seem to keep my session alive, it expired normally.
After a while of fiddling around I changed the code to:
JS + jQuery - client side:
function keepAliveFunc(){
setTimeout("keepAlive()", 10000);
};
function keepAlive() {
$.post("/Account/KeepAlive", null, function () { keepAliveFunc(); });
};
$(keepAliveFunc());
C# - server side:
[HttpPost]
public JsonResult KeepAlive()
{
return new JsonResult { Data = "Success" };
}
The latter worked well which has me conclude, with some uncertainty, that the Session is kept alive because of the POST request instead of the GET. Which raises the question: Why do I need to use POST when trying to keep my Session alive? What's the difference? Am I making some other mistake which I do not comprehend?
I've looked for answers but I cannot seem to find any on this matter, merely solutions without much explanation. Reading up on Session on MSDN also didn't help me much. This makes me conclude that there are some "words" related to Session and this perticular problem that I haven't encountered yet which makes me unable to google effectively.
With either GET or POST, the browser does send the SessionId cookie with the request. So for keep-alive purposes it doesn't matter which one you use. Most likely you are seeing the difference in behavior because of the different interval you and "pinging" the server.
With the GET request you did it at an interval of 300000 ms, while with the POST request you did it at an interval of 10000 ms.
Most likely, your server's session lifespan is somewhere between the two values.
You could, however, configure the session lifespan to fit your needs (as in increasing it), but keep in mind that expiring sessions is a security feature so try to find a small value that is big enough to let your application work ok, but still allow the session to expire in a safe interval of time.
I am working on a mutliplayer game and decided to use NodeJS aspart of the system.
The nodeJS is linked to m c# game emulator via TCP.
However how would I send messages to certain user ID?
Each individual user in the database is sided by a unique user ID (E.G 1)
How can I do this so if a user in game does a certain thing and that sends a message
from Node ONLY TO THEM.
Since I can't run node on the same port as my cms (Port 80).
I need a method in which I can use PHP to pull the ID or something.
Use as Jquery and 'GET'? I'm suck.
By message I mean data such as sending a javascript window.
Options available:
JQuery
Javascript
PHP
Node
I thought of a method were the user id is presented within a div through a parameter in PHP (E.G $ID) and then javascript checked against the div and the message to see if the ids matched. Then within the message the users ID would be included, then somehow I could split the message? so its "","" (ID,MESSAGE)
Code:
var socket = io.connect('http://dev.com');
socket.on('field', function (data) {
if ($("#userid").text().indexOf(data) > -1)
{
window.alert('lol');
console.log(data);
$("#field").html(data);
}
else
{
window.alert("Something has gone wrong with the node server...");
}
});
It didn't work.
THE PAGE:
THE C#:
THE NODE:
Based on your response in the comments:
Inside the messages are just html that node sends to the page via a Node HTTP server. The messages aren't big just little things like "window.open("google.com");. Messages are only triggered if a user clicks a certain thing within game and no.
It sounds to me like what you really want is some sort of RPC. There's a solid NPM module called Socket.IO which wraps all this up nicely for you. Fire an event, it can be handled server-side, and any callback data gets sent back to the client.
http://socket.io/docs/
I have a C# method from a web form that I want to call asynchronously with with either a Page Method, Web Method or possibly jQuery to avoid postback to the server. The method calls other methods and rebuilds a treeview and performs validation and sets some other values as well. Below is an example of the code.
What would be the simpleset way to do this?
Any code samples provided would be greatly appreciated if possible. No update Panels..
protected void btnSubmit_Click(object sender, ImageClickEventArgs e)
{
if (ValidateSelection() == true)
{
int ProductID = Convert.ToInt32(grdGetProducts.SelectedValue.ToString());
if (Convert.ToInt32(ddBetTypeID.SelectedItem.Value) != 2)
{
SubmitProduct(Convert.ToInt32(ddProductTypeID.SelectedItem.Value), currentWeek, Convert.ToInt32(ddProductID.SelectedItem.Value), Convert.ToInt32(ddValue.SelectedItem.Value), Convert.ToInt32(ddCost.SelectedItem.Value), ProductID);
}
if (Convert.ToInt32(ddProductTypeID.SelectedItem.Value) == 2)
{
int price;
price= 1;
//if 1 open side then part 2
if (txtProductID.Text != "0" && txt2ProductID.Text == "0")
{
price= 2;
}
if (ProductID > 2)
{
BuildTree(currentTime, Convert.ToInt32(ddProductID.SelectedItem.Value), currentProduct);
}
}
}
Without an update panel you are certainly going to need a lot of client side javascript.
I do things like this with dynamic tables all the time and the first thing I did was isolate my data and my display. You should start by doing the same.
Figure out what data is being validated and how you can gather it on the client to be sent to a web method. Then you need to write client scripts to do this gathering and posting. After you post with the client script, in the callback of the ajax call, you would then need to do the rendering on the page. Without an update panel this is all on you.
The issue you have without using an update panel is that you are going to have to recreate the treeview structure or manipulate it on the client side. This means replacing all the elements and their event handlers. This can be a very daunting task for the more complicated ASP controls.
What the server would need to send back for rendering would be all of the data the tree needs. It is on you to figure out what that is though.
I have dynamically rendered gridviews before because it is nice to use them to create complex styles. Then it is just a matter of creating rows with the script on the client, based on the data I get from the server; I imagine you can do something similar to this with a treeview.
I have learned a lot about jQuery, ajax and ASP.NET interactions by reading encosia.com. That individual is a wonderful resource.
Things to avoid using jQuery AJAX and ASP.NET
Mistakes: manual JSON serialization
Using jQuery to directly call asp.net page methods
Update Panels are Dangerous
I have a windows forms application that I am adding a request support form to, and would like the user to be able to input the values and hit a button. Once the button is pushed I can either:
Open a new mail message and auto populate the message. (Not sure how to do this)
Submit the request via a http form on my website. (I know how to do this)
Send an email directly from the code of the application. (I know how to do this)
What I want to know is what would be the best method to use? I think option 1 is the most transparent, and the user will see exactly what is being sent, but I am not sure how to ensure it works no matter what email client they use.
I see there being potential issues with option two, specifically a firewall possibly stopping the submission. But option 2 would allow me to supply them with a ticket number right then and there for their request.
Thanks for the help.
For Option 1, as suggested, use the mailto handler.
Format your string like so: string.Format("mailto:support#example.com?subject={0}&body={1}", subject, body). Don't forget to UrlEncode the subject and body values.
Then use System.Diagnostics.Process.Start() with your string.
This will launch the registered mail handler (Outlook, Windows Live Mail, Thunderbird, etc) on the system.
For option 1 : If the message body is short, then invoking the mailto handler from inside your code no longer requires that they be using outlook. It's kinda a cheap hack, but it's completely cross-platform for local mail clients. (If they're using something like gmail, you're still SOL, though)
Option 2) is the best to avoid enterprise firewall issues because the HTTP port may not be blocked.
Option 2) is the best for simple configuration. The only config key you will have is the service/page url. Then your SMTP configuration will stay on your webserver.
Now you will have to choose between using a webpage (if one already exists) or a webservice (which is best fitted for your feature).
For option (1) be prepared to deal with Outlook version problems. But this is not hard (again if we are talking about Outlook, last version)
//using Microsoft.Office.Interop.Outlook;
private void OutlookMail(string Subject, string Body)
{
ApplicationClass app = new ApplicationClass();
NameSpaceClass ns = (NameSpaceClass)app.GetNamespace("mapi");
ns.Logon("", "", true, true);
MailItem mi =
(MailItem)app.CreateItem(OlItemType.olMailItem);
mi.Subject = Subject;
int EOFPos = Body.IndexOf(char.Parse("\0"));
if (EOFPos != -1)
{
log.Error("EOF found in Mail body");
ErrorDialog ed = new ErrorDialog(TietoEnator.Common.ErrorDialog.ErrorDialog.Style.OK, "Export Error", "File could not be exported correctly, please inform responsible person", "", "EOF char detected in the body of email message.");
ed.ShowDialog();
Body=Body.Replace("\0", "");
}
mi.HTMLBody = "<html><head><META content='text/html; charset=CP1257' http-equiv=Content-Type></head><body><table>"+Body+"</table></body></html>";
mi.BodyFormat = OlBodyFormat.olFormatHTML;//.olFormatPlain;
mi.Display(0); // show it non - modally
ns.Logoff();
}
BTW for automatic support requests I plan to use in my current project "Microsoft Enterprise Logging Support Block" email sending functionality.