Objective
Generally speaking, HTTP is a text-based "one-way" communication mechanism. Here the so-called "one-way" is relative to the "two-way", because the HTTP server only need to return the appropriate HTML to the client on request, does not involve the client to the server communication. This one-way mechanism is relatively simple, the network quality requirements are not high. More scenarios, however, require reliable, stable end-to-end connectivity. Generally this kind of service is real-time, the state and is the long connection, the long connection implied that two segments must achieve the opposite communication the ability, also said is the server client both can communicate with each other in real time between. There is no doubt that a server that can communicate in real time is just one of our basic requirements for servers. Different from HTTP server with HTTP as communication protocol, real time server uses TCP/IP for protocol communication, and realizes the bidirectional mechanism of "socket socket".
Socket is based on the Boclet (U.c.berkley) University of the early development of the socket concept, the idea is to use network transmission analogy to file read and write (the transfer of action is considered to be write/Receive action is considered read), so, The transfer and reception simplifies the reading and writing that programmers can easily understand, and reduces the learning difficulty of network programming.
Chat Room Server
The real-time connection of the chat room is based on the underlying TCP direct connection, so we need to call Node's TCP module. What if you're not familiar with the so-called TCP network programming? It's too low-level, isn't it? It doesn't matter, I am not familiar with, while learning to do, but do not have to encounter unfamiliar words and fear, in fact, this principle is not profound, and the following examples are very simple and understandable! Let's start with the simplest, the following code is only ten lines, it is the role of the server to the client output a piece of text, complete Sever--> client one-way communication.
Sever--> Client's one-way communication
var net = require (' net ');
var chatserver = Net.createserver ();
Chatserver.on (' Connection ', function (client) {
client.write (' hi!\n ');//server to client output information, using the Write () method
Client.write (' bye!\n ');
Client.end (); Server end of Session
});
Chatserver.listen (9000);
The client can be a system-brought Telnet:
After performing telnet, connect to the service point, feedback hi! bye! And immediately end the server-side program to terminate the connection. What if we want the server to receive information to the client? You can listen for server.data events and do not abort the connection (otherwise you will end up not accepting messages from the client):
On the former basis, the realization of the Client--> Sever communication, so that is bidirectional communication
var net = require (' net ');
var chatserver = Net.createserver (),
clientlist = [];
Chatserver.on (' Connection ', function (client) {
//JS can add attributes to the object freely. Here we add a custom attribute of name, which indicates which client (client address + port is based)
Client.name = client.remoteaddress + ': ' + client.remoteport;
Client.write (' Hi ' + client.name + '!\n ');
Clientlist.push (client);
Client.on (' Data ', function (data) {
broadcast (data, client);//Accept information from client
});
function broadcast (message, client) {for
(var i=0;i<clientlist.length;i+=1) {
if (client!== clientlist[i ] {
clientlist[i].write (client.name + "says" + message);
}} Chatserver.listen (9000);
The point here is that, unlike operating systems, the limits of the port range are different and may be random.
So is the above a full functional code? We say there is another problem that is not taken into account: once a client exits, it remains in the clientlist, which is clearly a null pointer (Nullpoint). If this is the case, we write the program is too fragile, can be more robust? --Please keep looking.
First we simply remove the client from the array clientlist. It's not difficult to finish the work. The Node TCP API has provided us with the end event, which occurs when the client aborts the connection to the server. The code to remove the client object is as follows:
Chatserver.on (' Connection ', function (client) {
Client.name = client.remoteaddress + ': ' + client.remoteport
Client.write (' Hi ' + client.name + '!\n ');
Clientlist.push (client)
client.on (' Data ', function (data) {
broadcast (data, client)
})
Client.on (' End ', function () {
Clientlist.splice (clientlist.indexof (client), 1);//delete the formulation element in the array. This is JS basic skills Oh ~
})
}
But we don't dare say the code is robust, because once the end is not triggered, the exception still exists. Here's a look at the solution: Rewrite broadcast ():
function broadcast (message, client) {
var cleanup = [] for
(var i=0;i<clientlist.length;i+=1) {
if ( Client!== Clientlist[i]) {
if (clientlist[i].writable) {//Check sockets writable
clientlist[i].write (Client.name + " Says "+ Message"
} else {
Cleanup.push (Clientlist[i])//If not writable, collect and destroy. Destroy the Socket.destroy () using the API method before destroying it.
Clientlist[i].destroy ()}}}
Remove dead Nodes out of the write loop to avoid trashing loop index for
(i=0;i<cleanup.length;i+=1) {
Clientlis T.splice (Clientlist.indexof (Cleanup[i)), 1
}}
The TCP API also provides an error event to catch the client's exceptions:
Client.on (' Error ', function (e) {
console.log (e);
Node Network Programming API is also rich, this is just a primer, more content please continue to look at the browser Socket application.
Socket.io
As mentioned earlier, although browsers are also part of the client, they only support "single work" HTTP traffic. In view of this, the HTML5 new specification introduced a browser-based WebSocket, developed the underlying interface, allowing us to do more powerful operations, beyond the previous XHR.
As in the first example, we do not need a third-party framework to communicate directly with the Node TCP server.
But we have to recognize the fact that not every browser can successfully support WebSocket. So Socket.io (Http://socket.io) appears, offering degraded support when WebSocket is not supported, and allowing older browsers to work "Full-duplex". The order of precedence is as follows:
- WebSocket
- Socket over Flash API
- XHR Polling Long Connection
- XHR Multipart Streaming
- Forever Iframe
- JSONP Polling
After encapsulation, we can not explore the client using the above technology to achieve "Full-duplex", and we write code, regardless of which way to consider, because Socket.io to our API only one set. It's OK to know Socket.io's usage.
First deploy the Socket.io front-end code in the browser:
Service-side Node code:
var http = require (' http '),
io = require (' Socket.io '),
fs = require (' FS ');
Although we use the Synchronized method here, it will block the Node's event loop, but this is reasonable because readfilesync () executes only once in the program cycle, and more importantly, the synchronization method avoids the "additional synchronization with Socketio" caused by the asynchronous method ”。 When the HTML file is read and the server is ready, executing in the order that the client can get the HTML content immediately.
var sockfile = fs.readfilesync (' socket.html ');
The Socket server is built on top of the HTTP server, so call Http.createserver ()
server = Http.createserver () first;
Server.on (' request ', function (req, res) {
//general HTTP output format
res.writehead ({' Content-type ': ' text/html '}); C10/>res.end (Sockfile);
});
Server.listen (8080);
var socket = Io.listen (server); Referred to Socket.io
//Socket.io True Connection event
Socket.on (' Connection ', function (client) {
Console.log (' Client Connected ');
Client.send (' Welcome client ' + Client.sessionid); Send the text to the client
});
When the client connects, the server departs at the same time two events: Server.onrequest and Socket.onconnection. What's the difference between them? The difference is that the Socket is persistent.
Multiple Socket connections, first client code:
Service-Side code:
var sockfile = Fs.readfilesync (' socket.html ');
Server = Http.createserver ();
Server.on (' request ', function (req, res) {
res.writehead ({' Content-type ': ' text/html '});
Res.end (Sockfile);
});
Server.listen (8080);
var socket = Io.listen (server);
Socket.of ('/upandrunning ')
. On (' Connection ', function (client) {
Console.log (' client connected to-up and Running namespace. ');
Client.send ("Welcome to ' up and Running '");
});
Socket.of ('/weather ')
. On (' Connection ', function (client) {
Console.log (' Client connected to weather namespace. ');
Client.send ("Welcome to ' Weather Updates");
});
As on the code, we can divide multiple namespaces, respectively, upandrunning and weather.
For the use of Soclet.io in Express, you can refer to the 7.2.2 section of the book "Node:up and Ruuning".
The relationship of the time tonight, involving many aspects of Socket.io has not been discussed, let me know later.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.