一般咱们web使用的是http协议,可是 HTTP 协议有一个缺陷:通讯只能由客户端发起。html
因此咱们须要一个能够由服务端主动发出的协议,即WebSocket。node
WebSocket是HTML5新增的一种通讯协议,其特色是服务端能够主动向客户端推送信息,客户端也能够主动向服务端发送信息,是真正的双向平等对话,属于服务器推送技术的一种。jquery
Socket.IO 是一个基于 Node.js 的实时应用程序框架,在即时通信、通知与消息推送,实时分析等场景中有较为普遍的应用。web
socket.io 包含两个部分:express
固然,socket.IO构架在一个nodejs服务上,这里开启一个express服务。npm
建立文件夹socketIODemo,而后安装浏览器
npm init -y
npm install express --save
以后在socketIODemo中建立文件index.js:服务器
const express = require('express') const app = express() app.use(express.static(__dirname + '/public')); app.listen(3000, () => console.log('Example app listening on port 3000!'))
建立静态资源public/index.html :app
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } .chat { float: left; padding: 1em 1em 0 2em; height: 100%; width: 500px; border-right: 1px solid #DA4; overflow-y: scroll; } .inputpart { float: left; margin-left: 10px; } #userName { font-size: 20px; color: rgb(3, 57, 109); } </style> </head> <body> <div class="chat"> <ul id="messages"> //聊天信息 </ul> </div> <div class="inputpart"> <div id="userName"> //用来展现用户id </div> <form action=""> <input autocomplete="off" id="inpB" /><button id="say">Send</button> </form> </div> </body> </html>
此时开启服务: node index, 访问localhost:3000。框架
服务开启!
安装:
npm install socket.io --save
而后在index.js中注册socket.io,并改成http监听:
let http = require('http').Server(app) const io = require('socket.io')(http) app.use(express.static(__dirname + '/public')); http.listen(3000, () => console.log('Example app listening on port 3000!'))
此时服务已改成WebSocket服务。
服务端运行后会在根目录动态生成socket.io的客户端js文件,客户端能够经过固定路径/socket.io/socket.io.js添加引用。
在HTML中引用js文件,并调用:
<script src="/socket.io/socket.io.js"></script> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <script> $(function () { var userName = ''; while ($('#userName').text().trim() === '') { //设置用户名 let promptName = prompt("请设置你的昵称", "") userName = promptName ? promptName + ':' : '未命名:'; $('#userName').text(userName); } let socket = io(); socket.on('connect', function () { socket.emit('join', userName) }) // 监听系统消息 socket.on('sys', function (sysMsg) { var message = '<div class="sysMsg">' + sysMsg + '</div>'; $('#messages').append(message); }); }) </script>
这段代码中,socket.on('connect', function () { })
为默认监听事件,socket.io 提供了默认事件(如:connect, message, disconnect)。也能够自定义。socket.emit('action');
表示发送了一个action命令,命令是字符串的。
后台index.js文件中:
io.on('connection', function (socket) { console.log('a user connected') let userID = '' socket.on('join', function (userName) { userID = userName; io.emit('sys', userID + '已加入房间'); console.log(userID + '加入了'); }); })
connection事件在客户端成功链接到服务端时触发,有了这个事件,咱们能够随时掌握用户链接到服务端的信息。
当客户端成功创建链接时,在connection事件的回调函数中,咱们仍是能够为socket注册一些经常使用的事件,如:disconnect事件socket.on('disconnect',function(){...});
,它在客户端链接断开是触发,这时候我就知道用户已经离开了。
重启服务,打开多个窗口,查看聊天框内容:
下面添加聊天功能。
在HTML文件中添加事件监听click:
$('#say').click((e) => { e.preventDefault() socket.send($("#inpB")[0].value) $("#inpB")[0].value = '' }) socket.on('msg', function (userName, userColor, msg) { var message = ' <div class="message">' + `<span class="user" style="font-size:1.5em; color: #${userColor}">` + userName + '</span>' + ' <span class="msg">' + msg + '</span>' + '</div>'; $('#messages').append(message); // 滚动条保持最下方 $('#messages').scrollTop($('#messages')[0].scrollHeight); });
这段代码中,首先监听事件并将input中内容send回去;socket.on为自定义事件msg
用来接收后台发送来的其余人的发言。
socket.emit和socket.send的区别在stackoverflow中有一个解释大意是说emit能够自定义事件,而send不能够,且只能以message接收。
后台index.js:
io.on('connection', function (socket) { console.log('a user connected') let userID = '', userColor =parseInt(Math.random() * 16777216).toString(16) socket.on('join', function (userName) { userID = userName; io.emit('sys', userID + '已加入房间'); console.log(userID + '加入了'); }); socket.on('message', function (msg){ io.emit('msg', userID, userColor, msg) }) })
为新的成员随机匹配颜色,并将message监听到的信息经过自定义为msg
的事件emit出去。
此时,一个简易聊天室已经完成。
读者能够自行添加退出功能,或者设置多个房间。。。