首先使用最简单的代码,然后是实现客户管和服务端链接成功
index.html
<script src="/socket.io/socket.io.js"></script>, 这个是固定写法,不可以改变connect, message事件<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>socket.io</title>
</head>
<body>
<h2>socket.io</h2>
<script src="/socket.io/socket.io.js"></script>
<script>
let socket = io() // 相当于new Websocket()
// 客户端和服务端链接成功的回调函数
socket.on('connect', function() {
console.log('客户端链接成功')
socket.send('hello')
})
// 客户端接收到消息后的回调函数
socket.on('message', function (msg) {
console.log(msg)
})
</script>
</body>
</html>
app.js
let express = require('express')
let http = require('http')
let app = express()
app.use(express.static(__dirname))
app.get('/', function (res, req) {
res.header('Content-Type', 'text/html;charset=utf8')
res.sendFile(path.resolve('index.html'))
})
let server = http.createServer(app)
// 因为websocket协议是要依赖http协议实现握手的,所以需要把httpServer的实例传递给socket.io
let socketIo = require('socket.io')
let io = socketIo(server)
// 在服务器监听客户端的链接
io.on('connection', socket => {
console.log('客户端连接到服务器')
// 监听接受客户端发过来的消息
socket.on('message', msg => {
console.log('客户端等候扫服务器的消息', msg)
// 像客户端发送数据
socket.send(`服务器说:${msg}`)
})
socket.on('disconect', function () {
console.log('断开连接')
})
socket.on('error', () => {
console.log('连接错误')
})
})
server.listen(9999)
为了美化一下样式,这里使用了bootstarp,
index.html 修改如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<title>socket.io</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="row-md-12">
<div class="panel panel-default">
<!-- 头部 -->
<header class="panel-heading text-center">
<h4>welcome to talk room</h4>
</header>
<!-- 消息列表 -->
<div class="panel-body">
<ul class="list-group" id="msg-list" style="list-style: none;">
</ul>
</div>
<!-- 消息输入,发送按钮 -->
<div class="panel-footer">
<div class="row-md-10">
<input type="text" id="content" class="form-control">
<button id="btn" class="btn btn-primary">发送消息</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
let socket = io() // 相当于new Websocket()
let ipt = document.querySelector('#content')
let btn = document.querySelector('#btn')
let msgList = document.querySelector('#msg-list')
let LI = document.createElement('li')
socket.on('connect', function () {
console.log('客户端链接成功')
})
socket.on('message', function (msg) {
let li = LI.cloneNode()
msg = JSON.parse(msg)
li.innerHTML = `<span style="color: orange">${msg.name}: </span><span style="color: #06c;">${msg.msg}</span><span style="float: right;">${(new Date(msg.timer)).toLocaleString()}</span>`
msgList.appendChild(li)
})
btn.addEventListener('click',function (params) {
let msg = ipt.value
if (msg) {
socket.emit('message', msg)
ipt.value = ''
} else {
alert('发送的消息不能为空!')
}
}, false)
</script>
</body>
</html>
app.js修改如下
let express = require('express')
let http = require('http')
let app = express()
app.use(express.static(__dirname))
app.get('/', function (res, req) {
res.header('Content-Type', 'text/html;charset=utf8')
res.sendFile(path.resolve('index.html'))
})
let server = http.createServer(app)
// 因为websocket协议是要依赖http协议实现握手的,所以需要把httpServer的实例传递给socket.io
let socketIo = require('socket.io')
let io = socketIo(server)
// 在服务器监听客户端的链接
let sockets = {} // 保存用户
let SYS = '系统提示'
let t = new Date() // 用来处理消息发送时间
io.on('connection', socket => {
console.log('客户端连接到服务器', socket.name)
let username;
// 监听接受客户端发过来的消息
socket.on('message', msg => {
if (username) {
username = msg
// 消息内容
let message = {
name: SYS,
timer: t.getTime(),
msg: `${msg} 进入聊天`
}
// 将对象保存,方便后期使用
sockets[username] = socket
// 像除了自己别的用户广播消息
socket.broadcast.emit('message', JSON.stringify(message))
} else {
// 像客户端发送数据
let message = {
name: username,
timer: t.getTime(),
msg: msg
}
io.emit('message', JSON.stringify(message))
}
})
socket.on('disconect', function () {
console.log('断开连接')
})
socket.on('error', () => {
console.log('连接错误')
})
})
server.listen(9999)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<title>socket.io</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="row-md-12">
<div class="panel panel-default">
<header class="panel-heading text-center">
<h4>welcome to talk room</h4>
</header>
<div class="panel-body">
<ul class="list-group" id="msg-list" style="list-style: none;">
</ul>
</div>
<div class="panel-footer">
<div class="row-md-10">
<input type="text" id="content" class="form-control">
<button id="btn" class="btn btn-primary">发送消息</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
let socket = io() // 相当于new Websocket()
let ipt = document.querySelector('#content')
let btn = document.querySelector('#btn')
let msgList = document.querySelector('#msg-list')
let LI = document.createElement('li')
socket.on('connect', function () {
console.log('客户端链接成功')
})
socket.on('message', function (msg) {
let li = LI.cloneNode()
msg = JSON.parse(msg)
li.innerHTML = `<span style="color: orange" onClick="sendPrive('${msg.name}')">${msg.name}: <span style="color: #06c;">${msg.msg}</span></span><span style="float: right;">${(new Date(msg.timer)).toLocaleString()}</span>`
msgList.appendChild(li)
})
/**
* 设置需要私密通话的对象
*/
function sendPrive(name) {
let str = `@${name} `
ipt.value = str
}
btn.addEventListener('click',function (params) {
let msg = ipt.value
if (msg) {
socket.emit('message', msg)
ipt.value = ''
} else {
alert('发送的消息不能为空!')
}
}, false)
</script>
</body>
</html>
app.js
/^@([^ ]+) (\S)+/获取消息的name和内容,如果只有消息,则不会有返回值let express = require('express')
let http = require('http')
let app = express()
app.use(express.static(__dirname))
app.get('/', function (res, req) {
res.header('Content-Type', 'text/html;charset=utf8')
res.sendFile(path.resolve('index.html'))
})
let server = http.createServer(app)
// 因为websocket协议是要依赖http协议实现握手的,所以需要把httpServer的实例传递给socket.io
let socketIo = require('socket.io')
let io = socketIo(server)
// 在服务器监听客户端的链接
let sockets = {} // 保存用户
let SYS = '系统提示'
let t = new Date()
io.on('connection', socket => {
console.log('客户端连接到服务器')
// 监听接受客户端发过来的消息
let username;
socket.on('message', msg => {
if (!username) {
username = msg
let message = {
name: SYS,
timer: t.getTime(),
msg: `${msg} 进入聊天`
}
sockets[username] = socket
socket.broadcast.emit('message', JSON.stringify(message))
} else {
// 像客户端发送数据
// 解析数据,看是否又私密聊天
if (msg.match(/^@([^ ]+) (\S)+/)) {
let [, name, m] = msg.match(/^@([^ ]+) (\S)+/)
if (name) {
if (name === username) {
let message = {
name: SYS,
timer: t.getTime(),
msg: '您不可以@自己!'
}
socket.emit('message', JSON.stringify(message))
} else {
let message = {
name: socket.name,
timer: t.getTime(),
msg: m
}
sockets[username].emit('message', JSON.stringify(message))
}
} else { // 如果不存在,则提示用户不存在
let message = {
name: SYS,
timer: t.getTime(),
msg: '你@的用户不存在!'
}
socket.emit('message', JSON.stringify(message))
}
} else {
let message = {
name: socket.name,
timer: t.getTime(),
msg: msg
}
io.emit('message', JSON.stringify(message))
}
}
})
socket.on('disconect', function () {
console.log('断开连接')
})
socket.on('error', () => {
console.log('连接错误')
})
})
server.listen(9999)
index.html修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<title>socket.io</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="row-md-12">
<div class="panel panel-default">
<header class="panel-heading text-center">
<h4>welcome to talk room</h4>
<div>
<button class="btn btn-danger" onclick="joinRoom('red')">进入红房间</button>
<button class="btn btn-danger" onclick="leaveRoom('red')">离开红房间</button>
 
