根據指南,咱們來建立一個聊天應用。css
使用流行的技術棧(例如PHP)去寫一個聊天應用傳統意義上是比較難的。這樣涉及到了服務器的輪詢,跟蹤時間戳,並且應該是比較慢的。
Socket解決了大多數的實時聊天方案,在客戶端和服務端提供實時的雙向通道。這就意味着服務端能夠向客戶端推送消息。當你發送一條消息,服務端能夠得到而後推送到其餘鏈接的客戶端。html
第一步就是建立一個html頁面,提供表單和消息列表。咱們準備使用node的web框架express。首先建立package.json配置文件。node
{ "name" : "socket-chat-example", "version" : "0.0.1", "description" : "my first socket.io app", "dependencies" : {} }
而後安裝express:jquery
npm install express --save-dev
express安裝後,咱們在當前目錄下建立一個index.js文件設置咱們的應用。web
var app = require('express')() var http = require('http').Server(app) app.get('/', function(req, res) { res.send('<h1>hello world</h1>') }) http.listen(3000, function() { console.log('listening on 3000') })
如上:express初始化一個應用程序是能夠提供給http服務的函數處理程序;咱們定義了一個路由當咱們進入主目錄時被調用;咱們建立了一個監聽3000端口的http服務。
咱們執行node index.js能夠看到:express
打開瀏覽器,輸入http://localhost:3000能夠看到:npm
目前,咱們準備在index.js文件中調用res.send()發送一個html字符串。若是咱們把整個html字符串都放在裏面,那樣看起來會很混亂。那麼,咱們準備建立一個index.html文件,而後發送。json
//這裏咱們經過sendFile這個方法 app.get('/', function(req, res){ res.sendFile(__dirname + '/index.html'); }); `` 建立index.html文件:
<!doctype html>
<html>
<head>瀏覽器
<title>Socket.IO chat</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } </style>
</head>
<body>服務器
<ul id="messages"></ul> <form action=""> <input id="m" autocomplete="off" /><button>Send</button> </form>
</body>
</html>
而後重啓服務,打開瀏覽器能夠看到以下: ![clipboard.png](/img/bVXQoz) ##### **Integration Socket.IO** Socke.IO有兩部分組成:
在開發期間,socket.io會自動的服務客戶端,因此目前咱們只要安裝該模塊:
npm install socket.io --save-dev
而後從新修改index.js:
var app = require('express')()
var http = require('http').Server(app)
var io = require('socket.io')(http)
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html')
})
io.on('connection', function(req, res) {
console.log('a user connected')
})
http.listen(3000, function() {
console.log('listening on 3000')
})
如上,能夠看到傳入http服務初始化一個socket.io實例,而後經過connection事件監聽新鏈接。 而後再修改如下index.html文件,在</body>後插入如下代碼:
<script src="https://cdn.bootcss.com/sockj...;></script>
<script>
var socket = io();
</script>
如上就是加載socket.io-client的所有內容,它能夠暴露一個全局的io,而後進行鏈接。 注意上面,當調用io()的時候並無特別指定任何url, 所以它默試圖鏈接到服務頁面的主機。 若是你從新加載服務和網站,你能夠看到控制檯中打出"a user connected",當你從新開幾個網頁的時候也能夠看到控制檯中打印出"a user connected"。 每個socket還能夠觸發一個disconnect事件:
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
從新啓動,而後打開連接後刷新,能夠看到以下: ![clipboard.png](/img/bVXQIk) ##### **Emitting events** Socket.IO背後的思想是你能夠發送和接受任何你想要的事件,且伴隨着你想要的數據。任何能夠被編碼成JSON的對象和二進制數據均可以。 接下來,當用戶輸入消息時,服務器經過一個chat message事件得到。修改頁面腳本文件:
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquer...;></script>
<script>
$(function () {
var socket = io(); $('form').submit(function(){ socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; });
});
</script>
而後修改下index.js文件:
io.on('connection', function(socket){
socket.on('chat message', function(msg){
console.log('message: ' + msg);
});
});
##### **Broadcasting** 下一個目標就是將事件從服務器發送到其餘用戶。爲了將使勁按發送給每一個用戶,Socket.IO提供給咱們一個**io.emit:**
io.emit('some event', {for : "everyone"})
若是你想發送消息給每一個用戶除了當前用戶。這裏提供了一個**broadcast**:
io.on('connection', function(socket) {
socket.broadcast.emit('hi')
})
在這種狀況下,爲了簡單起見咱們將消息發送給每一個人,包括髮送者。
io.on('connection', function(socket) {
socket.on('chat message', function(msg) { io.emit('chat message', msg) })
})
在客戶端這邊,當咱們捕捉到chat message事件,咱們會將消息加入頁面中:
<script>
$(function () {
var socket = io(); $('form').submit(function(){ socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; }); socket.on('chat message', function(msg){ $('#messages').append($('<li>').text(msg)); });
});</script>