How does the node. js chat program implement the Ajax long-polling long-link refresh mode?

Source: Internet
Author: User

Let's talk about the theme today. Looking at this program, I feel that its most valuable part is to demonstrate how to use nodejs to implement the Refresh Technology of the persistent connection mode.
(This program is not described in detail and focuses on this function)
Client. js
First, let's take a look at the core code: Copy codeThe Code is as follows: function longPoll (data ){
//... The ** line is omitted here.
$. Ajax ({cache: false
, Type: "GET"
, Url: "/recv"
, DataType: "json"
, Data: {since: CONFIG. last_message_time, id: CONFIG. id}
, Error: function (){
AddMessage ("", "long poll error. trying again...", new Date (), "error ");
Transmission_errors + = 1;
// Don't flood the servers on error, wait 10 seconds before retrying
SetTimeout (longPoll, 10*1000 );
}
, Success: function (data ){
Transmission_errors = 0;
// If everything went well, begin another request immediately
// The server will take a long time to respond
// How long? Well, it will wait until there is another message
// And then it will return it to us and close the connection.
// Since the connection is closed when we get data, we longPoll again
LongPoll (data );
}
});
}

This is a piece of code in client. js. When you look at this code, you should immediately think of two words-"recursion ". In the longPoll method, call the longPoll method again, which is a typical recursive call.
According to the semantics of this code, we can see that the longPoll method will be called during the first loading, and the value will be obtained asynchronously from "/resv". If it succeeds, the success method will be executed, call the longPoll method again. If the call fails, run the error function and call the longPoll method again every 10 seconds. Of course, the execution of the error method has a certain number of times, which is controlled by the variable transmission_errorsx.
You may have a question: will the server have a great burden if data is obtained recursively and cyclically? Does this loop continue when no data is available? Of course, the answer is no! In addition, nodejs makes good use of its own characteristics to solve this problem. Next, let's look:
Server. js
The core code is as follows:Copy codeThe Code is as follows: fu. get ("/recv", function (req, res ){
// Verify and update the session ......
Channel. query (since, function (messages ){
If (session) session. poke ();
Res. simpleJSON (200, {messages: messages, rss: mem. rss });
});
});

Don't worry about what this fu. get () means. It has nothing to do with this tutorial. In short, you just need to know that it can respond to the client call. In addition to some session operations, the above Code only calls the channel query method. Note:
Since, which records a time;
The anonymous method accepts a messages parameter. Two actions: 1. Update the session time, 2. Return a json value, that is, return messages to the client.
Some people may have doubts: is it not possible to directly return messages here? Why do I have to define a method in a channel to operate? Answer: If so, it becomes an endless loop. The server and client interact with each other every moment, even if there is no information to return.
Let's take a look!
See how channel is defined:Copy codeCode: var MESSAGE_BACKLOG = 200,
SESSION_TIMEOUT = 60*1000;
Var channel = new function (){
Var messages = [],
Callbacks = [];
This. appendMessage = function (nick, type, text ){
Var m = {nick: nick
, Type: type // "msg", "join", "part"
, Text: text
, Timestamp: (new Date (). getTime ()
};
Switch (type ){
Case "msg ":
Sys. puts ("<" + nick + ">" + text );
Break;
Case "join ":
Sys. puts (nick + "join ");
Break;
Case "part ":
Sys. puts (nick + "part ");
Break;
}
Messages. push (m );
While (callbacks. length> 0 ){
// Shift () is used to delete the first element of the array from it and return the value of the first element.
Callbacks. shift (). callback ([m]);
}
While (messages. length> MESSAGE_BACKLOG)
Messages. shift ();
};
This. query = function (since, callback ){
Var matching = [];
For (var I = 0; I <messages. length; I ++ ){
Var message = messages [I];
If (message. timestamp> since)
Matching. push (message)
}
If (matching. length! = 0 ){
Callback (matching );
} Else {
Callbacks. push ({timestamp: new Date (), callback: callback });
}
};
// Clear old callbacks
// They can hang around for at most 30 seconds.
SetInterval (function (){
Var now = new Date ();
While (callbacks. length> 0 & now-callbacks [0]. timestamp> 30*1000 ){
Callbacks. shift (). callback ([]);
}
},3000 );
};

The channel defines two variables, two methods, and a setInterval function that is executed every 3 seconds.
First, let's look at the query method,
The query method receives two parameters:
Since: record a time
Callback: The anonymous function passed in when the channel. query method is called. (In JS, the function can be called directly after the parameter is passed and received. I don't want to make up the course soon ...)
The query method searches for matching chat records and places them in the matching queue. If matching. length> 0, call the function received by callback to return matching to the client in json format. But... Next is the focus !!!Copy codeThe Code is as follows: if (matching. length! = 0 ){
Callback (matching );
} Else {
Callbacks. push ({timestamp: new Date (), callback: callback });
}

If matching. length <= 0, the program saves the callback and current time in json format to a callbacks queue. Yes! No execution. Because there is no matching chat message and it does not need to be displayed on the client, this function is saved first and not executed first.
It cannot be stored like this. What if someone sends a chat message in the next second?
Next, let's look at the appendMessage (adding chat messages) method:
In this method, the previous part is easy to understand. It is nothing more than receiving input parameters, combining them into a m set, and then using sys. puts is displayed on the terminal and m is inserted into the messages chat message queue. Next, we will focus on:Copy codeThe Code is as follows: while (callbacks. length> 0 ){
// Shift () is used to delete the first element of the array from it and return the value of the first element.
Callbacks. shift (). callback ([m]);
}

Now you need to determine whether callbacks has been stored. If yes, execute one and delete the other until the execution is complete. Because when no chat message can be returned, someone sends a request, and the system does not execute these requests, they are all placed in the callbacks list.
Now someone has sent a chat message. When executing the add method, they need to execute all the unexecuted requests again.
In general, you can send a request to me. I have no new message to reply to you. Once someone sends a new message, I will reply to you immediately.
I don't know if you understand it...
This step is complete. The last step is to clear the expired callbacks every three seconds. It is a setInterval function, which is not hard to understand.
Summary
Nodejs uses its own event-driven language features to implement the long link refresh function, opening our eyes. I feel that I have benefited a lot. I would like to take the time to write a tutorial to share with you and deepen my understanding.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.