在上一篇讲了 npm 上最流行的 WebSocket 库之一的 ws 库,那么本篇就来讲另外一个,就是 socket.io 库,socket.io 其实是一个兼容方案,当浏览器不支持 H5 的情况下就不能够使用上一篇内容讲的 WebSocket ,只能采用其他的方案,socket.io 就解决了关于浏览器的兼容。
Node实现 Socket 通信 | WebSocket 通信 —— 浏览器原生支持
Socket.io 库地址: Socket.IO
下面来使用 socket.io 库来实现服务器与客户端的通信:
引入 Socket.io
打开 CMD 命令窗口切到待定目录下,使用如下命令进行安装 socket.io 库;
npm i socket.io
安装完成这里仅需要从 node_modules 中去找到一个 socket.io.js文件,路径如下:(后面会用到)
/node_modules/socket.io/client-dist/socket.io.js
—— 客户端
这里的客户端界面还是使用前面所用的 html文件,使用script标签引入 socket.ios.js 之后就来进行与服务端接口的连接操作;这里为了不与 html 文件搞混,将其分离出来使用script标签引入;
SocketIO.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./socket.io.js" type="text/javascript"></script>
<script src="./SocketIOClient.js"></script>
<style>
.chatroom{
height: 400px;
width: 220px;
border: 1px solid blue;
padding: 5px;
overflow: scroll;
}
.footer{
margin-top: 10px;
}
</style>
</head>
<body>
<h3>Socket.IO 客户端</h3>
<div id="chatroom" class="chatroom"></div>
<div class="footer">
<input type="text" name="sayinput" id="sayinput" value="" />
<input type="button" name="send" id="sendbutton" value="发送" />
</div>
</body>
</html>
SocketIOClient.js 文件 —— 接入服务端
var iosocket = null
window.onload = function () {
// 连接
iosocket = io.connect('http://127.0.0.1:9000')
iosocket.on('connect',function(){
iosocket.send('— — 已上线 — —')
})
// 收集
iosocket.on('message',function(message){
var chatroom = document.querySelector('#chatroom');
chatroom.innerHTML += '<br/>' + message
})
// 关闭
iosocket.on('disconnect',function(){
console.log('服务器关闭');
})
// 发送
function send(){
iosocket.send(sayinput.value)
sayinput.value = ''
}
// 回车
document.onkeyup = function (event) {
if (event.key = '13'){
send()
}
}
// 按钮
sendbutton.onclick = function () {
send()
}
}
内容与之前讲过WebSocket的一些操作没有太大的差异处理,这里也不再过多赘述!
—— 服务端
安装 express 框架
引入 socket.io
var socket = require('socket.io')
// 服务端
// var app = require('express')()
var express = require('express')
var app = express()
var http = require('http').Server(app)
// var socket = require('socket.io')
// var io = socket(http)
var io = require('socket.io')(http)
var fs = require('fs');
app.get('/', function (req, res) {
function callback(data) {
res.send(data.toString())
}
fs.readFile('./SocketIo.html', function (err, data) {
if (err) {
console.log(err);
callback('文件不存在')
} else {
callback(data)
}
})
})
// socket.io设置
// 在线用户
var onlineUsers = {}
var i = 0
io.on('connection', function (socket) {
console.log('有人连上来了~');
//监听新用户的加入
socket.name = '用户' + ++i
onlineUsers[socket.name] = socket
// 监听用户退出
socket.on('disconnect', function () {
console.log('有人退出');
delete onlineUsers[socket.name]
})
// 监听用户发布聊天内容
socket.on('message', function (msg) {
broadcast(msg, socket)
})
})
function broadcast(msg, socket) {
for (var key in onlineUsers) {
onlineUsers[key].send(socket.name + ' : ' + msg)
}
}
http.listen(9000, function () {
console.log('Port:9000 | Running ...');
})
以上这么写会有什么问题,下面来测试一下:
服务端正常运行,下来来看一下客户端,通过浏览器访问 http://127.0.0.1:9000 ,会出现的是客户端的网页HTML文件(./SocketIO.html);
可以使用静态资源进行托管,即在创建一个public文件夹,将托管文件放置到该文件夹下,使用如下命令:
app.use(express.static('public'))
或者也可以这样,设置 app.get('/...') 这样的形式访问:
app.get('/SocketIOClient.js',function(req,res){
fs.readFile('./public/SocketIOClient.js',(err,data)=>{
res.send(data)
})
})
app.get('/socket.io.js',function(req,res){
fs.readFile('./public/socket.io.js',(err,data)=>{
res.send(data)
})
})
script标签
<script src="./socket.io.js" type="text/javascript"></script>
<script src="./SocketIOClient.js"></script>
这里需要注意的就是这个script的请求路径问题了,在之前讲静态资源托管讲过了,可以回去翻阅温故,下面来测试一下:
再来开启一个客户端,使 用户2 上线:
分别来进行发送信息:
以上就是本篇的全部内容了,感谢大家的支持!如果前面有不理解的最后面附上完整的代码,需要注意的是相应的依赖包需要自行下载,express 和 socket.io :
// var app = require('express')()
var express = require('express')
var app = express()
// var http = require('http')
// var server = http.Server(app)
var server = require('http').Server(app)
// var socket = require('socket.io')
// var io = socket(http)
var io = require('socket.io')(server)
var fs = require('fs');
// app.use(express.static('public'))
app.get('/', function (req, res) {
function callback(data) {
res.send(data.toString())
}
fs.readFile('./SocketIo.html', function (err, data) {
if (err) {
console.log(err);
callback('文件不存在')
} else {
callback(data)
}
})
})
app.get('/SocketIOClient.js',function(req,res){
fs.readFile('./public/SocketIOClient.js',(err,data)=>{
res.send(data)
})
})
app.get('/socket.io.js',function(req,res){
fs.readFile('./public/socket.io.js',(err,data)=>{
res.send(data)
})
})
// socket.io设置
// 在线用户
var onlineUsers = {}
var i = 0
io.on('connection', function (socket) {
console.log('有人连上来了~');
//监听新用户的加入
socket.name = '用户' + ++i
onlineUsers[socket.name] = socket
// 监听用户退出
socket.on('disconnect', function () {
console.log('有人退出');
delete onlineUsers[socket.name]
})
// 监听用户发布聊天内容
socket.on('message', function (msg) {
broadcast(msg, socket)
})
})
function broadcast(msg, socket) {
for (var key in onlineUsers) {
onlineUsers[key].send(socket.name + ' : ' + msg)
}
}
server.listen(9000, function () {
console.log('Port:9000 | Running ...');
})