介绍
通常我们web使用的是http协议,但是 HTTP 协议有一个缺陷:通信只能由客户端发起。
所以我们需要一个可以由服务端主动发出的协议,即WebSocket。
WebSocket是HTML5新增的一种通信协议,其特点是服务端可以主动向客户端推送信息,客户端也可以主动向服务端发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
Socket.IO 是一个基于 Node.js 的实时应用程序框架,在即时通讯、通知与消息推送,实时分析等场景中有较为广泛的应用。
socket.io 包含两个部分:
- 服务器端(server):运行在 Node.js 服务器上
- 客户端(client):运行在浏览器中
开启服务
当然,socket.IO构架在一个nodejs服务上,这里开启一个express服务。
创建文件夹socketIODemo,然后安装
npm init -y
npm install express --save
之后在socketIO中创建文件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 :
<!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。
服务开启!
使用socket.IO
安装:
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出去。
此时,一个简易聊天室已经完成。
读者可以自行添加退出功能,或者设置多个房间。。。
原文地址:https://www.cnblogs.com/coldant/p/10437220.html