领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

网络套接字教程:创建实时网络套接字服务器

nixiaole 2024-11-22 18:52:33 知识剖析 19 ℃

我们使用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"

}))

}

});

});

最近发表
标签列表