1. 程式人生 > >Socket.IO實現簡單聊天室

Socket.IO實現簡單聊天室

Socket.IO介紹

官方文件
https://socket.io/docs/

Socket.io是一個跨瀏覽器支援WebSocket的實時通訊的JS。它不僅簡化了介面,使得操作更容易,而且對於那些不支援WebSocket的瀏覽器,會自動降為Ajax連線,最大限度地保證了相容性。它的目標是統一通訊機制,使得所有瀏覽器和移動裝置都可以進行實時通訊。
Socket.io實際上是WebSocket的父集,Socket.io封裝了WebSocket和輪詢等方法,會根據情況選擇方法來進行通訊。
Socket.io將WebSocket和Polling機制以及其它的實時通訊方式封裝成通用的介面,並在服務端實現了這些實時機制相應程式碼。這就是說,WebSocket僅僅是Socket.io實現實時通訊的一個子集,那麼Socket.io都實現了Polling中那些通訊機制呢?

 Adobe Flash Socket
 大部分PC瀏覽器都支援的Socket模式,不過是通過第三方嵌入到瀏覽器,不在W3C規範內,可能將逐步被淘汰。況且,大部分手機瀏覽器並不支援此種模式。
 AJAX Long Polling
 定時向服務端傳送請求,缺點是給服務端帶來壓力並出現資訊更新不及時的現象。
 AJAX multipart streaming
 在XMLHttpRequest物件上使用某些瀏覽器支援的multi-part標誌,AJAX請求被髮送給服務端並保持開啟狀態(掛起狀態),每次需要向客戶端傳送資訊,就尋找一個掛起的HTTP請求響應給客戶端,並且所有的響應都會通過統一連線來寫入。
 Forever Iframem
 永存的Iframe設計了一個置於頁面中隱藏的iframe標籤,該標籤的src屬性指向返回服務端時間的Servlet路徑。每次在事件到達時,Servlet寫入並重新整理一個新的Script標籤,該標籤內部帶有JS程式碼,iframe的內容被附加上script標籤,標籤中的內容就會得到執行。這種方式的缺點是接收資料都是由瀏覽器通過HTML標籤來處理的,因此無法知道連線何時在哪一端被斷開,而且iframe標籤在瀏覽器中將被逐步取消。
 JSONP Polling
 JSONP輪詢基本與HTTP輪詢一樣,不同之處則是JSONP可發出跨域請求

聊天室實現

伺服器端:

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);

server.listen(8080);

app.get('/chat3',(req,res) => {
	res.sendFile(__dirname + '/www/chat3.html')
})
app.get('/chat4',(req,res) => {
	res.sendFile(__dirname + '/www/chat4.html')
})

io.on('connection', (socket) => {
	console.log('客戶端與服務端連線成功')
	//監聽客戶端的訊息
	socket.on('message',(data) => {
		console.log(data)
		//將資訊發給每個人
		io.emit('message',data);
	})
	//斷開連線
	socket.on('disconnect', () => {
        console.log('連線已斷開...');
    });
})

客戶端:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://static.wanlianjin.com/data/m/wlcs/js/nocar/jquery-1.7.2.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="/socket.io/socket.io.js"></script>
</head>
<body>
    <ul id="messages"></ul>
    <input id="m" autocomplete="off" /><button>Send</button>
    <script>
        var socket = io();
        $('button').click(() => {
            //傳送訊息
            socket.emit('message',{'messages':'小明'+$('#m').val()});
            $('#m').val('')
        })
        //接收訊息
        socket.on('message', (data) => {
            console.log(data)
            $('#messages').append('<li>'+ data.messages +'</li>')
        })
    </script>
</body>
</html>