<button class="btn btn-success" onclick="joinRoom('blue')">进入绿房间</button>
<button class="btn btn-success" onclick="leaveRoom('blue')">离开绿房间</button>
</div>
</header>
<div class="panel-body">
<ul class="list-group" id="msg-list" style="list-style: none;">
</ul>
</div>
<div class="panel-footer">
<div class="row-md-10">
<input type="text" id="content" class="form-control">
<button id="btn" class="btn btn-primary">发送消息</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
let socket = io() // 相当于new Websocket()
let ipt = document.querySelector('#content')
let btn = document.querySelector('#btn')
let msgList = document.querySelector('#msg-list')
let LI = document.createElement('li')
socket.on('connect', function () {
console.log('客户端链接成功')
})
socket.on('message', function (msg) {
let li = LI.cloneNode()
msg = JSON.parse(msg)
li.innerHTML = `<span style="color: orange" onClick="sendPrive('${msg.name}')">${msg.name}: <span style="color: #06c;">${msg.msg}</span></span><span style="float: right;">${(new Date(msg.timer)).toLocaleString()}</span>`
msgList.appendChild(li)
})
/**
* 设置需要私密通话的对象
*/
function sendPrive(name) {
let str = `@${name} `
ipt.value = str
}
/**
* 进入放假
*/
function joinRoom (room) {
socket.emit('join', room);//进入chat房间
}
/**
* 离开房间
*/
function leaveRoom(room) {
socket.emit('leave', room);//离开chat房间
}
btn.addEventListener('click',function (params) {
let msg = ipt.value
if (msg) {
socket.emit('message', msg)
ipt.value = ''
} else {
alert('发送的消息不能为空!')
}
}, false)
</script>
</body>
</html>
app.js修改
let express = require('express')
let http = require('http')
let app = express()
app.use(express.static(__dirname))
app.get('/', function (res, req) {
res.header('Content-Type', 'text/html;charset=utf8')
res.sendFile(path.resolve('index.html'))
})
let server = http.createServer(app)
// 因为websocket协议是要依赖http协议实现握手的,所以需要把httpServer的实例传递给socket.io
let socketIo = require('socket.io')
let io = socketIo(server)
// 在服务器监听客户端的链接
let SYS = '系统提示'
let t = new Date()
//命名是用来实现隔离的
let sockets = {};
io.on('connection', socket => {
console.log('客户端连接到服务器')
let rooms = []
let username;
// 监听接受客户端发过来的消息
socket.on('message', msg => {
if (!username) { // 第一次进入聊天
username = msg
let message = {
name: SYS,
timer: t.getTime(),
msg: `${msg} 进入聊天`
}
sockets[username] = socket
socket.broadcast.emit('message', JSON.stringify(message))
} else {
// 像客户端发送数据
if (rooms.length > 0) {
for (let i = 0; i < rooms.length; i++) {
if (msg.match(/^@([^ ]+) (\S)+/)) {
let [, name, m] = msg.match(/^@([^ ]+) (\S+)/)
if (name && sockets[username]) {
if (username === name) {
let message = {
name: SYS,
timer: t.getTime(),
msg: '您不可以@自己!'
}
socket.emit('message', JSON.stringify(message))
} else {
let message = {
name: username,
timer: t.getTime(),
msg: m
}
sockets[name].emit('message', JSON.stringify(message))
}
} else { // 如果不存在,则提示用户不存在
let message = {
name: SYS,
timer: t.getTime(),
msg: '你@的用户不存在!'
}
socket.emit('message', JSON.stringify(message))
}
} else {
let message = {
name: username,
timer: t.getTime(),
msg: msg
}
io.in(rooms[i]).emit('message', JSON.stringify(message))
}
}
} else {
// 解析数据,看是否又私密聊天
if (msg.match(/^@([^ ]+) (\S)+/)) {
let [, name, m] = msg.match(/^@([^ ]+) (\S+)/)
if (name && sockets[username]) {
if (username === name) {
let message = {
name: SYS,
timer: t.getTime(),
msg: '您不可以@自己!'
}
socket.emit('message', JSON.stringify(message))
} else {
let message = {
name: username,
timer: t.getTime(),
msg: m
}
sockets[name].emit('message', JSON.stringify(message))
}
} else { // 如果不存在,则提示用户不存在
let message = {
name: SYS,
timer: t.getTime(),
msg: '你@的用户不存在!'
}
socket.emit('message', JSON.stringify(message))
}
} else {
let message = {
name: username,
timer: t.getTime(),
msg: msg
}
io.emit('message', JSON.stringify(message))
}
}
}
})
socket.on('disconect', function () {
console.log('断开连接')
})
socket.on('error', () => {
console.log('连接错误')
})
socket.on('join', roomName => {
let oldIndex = rooms.indexOf(roomName);
if (oldIndex == -1) {
socket.join(roomName);//相当于这个socket在服务器端进入了某个房间
rooms.push(roomName);
let message = {
name: SYS,
timer: t.getTime(),
msg: `您成功进入${roomName}房间了`
}
socket.emit('message', JSON.stringify(message))
} else{
let message = {
name: SYS,
timer: t.getTime(),
msg: `您已经在${roomName}房间了`
}
socket.emit('message', JSON.stringify(message))
}
socket.on('joined', () => {
let message = {
name: SYS,
timer: t.getTime(),
msg: `您进入了 ${roomName} 房间`
}
socket.emit('message', JSON.stringify(message))
// io.in(room).emit('message', JSON.stringify(message2));
})
})
socket.on('leave', roomName => {
// 这里应该判断用户在不在该房间
let oldIndex = rooms.indexOf(roomName);
if (oldIndex !== -1) {
socket.leave(roomName);//相当于这个socket在服务器端进入了某个房间
rooms.splice(oldIndex, 1);
let message = {
name: SYS,
timer: t.getTime(),
msg: `您离开${roomName}房间了`
}
socket.emit('message', JSON.stringify(message))
} else {
let message = {
name: SYS,
timer: t.getTime(),
msg: `您已经不在${roomName}房间了`
}
socket.emit('message', JSON.stringify(message))
}
})
})
server.listen(9999)
以上所以一个简单的聊天室的实现demo,当然还有很多遗留问题,不能@系统,不然会报错,聊天记录没有保存,你在进入聊天室名字会丢,消息没有做过滤,导致同时在多个聊天室的时候会收到多条消息,这些都会解决的,但不是现在。。。。
最近学习redis的时候顺便学习了一下数据结构,发现使用集合能够优雅的实现接收到多条消息的问题,使用并集就可以了,这里先做一个记录 后期补上
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务