网站首页 > 知识剖析 正文
我们使用Javascript所做的许多工作都涉及到我们从服务器来回发送信息。您可能熟悉原料药,将数据以特定格式发送到服务器或网站,以获得特定的响应。
这些被称为RESTAPI。尽管它们很有用,但它们并不擅长恒定的数据流。如果您尝试使用RESTAPI实时地做一些事情,那么您将遇到一个糟糕的时刻。幸运的是,如果我们想要与用户建立实时连接,我们就有了另一种选择,称为WebSocket.
WebSocket是如何工作的
WebSocket本质上是服务器与计算机之间的常量连接。当您访问一个网站时,它可以发送一个GET请求服务器,以启动WebSocket用户与服务器之间的连接。
WebSocketsvs RESTAPI
如果用户离开网站,连接就会被切断,所以只要用户继续使用网站,用户就只能访问WebSocket。
一个WebSocket能打开多长时间?
一旦WebSocket被创建,理论上它可以永远保持打开状态。这方面有几个例外:
服务器停机:这将破坏WebSocket,但我们可以尝试重新连接到它。
停电或者网络连接问题:如果用户的互联网停止,连接就会中断。
无所事事:如果用户不通过WebSocket交互或发送数据,则连接不可避免地会超时。
因此,当我们设计WebSocket时,如果用户的连接由于某种原因停止,我们需要考虑如何重新连接到WebSocket,而不是中断用户的体验。
制作WebSocket
A WebSocket因此,由两个部分组成;服务器是局部机器用户正在使用的。对于我们正在做的事情,我们将使用Node.js作为服务器,但是其他语言也支持WebSocket。
当用户访问我们的网站时,我们加载一个带有Javascript的文件,其中包含到我们WebSocket的连接字符串。同时,在我们的后端,我们将设置WebSocket,用户将连接到。下图显示了这一点:
步骤1:创建我们的服务器
让我们从事我们的Node.js Web服务器用于WebSocket连接。为此,我们将使用一个特快专递服务器,并附带一个名为express-ws。这个附加的包将允许我们使用ws我们可以用同样的方式get.
import path from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
import express from 'express'
import expressWs from 'express-ws'
import http from 'http'
// Our port
let port = 3000;
// App and server
let app = express();
let server = http.createServer(app).listen(port);
// Apply expressWs
expressWs(app, server);
app.use(express.static(__dirname + '/views'));
// Get the route /
app.get('/', (req, res) => {
res.status(200).send("Welcome to our app");
});
// Get the /ws websocket route
app.ws('/ws', async function(ws, req) {
ws.on('message', async function(msg) {
console.log(msg);
// Start listening for messages
});
});
最后一条,app.ws,指的是WebSocket,这就是我们在前端尝试连接的地方。目前,WebSocket只在收到来自前端的消息时,才会记录消息。让我们修改它,这样它就会发回一些东西:
// Get the /ws websocket route
app.ws('/ws', async function(ws, req) {
ws.on('message', async function(msg) {
// What was the message?
console.log(msg);
// Send back some data
ws.send(JSON.stringify({
"append" : true,
"returnText" : "I am using websockets!"
}));
});
});
现在,只要这个WebSocket连接接收到数据,它就会发送回一个对象,我们已经在上面定义了这个对象。然后,我们可以在前端操作这个对象,为用户显示或更改视图。
步骤2:在前端连接
如前所述,当我们的用户访问我们的网站时,我们在HTML文档中为他们提供了一些本地javascript。我在index.html文件中为演示添加了一些其他元素:
<script src="local.js"></script>
<p>Welcome to websockets. Click here to start receiving messages.</p>
<button id="websocket-button">Click me</button>
<div id="websocket-returns"></div>
接下来,我们需要在我们的local.js档案。我已经创建了一个连接文件,我们在加载文档之后运行它。看起来是这样的:
// @connect
// Connect to the websocket
let socket;
const connect = function() {
return new Promise((resolve, reject) => {
const socketProtocol = (window.location.protocol === 'https:' ? 'wss:' : 'ws:')
const port = 3000;
const socketUrl = `${socketProtocol}//${window.location.hostname}:${port}/ws/`
// Define socket
socket = new WebSocket(socketUrl);
socket.onopen = (e) => {
// Send a little test data, which we can use on the server if we want
socket.send(JSON.stringify({ "loaded" : true }));
// Resolve the promise - we are connected
resolve();
}
socket.onmessage = (data) => {
console.log(data);
// Any data from the server can be manipulated here.
let parsedData = JSON.parse(data.data);
if(parsedData.append === true) {
const newEl = document.createElement('p');
newEl.textContent = parsedData.returnText;
document.getElementById('websocket-returns').appendChild(newEl);
}
}
socket.onerror = (e) => {
// Return an error if any occurs
console.log(e);
resolve();
// Try to connect again
connect();
}
});
}
// @isOpen
// check if a websocket is open
const isOpen = function(ws) {
return ws.readyState === ws.OPEN
}
要连接到webSocket,我们必须使用WS://,而不是HTTP,以及WSS://,而不是HTTPS。我们把它放进我们的new WebSocket()函数来生成我们的连接。在我们的连接函数中,我们有三个事件侦听器:
socket.onopen*如果连接成功并打开,则会触发。
socket.onmessage::每当服务器向我们发送消息时,都会触发。在我们的示例中,如果用户接收到具有append设为true.
socket.onerror*如果连接失败,或发生错误,这将触发。
让我们将所有这些联系在一起;因为我们将套接字变量存储在全局范围内,所以我们可以在连接成功后发送数据。下面的事件侦听器连接到WebSocket,然后当用户单击我们的HTML按钮时将数据发送到服务器。
当服务器接收到此数据时,当服务器的消息“事件”触发时,它会发回自己的数据。这将返回给用户,然后用户向他们的文档添加一个新元素。
javascript Copy// When the document has loaded
document.addEventListener('DOMContentLoaded', function() {
// Connect to the websocket
connect();
// And add our event listeners
document.getElementById('websocket-button').addEventListener('click', function(e) {
if(isOpen(socket)) {
socket.send(JSON.stringify({
"data" : "this is our data to send",
"other" : "this can be in any format"
}))
}
});
});
猜你喜欢
- 2024-11-22 只用一行代码快速收集H5聊天用户体验数据——附赠告警机器人
- 2024-11-22 js实现超级链接从新标签打开?
- 2024-11-22 SpringBoot+WebSocket实现简单的数据推送
- 2024-11-22 防止网页被嵌入框架的代码「转」
- 2024-11-22 如何在浏览器中启动Exe文件?
- 2024-11-22 从零开始开发一个实时博客
- 2024-11-22 简单分析实现运维利器---webssh终端libl
- 2024-11-22 如何开发跨框架的组件
- 2024-11-22 location.origin 兼容性处理
- 2024-11-22 为何强烈推荐 ShareJS 做多人协作编辑?
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)