序幕介绍:
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
讲人话就是说:WebSocket 使得客户端和服务器之间的数据交换变得更加简单,在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
WebSocket:
- 常见方法
WebSocket(url)
:创建WebSocket对象并与指定的URL建立连接
// 创建WebSocket对象并与服务器建立连接
var socket = new WebSocket("ws://example.com");
- 常见方法
send(data)
:向服务器发送数据
// 向服务器发送数据
function sendData(data) {
socket.send(data);
console.log("发送数据:" + data);
}
- 常见方法
close(code, reason)
:主动关闭WebSocket连接
// 主动关闭WebSocket连接
function closeConnection() {
socket.close();
console.log("关闭WebSocket连接");
}
- 常见事件:
onopen
:当WebSocket连接成功打开时触发的事件
// 连接成功时触发的事件
socket.onopen = function(event) {
console.log("WebSocket连接已打开");
// 发送数据示例
socket.send("Hello, server!");
};
- 常见事件:
onmessage
:当从服务器接收到消息时触发的事件
// 接收到消息时触发的事件
socket.onmessage = function(event) {
var message = event.data;
console.log("收到消息:" + message);
};
- 常见事件:
onclose
:当WebSocket连接关闭时触发的事件
// 连接关闭时触发的事件
socket.onclose = function(event) {
console.log("WebSocket连接已关闭");
};
- 常见事件:
onerror
:当WebSocket连接发生错误时触发的事件
// 连接错误时触发的事件
socket.onerror = function(error) {
console.error("WebSocket错误:" + error);
};
效果图:
代码展示:
index.html
<html>
<head>
<meta charset="UTF-8">
<title>webrtc demo</title>
</head>
<body>
<h1>Websocket简易聊天</h1>
<div id="app">
<input id="sendMsg" type="text" />
<button id="submitBtn">发送</button>
</div>
</body>
<script type="text/javascript">
//在页面显示聊天内容
function showMessage(str, type) {
var div = document.createElement("div");
div.innerHTML = str;
if (type == "enter") {
div.style.color = "blue";
} else if (type == "leave") {
div.style.color = "red";
}
document.body.appendChild(div);
}
//新建一个websocket
var websocket = new WebSocket("ws://172.21.2.52:8099");
//连接建立时触发
websocket.onopen = function () {
console.log("已经连上服务器----");
document.getElementById("submitBtn").onclick = function () {
// 获取输入的内容
var txt = document.getElementById("sendMsg").value;
if (txt) {
//使用连接发送数据
websocket.send(txt);
}
};
};
//连接关闭时触发
websocket.onclose = function () {
console.log("websocket close");
};
//客户端接收服务端数据时触发
websocket.onmessage = function (e) {
var mes = JSON.parse(e.data); // json格式
// 渲染
showMessage(mes.data, mes.type);
};
</script>
</html>
node.js 记得下载:nodejs-websocket依赖
var ws = require("nodejs-websocket")
var port = 8099;
var user = 0;
// 创建一个连接
var server = ws.createServer(function (conn) {
console.log("创建一个新的连接--------");
user++;
// 给连接设置昵称属性
conn.nickname = "user" + user;
// 给连接设置文件描述符属性
conn.fd = "user" + user;
var mes = {};
// 消息类型为进入聊天室
mes.type = "enter";
// 消息内容为进入提示
mes.data = conn.nickname + " 进来啦"
// 广播该消息给所有客户端
broadcast(JSON.stringify(mes));
//向客户端推送消息
conn.on("text", function (str) {
console.log("回复 " + str)
// 消息类型为普通消息
mes.type = "message";
mes.data = conn.nickname + " 说: " + str;
broadcast(JSON.stringify(mes));
});
//监听关闭连接操作
conn.on("close", function (code, reason) {
console.log("关闭连接");
mes.type = "leave";
mes.data = conn.nickname + " 离开了"
broadcast(JSON.stringify(mes));
});
//错误处理
conn.on("error", function (err) {
console.log("监听到错误");
console.log(err);
});
}).listen(port);
function broadcast(str) {
server.connections.forEach(function (connection) {
connection.sendText(str);
})
}
IndexedDB
IndexedDB(索引数据库)是浏览器提供的一种客户端数据库存储解决方案。它允许 Web 应用程序在用户设备上存储大量结构化数据,并可在离线状态下进行查询和操作。IndexedDB 使用对象存储模型,类似于关系型数据库,但不支持 SQL 查询语言。
- open(): 打开数据库连接
let request = window.indexedDB.open("myDatabase", 1);
request.onerror = function(event) {
console.log("Failed to open database");
};
request.onsuccess = function(event) {
let db = event.target.result;
console.log("Database opened successfully");
};
- createObjectStore(): 创建对象存储空间
let objectStore = db.createObjectStore("messages", { keyPath: "id", autoIncrement: true });
- createIndex(): 创建索引
objectStore.createIndex("type", "user", { unique: false });
- transaction(): 开启事务
let transaction = db.transaction(["messages"], "readwrite");
- objectStore.add(): 添加数据到对象存储空间
let objectStore = transaction.objectStore("messages");
let message = { id: 1, type: "text", data: "Hello World", user: "Alice" };
let request = objectStore.add(message);
request.onsuccess = function(event) {
console.log("Data added successfully");
};
- objectStore.get(): 通过主键获取数据
let objectStore = transaction.objectStore("messages");
let request = objectStore.get(1);
request.onsuccess = function(event) {
let data = event.target.result;
console.log(data);
};
- objectStore.getAll(): 获取所有数据
let objectStore = transaction.objectStore("messages");
let request = objectStore.getAll();
request.onsuccess = function(event) {
let data = event.target.result;
console.log(data);
};
- objectStore.put(): 更新数据
let objectStore = transaction.objectStore("messages");
let message = { id: 1, type: "text", data: "Hello Updated", user: "Alice" };
let request = objectStore.put(message);
request.onsuccess = function(event) {
console.log("Data updated successfully");
};
- objectStore.delete(): 删除数据
let objectStore = transaction.objectStore("messages");
let request = objectStore.delete(1);
request.onsuccess = function(event) {
console.log("Data deleted successfully");
};
- clear(): 清空对象存储空间中的所有数据
let objectStore = transaction.objectStore("messages");
let request = objectStore.clear();
request.onsuccess = function(event) {
console.log("Object store cleared successfully");
};
WebSocket加IndexedDB完整代码
WebSocket实现聊天,IndexedDB将聊天数据存储起来,防止刷新丢失
html文章来源:https://www.toymoban.com/news/detail-695100.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webrtc demo</title>
</head>
<body>
<h1>Websocket简易聊天</h1>
<div id="app">
<input id="sendMsg" type="text" />
<button id="submitBtn">发送</button>
<div id="leaveMessage"></div>
<div id="chat"></div>
</div>
<script type="text/javascript">
var db, transaction, objectStore;
// 在页面显示聊天内容
function showMessage(str, type, user = null, state = 1) {
var div = document.createElement("div");
var spanStr = document.createElement("span");
spanStr.innerHTML = str;
if (user != null) {
var spanUser = document.createElement("span");
spanUser.innerHTML = user;
div.appendChild(spanUser);
}
if (type == "enter") {
div.style.color = "blue";
} else if (type == "leave") {
div.style.color = "red";
}
div.appendChild(spanStr);
document.getElementById("chat").appendChild(div);
if (state == 1) {
document.getElementById("chat").appendChild(div);
} else {
document.getElementById("leaveMessage").appendChild(div);
}
}
// 创建或打开 IndexedDB 数据库
var request = window.indexedDB.open("chatDB", 1);
request.onerror = function () {
console.log("无法打开数据库");
};
request.onupgradeneeded = function (event) {
// 获取到数据库对象 db
db = event.target.result;
// 创建名为 "messages" 的对象存储,并指定 "id" 为键路径,并自动递增生成
objectStore = db.createObjectStore("messages", { keyPath: "id", autoIncrement: true });
// 创建一个名为 "type" 的索引,用于根据消息类型进行检索,允许重复值
objectStore.createIndex("type", "user", { unique: false });
// 创建一个名为 "data" 的索引,用于根据消息内容进行检索,允许重复值
objectStore.createIndex("data", "data", { unique: false });
objectStore.createIndex("state", "state", { unique: false });
objectStore.createIndex("user", "user", { unique: false });
};
request.onsuccess = function (event) {
db = event.target.result;
// 新建一个websocket
var websocket = new WebSocket("ws://172.21.2.52:8099");
// 连接建立时触发
websocket.onopen = function () {
console.log("已经连上服务器----");
document.getElementById("submitBtn").onclick = function () {
var txt = document.getElementById("sendMsg").value;
if (txt) {
websocket.send(JSON.stringify(txt));
}
};
// 给输入框添加键盘按下事件监听器
document.getElementById("sendMsg").addEventListener("keydown", function (event) {
// 检查按下的键是否是回车键(键码为13)
if (event.keyCode == 13) {
// 取消回车键的默认行为(避免表单提交等操作)
event.preventDefault();
var txt = document.getElementById("sendMsg").value;
if (txt) {
websocket.send(JSON.stringify(txt));
}
}
});
};
// 连接关闭时触发
websocket.onclose = function () {
console.log("websocket close");
};
// 客户端接收服务端数据时触发
websocket.onmessage = function (e) {
var mes = JSON.parse(e.data); // json格式
// 渲染
if (mes.state == 0) {
showMessage(mes.data, mes.type, mes.user);
saveMessage(mes)
document.getElementById("sendMsg").value = ''
} else {
showMessage(mes.data, mes.type);
}
};
function saveMessage(message) {
let transaction = db.transaction(["messages"], "readwrite");
let objectStore = transaction.objectStore("messages");
var saveRequest = objectStore.add(message);
saveRequest.onsuccess = function () {
console.log("消息已保存到 IndexedDB");
};
saveRequest.onerror = function () {
console.log("保存消息时发生错误");
};
}
function loadMessages() {
// 创建一个只读事务,该事务用于操作名为 "messages" 的对象存储
transaction = db.transaction(["messages"], "readonly");
// 获取对 "messages" 对象存储的引用,以便进行后续的操作
objectStore = transaction.objectStore("messages");
// 回一个获取所有数据的请求
var getAllRequest = objectStore.getAll();
// 在获取数据成功时触发
getAllRequest.onsuccess = function () {
var messages = getAllRequest.result;
messages.forEach(function (message) {
showMessage(message.data, message.type, message.user, 0);
});
};
}
// 页面加载完成后加载聊天记录
window.onload = function () {
loadMessages();
};
};
</script>
</body>
</html>
node文章来源地址https://www.toymoban.com/news/detail-695100.html
var ws = require("nodejs-websocket")
var port = 8099;
var user = 0;
// 创建一个连接
var server = ws.createServer(function (conn) {
console.log("创建一个新的连接--------");
user++;
// 给连接设置昵称属性
conn.nickname = "user" + user;
// 给连接设置文件描述符属性
conn.fd = "user" + user;
var mes = {};
// 消息类型为进入聊天室
mes.type = "enter";
// 消息内容为进入提示
mes.data = conn.nickname + " 进来啦";
mes.state = 1;
// 广播该消息给所有客户端
broadcast(JSON.stringify(mes));
//向客户端推送消息
conn.on("text", function (str) {
console.log("回复 " + str)
// 消息类型为普通消息
mes.type = "message";
mes.user = conn.nickname + " 说:";
mes.data = str;
mes.state = 0;
broadcast(JSON.stringify(mes));
});
//监听关闭连接操作
conn.on("close", function (code, reason) {
console.log("关闭连接");
mes.type = "leave";
mes.data = conn.nickname + " 离开了"
broadcast(JSON.stringify(mes));
});
//错误处理
conn.on("error", function (err) {
console.log("监听到错误");
console.log(err);
});
}).listen(port);
function broadcast(str) {
server.connections.forEach(function (connection) {
connection.sendText(str);
})
}
到了这里,关于【WebSocket&IndexedDB】node+WebSocket&IndexedDB开发简易聊天室的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!