Use Node.js+socket.io to build websocket real-time applications
Real-time push technology in the web domain is also called realtime technology. The purpose of this technology is to allow users to get real-time updates without having to refresh their browsers. It has a wide range of application scenarios, such as online chat rooms, online customer service systems, commenting systems, WEBIM, etc.
WebSocket Introduction
When it comes to web real-time push, you have to say websocket. Before the advent of WebSocket, many Web sites in order to implement real-time push technology, the usual approach is polling (Polling) and comet technology, comet can be subdivided into two implementations, one is the long polling mechanism, a kind of called streaming technology, these two methods are actually the improvement of polling technology, These scenarios have obvious drawbacks, requiring the browser to issue HTTP request to the server, which consumes server bandwidth and resources heavily. In the face of this situation, HTML5 defines the WebSocket protocol to better conserve server resources and bandwidth and achieve real real-time push.
WebSocket protocol is essentially a TCP-based protocol, which consists of communication protocols and programming APIs, WebSocket can establish a two-way connection between the browser and the server, in an event-based manner, giving the browser real-time communication capabilities. Since it is two-way communication, it means that the server side and the client can send and respond to the request at the same time, instead of requesting and responding like HTTP.
In order to establish a WebSocket connection, the client browser first initiates an HTTP request to the server, which differs from the usual HTTP request and contains additional header information, with the additional header information "Upgrade:websocket" Indicates that this is an application protocol upgrade HTTP request, the server side to resolve these additional header information and then generate the response information returned to the client, the client and server side of the WebSocket connection is established, the two sides can pass through this connection channel free information, And the connection persists until either the client or the server side actively closes the connection.
A typical WebSocket client request header:
As mentioned earlier, WebSocket is a new communication protocol in HTML5, which means that some older browsers (mainly IE10 below) do not have this feature, and the public data from Baidu statistics show that IE8 is still at the top of 33% market share. Fortunately, the market share of the Chrome browser is rising year by day, with more than 26% market share second, while Microsoft announced the end of the technical support for IE6 and prompted users to update to the new version of the browser, which has been a headache for many front-end engineers, the browser is expected to exit the historical stage, Plus almost all of the smartphone browsers support HTML5, so WebSocket's real-world significance increases, but in any case, we still have to consider the compatibility of low-version browsers in our actual projects: using new technologies in a browser that supports WebSocket, In browsers that do not support websocket, comet is enabled to receive messages.
WebSocket Combat
This article will use the multiplayer live chat app as an example scenario, and we'll start by identifying the basic needs of this chat application.
Demand analysis
1. Compatible with low-version browsers that do not support websocket.
2, allow the client to have the same user name.
3, enter the chat room can see the current online users and online number.
4, users on-line or exit, all online clients should be updated in real-time.
5, the user sends the message, all clients collect in real time.
In the actual development process, in order to use the WebSocket interface to build a Web application, we first need to build a implementation of the WebSocket specification of the service side, the implementation of the server is not limited by the platform and development language, only need to comply with websocket specifications, At present, there are some more mature WebSocket server implementations, such as the node.js+socket.io used in this paper. Why choose this option? Let's start with a brief introduction to both of them.
node. js
node. js, written in the C + + language, is not a JavaScript application, but a JavaScript operating environment, according to the memory of node. JS founder Ryan Dahl, He initially wanted to use Ruby to write node. js, but later found that the performance of the Ruby virtual machine did not meet his requirements, and later he tried to use the V8 engine, so he chose the C + + language.
node. JS supports systems including *nux, Windows, which means programmers can write system-level or server-side JavaScript code and give it to node. js to explain execution. node. JS's Web Development Framework Express helps programmers build Web sites quickly, and since 2009, node. JS has grown at a remarkable pace, and its development prospects have been fully affirmed by the technical community.
Socket.io
Socket.io is an open-source WebSocket library that implements the WebSocket server through node. JS and also provides a client JS library. Socket.io supports event-based real-time bidirectional communication, which can work on any platform, browser or mobile device.
Socket.io supports 4 protocols: WebSocket, Htmlfile, xhr-polling, jsonp-polling, which automatically selects the appropriate communication method according to the browser, so that developers can focus on the implementation of the function rather than the compatibility of the platform, At the same time Socket.io has good stability and performance.
Encoding implementation
First on the demo:
Click here to view the online demo. The entire development process is very simple and the following is a simple record of the development steps:
Install node. js
Depending on your operating system, go to the node. JS website to download and install. If the installation is successful. Enter node -v
and npm -v
should be able to see the corresponding version number on the command line.
Node-v v0.10.26 npm-v 1.4.6
Build WebSocket Service Side
This link we as far as possible to consider the real production environment, the WebSocket back-end service to build a line can be accessed by domain name services, if you are in the local development environment, you can switch to a local IP address, or use a virtual domain name to point to the local IP.
First go to your working directory, for example /workspace/wwwroot/plhwin/realtime.plhwin.com
, create a new file named, with the package.json
following content:
{ "name": "Realtime-server", "version": "0.0.1", "description": "My first realtime Server", " Dependencies ": {}}
Next use npm
the command to install express
andsocket.io
NPM Install--save expressnpm install--save Socket.io
After successful installation, you should be able to see the working directory generated a folder called ' Node_modules ', which is ' Express ' and ' Socket.io ', then you can start to write the server code, create a new file: ' Index.js '
var app = require (' Express ') (); var http = require (' http '). Server (APP), var io = require (' Socket.io ') (HTTP), App.get ('/', function (req, res) { res.send ('
Command line runs node index.js
, if everything goes well, you should see the listening on *:3000
words returned, which indicates that the service has been successfully built. http://localhost:3000
you should be able to see the normal Welcome page when you open it in the browser.
If you want to let the service run on-line server, and can be accessed through the domain name, you can use Nginx Proxy, and then add the following configuration nginx.conf, and then the domain name (such as: realtime.plhwin.com) resolution to the server IP.
Server { listen ; server_name realtime.plhwin.com; Location/{ proxy_pass http://127.0.0.1:3000; } }
After completing the above steps, http://realtime.plhwin.com:3000
the backend service is set up normally.
Service-Side Code implementation The preceding index.js
runs on the server, the previous code is just a simple webserver welcome content, let us put the complete implementation code of the WebSocket server to join in, the entire server can handle the client's request. The complete index.js
code is as follows:
var app = require (' Express ') (); var http = require (' http '). Server (APP), var io = require (' Socket.io ') (HTTP), App.get ('/', function (req, res) {res.send (' Client code ImplementationGo to the client working directory /workspace/wwwroot/plhwin/demo.plhwin.com/chat
and create a new one index.html
:
<! DOCTYPE html>
<meta charset= "Utf-8" >
<meta name= "format-detection" content= "Telephone=no"/>
<meta name= "format-detection" content= "Email=no"/>
<meta content= "Width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" name = "Viewport" >
<title> Multi-person chat room </title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<!--[if lt IE 8]><script src="./json3.min.js"></script><![endif]-->
<script src="http://realtime.plhwin.com:3000/socket.io/socket.io.js"></script>
<body>
<div id= "Loginbox" >
<div style= "width:260px;margin:200px auto;" >
Please enter your nickname in the chat room first <br/><br/>
<input type= "text" style= "width:180px;" placeholder= "Please enter user name" id= "username" name= "username"/>
<input type= "button" style= "width:50px;" value= "Submit" onclick= "Chat.usernamesubmit ();" />
</div>
</div>
<div id= "Chatbox" style= "Display:none;" >
<div style= "background: #3d3d3d; height:28px; width:100%;font-size:12px; " >
<div style= "Line-height:28px;color: #fff;" >
<span style= "text-align:left;margin-left:10px;" >websocket Multi-person chat room </span>
<span style= "float:right; margin-right:10px; " ><span id= "Showusername" ></span>| <a href= "javascript:;" onclick= "Chat.logout ()" style= "color: #fff;" > Exit </span>
</div>
</div>
<div id= "Doc" >
<div id= "Chat" >
<div id= "message" class= "message" >
<div id= "Onlinecount" style= "Width:background: #EFEFF4; font-size:12px; margin-top:10px; margin-left:10px; Color: #666; " >
</div>
</div>
<div class= "Input-box" >
<div class= "Input" >
<input type= "text" maxlength= "placeholder=" Please enter chat content, press CTRL to submit "id=" Content name= "Content" >
</div>
<div class= "Action" >
<button type= "button" id= "Mjr_send" onclick= "Chat.submit ();" >
Submit
</button>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="./client.js"></script>
</body>
The above HTML content itself is nothing to say, we mainly look at the inside of the 4 file request:
1, Realtime.plhwin.com:3000/socket.io/socket.io.js
2, Style.css
3, Json3.min.js
4, Client.js
The 1th JS is Socket.io provided by the client JS file, in front of the installation of the service side of the steps, when NPM installed Socket.io and set up webserver, the JS file will be able to access the normal.
The 2nd style.css file Nothing to say, is the style file just.
The 3rd JS only in IE8 version of the Internet Explorer to load, the purpose is to allow these low version of IE browser can also handle JSON, this is an open source JS, see: http://bestiejs.github.io/json3/
The 4th one client.js
is the full client's business logic implementation code, which reads as follows:
(function () {var d = document, W = window, p = parseint, DD = d.documentelement, db = d.body, DC = D.C Ompatmode = = ' Css1compat ', dx = DC? DD:DB, EC = encodeuricomponent; W.chat = {Msgobj:d.getelementbyid ("message"), Screenheight:w.innerheight? W.innerheight:dx.clientheight, Username:null, Userid:null, socket:null,//Keep the browser scroll bar at the lowest scrolltobottom:function () { W.scrollto (0, this.msgObj.clientHeight); },//Exit, this example is just a simple refresh logout:function () {//this.socket.disconnect (); Location.reload (); },//Submit Chat message Content Submit:function () {var content = d.getElementById ("content"). Value; if (content! = ") {var obj = {Userid:this.userid, username:this.us Ername, content:content}; This.socket.emit (' message ', obj); D.gEtelementbyid ("Content"). Value = '; } return false; }, Genuid:function () {return new Date (). GetTime () + "" +math.floor (Math.random () *899+100); },//update system messages, in this case call Updatesysmsg:function (O, action) {//Current online user list var onlineus when user joins, exits) ers = o.onlineusers; Current number of online var onlinecount = O.onlinecount; New user-Added information var user = O.user; Update online number var userhtml = '; var separator = '; For (key in onlineusers) {if (Onlineusers.hasownproperty (key)) {userhtml + = Separator+onl Ineusers[key]; Separator = ', '; }} d.getElementById ("Onlinecount"). InnerHTML = ' current total of ' +onlinecount+ ' people online, online list: ' +userhtml; Add System message var html = '; HTML + = '
‘; HTML + = User.username; HTML + = (action = = ' login ')? ' joined the chat room ': ' exited the chat room '; HTML + = '‘; var section = d.createelement (' section '); Section.classname = ' System J-mjrlinkwrap j-cutmsg '; section.innerhtml = html; This.msgObj.appendChild (section); This.scrolltobottom (); },//First interface user submits user name Usernamesubmit:function () {var username = d.getElementById ("username"). Value; if (username! = "") {d.getElementById ("username"). Value = '; d.getElementById ("Loginbox"). Style.display = ' None '; d.getElementById ("Chatbox"). Style.display = ' block '; This.init (username); } return false; }, Init:function (username) {//client generates UID based on time and random number, which allows the chat room user name to be duplicated. In the actual project, if the user is required to log in, then directly using the user's UID to do the identification can be This.userid = This.genuid (); This.username = Username; d.getElementById ("Showusername"). InnerHTML = This.username; This.msgObj.style.minHeight = (this.screenheight-dB.clientheight + this.msgObj.clientHeight) + "px"; This.scrolltobottom (); Connect the WebSocket back-end server This.socket = Io.connect (' ws://realtime.plhwin.com:3000 '); Tell the server that a user is logged in this.socket.emit (' login ', {userid:this.userid, username:this.username}); Listen for new user login This.socket.on (' login ', function (o) {chat.updatesysmsg (o, ' login '); }); Listener user exits This.socket.on (' logout ', function (o) {chat.updatesysmsg (O, ' logout '); }); Listen for message send This.socket.on (' message ', function (obj) {var isme = (Obj.userid = = Chat.userid)? True : false; var contentdiv = '
' +obj.content+ ''; var usernamediv = ' +obj.username+ '; var section = d.createelement (' section '); if (isme) { section.classname = ' user '; section.innerhtml = Contentdiv + usernamediv; } else { section.classname = ' service '; section.innerhtml = Usernamediv + contentdiv; } CHAT.msgObj.appendChild (section); Chat.scrolltobottom ();} ); } ; The user name d.getElementById ("username") is submitted via "enter". onkeydown = function (e) { e = e | | event; if (E.keycode = = =) { chat.usernamesubmit (); } }; Submit information via "Enter" d.getElementById ("content"). onkeydown = function (e) { e = e | | event; if (E.keycode = = =) { chat.submit (); } };}) ();
Now that all the coding development work is done, open the http://demo.plhwin.com/chat/in the browser to see the effect, and later I will submit the demo code on GitHub.
This example is just a simple demo, leaving 2 thoughts about the project extension:
1, the assumption is an online customer service system, there are many companies use your services, each company's own users can enter the company's chat room through a dedicated URL address, chat is one-to-one, each company can create a new number of customer service personnel, each customer service personnel can simultaneously and the client's multiple users chat.
2, also assumed to be an online Webim system, to achieve similar, QQ function, the client can see friends online status, online list, add friends, delete friends, new groups, etc., the message in addition to support the basic text, but also support emoticons, pictures and files.
Interested students can continue in-depth study.
Use Node.js+socket.io to build websocket real-time applications