오늘 기사에서는 NHL 라이브 게임 점수를 표시하는 웹 애플리케이션을 만드는 방법을 보여 드리겠습니다. 게임이 진행됨에 따라 점수가 자동으로 업데이트됩니다.
이 기사는 제가 가장 좋아하는 두 가지 취미인 개발과 스포츠를 결합할 수 있는 기회를 제공하기 때문에 매우 흥미로운 기사입니다.
애플리케이션을 만드는 데 사용되는 기술은 다음과 같습니다.
- Node.js
- Socket.io
- MySportsFeeds.com
- Preact(React와 유사)
- HTM
아직 Node.js를 설치하지 않았다면 지금 다운로드 페이지를 방문하여 설정한 후 계속하세요.
Socket.io란 무엇인가요?
Socket.io는 WebSocket을 사용하여 클라이언트를 서버에 연결하는 기술입니다. 이 예에서 클라이언트는 웹 브라우저이고 서버는 Node.js 애플리케이션입니다. 서버에는 언제든지 여러 클라이언트가 연결될 수 있습니다.
연결이 설정되면 서버는 모든 클라이언트 또는 단일 클라이언트에 메시지를 보낼 수 있습니다. 그 대가로 클라이언트는 서버에 메시지를 보내 양방향 실시간 통신을 가능하게 합니다.
Socket.io 이전에는 웹 애플리케이션이 일반적으로 AJAX를 사용했으며 클라이언트와 서버 모두 이벤트를 위해 서로 폴링했습니다. 예를 들어 AJAX 호출은 처리해야 할 메시지가 있는지 확인하기 위해 10초마다 발생합니다.
메시지 폴링은 메시지가 없을 때 지속적으로 찾기 때문에 클라이언트와 서버에 많은 오버헤드를 발생시킵니다.
Socket.io를 사용하면 메시지를 찾을 필요 없이 즉시 메시지를 받을 수 있으므로 오버헤드가 줄어듭니다.
샘플 Socket.io 애플리케이션
실시간 모션 데이터로 작업하기 전에 Socket.io의 작동 방식을 보여주는 샘플 애플리케이션을 만들어 보겠습니다.
먼저 새로운 Node.js 애플리케이션을 생성하겠습니다. 프로젝트를 원하는 폴더로 이동하여 앱용 새 폴더를 만든 다음 새 앱을 만듭니다.
으아아아기본 설정을 모두 사용했습니다.
웹 애플리케이션을 만들고 있으므로 설정을 단순화하기 위해 Express라는 NPM 패키지를 사용하겠습니다. 명령 프롬프트에서 다음과 같이 설치합니다: npm installexpress
--저장
물론, Socket.io 패키지를 설치해야 합니다: npm install
소켓.io --save
웹 서버를 만드는 것부터 시작해 보겠습니다. index.js라는 새 파일을 만들고 그 안에 다음 코드를 입력하여 Express를 사용하여 웹 서버를 만듭니다.
으아아아Express를 처음 사용하는 경우 위의 코드 예제에는 Express 라이브러리가 포함되어 있으며 새 HTTP 서버를 생성합니다. 이 예에서 HTTP 서버는 https://localhost:3000과 같은 포트 3000에서 수신 대기합니다. 경로는 사이트의 루트 디렉터리 "/"에 생성됩니다. 라우팅 결과는 index.html이라는 HTML 파일을 반환합니다.
index.html 파일을 생성하기 전, Socket.io를 설정하여 서버를 마무리해보겠습니다. 소켓 서버를 생성하려면 index.js 파일에 다음을 추가하세요.
으아아아Express와 유사하게 코드는 먼저 Socket.io 라이브러리를 가져옵니다. io
的变量中。接下来,使用 io
变量,通过 on
io
io 변수를 사용하여 on
함수를 통해 이벤트 핸들러를 만듭니다. 수신 중인 이벤트는 연결입니다. 이 이벤트는 클라이언트가 서버에 연결할 때마다 호출됩니다.
node index.js
이제 매우 기본적인 클라이언트를 만들어 보겠습니다.
이라는 새 파일을 만들고 그 안에 다음 코드를 입력하세요.
으아아아- 위의 HTML은 Socket.io 클라이언트 JavaScript를 로드하고 서버에 대한 연결을 초기화합니다. 예시를 보려면 Node 애플리케이션을 실행하세요:
- node index.js
- 그런 다음 브라우저에서 http://localhost:3000으로 이동하세요. 페이지에는 아무 것도 나타나지 않습니다. 그러나 Node 애플리케이션을 실행하는 콘솔을 보면 두 개의 메시지가 기록됩니다.
HTTP 서버가 포트 3000에서 시작되었습니다
클라이언트 연결 수신
io.on
函数已更新,包含几行新代码。第一个 socket.emit
将消息发送到客户端。 sendToClient
是事件的名称。通过命名事件,您可以发送不同类型的消息,以便客户端可以以不同的方式解释它们。第二个添加是 socket.on
,其中还包含一个事件名称:receivedFromClient
服务器端修改完成;它现在可以从任何连接的客户端发送和接收数据。
让我们通过更新客户端以接收 sendToClient
事件来完成此示例。当它接收到该事件时,它可以将 receivedFromClient
事件响应回服务器。
这是在 HTML 的 JavaScript 部分中完成的,因此在 index.html 文件中,我更新了 JavaScript,如下所示:
const socket = io(); socket.on('sendToClient', function (data) { console.log(data); socket.emit('receivedFromClient', { my: 'data' }); });
使用实例化的套接字变量,我们在服务器上具有与 socket.on
函数非常相似的逻辑。对于客户端,它正在监听 sendToClient
事件。一旦客户端连接,服务器就会发送此消息。当客户端收到它时,它会记录到浏览器中的控制台。然后,客户端使用与服务器发送原始事件相同的 socket.emit
。在本例中,客户端将 receivedFromClient
事件发送回服务器。当服务器收到消息时,会将其记录到控制台窗口。
亲自尝试一下。首先,在控制台中运行 Node 应用程序:node index.js
。然后在浏览器中加载 http://localhost:3000。
检查 Web 浏览器控制台,您应该会看到记录以下 JSON 数据: {hello:
“世界”}
然后,在运行 Node 应用程序的命令提示符中,您应该看到以下内容:
HTTP server started on port 3000 Client connection received { my: 'data' }
客户端和服务器都可以使用接收到的 JSON 数据来执行特定任务。一旦我们连接到实时体育数据,我们将了解更多信息。
运动数据
现在我们已经掌握了如何向客户端和服务器发送和接收数据,可以利用它来提供实时更新。我选择使用体育数据,尽管同样的理论并不限于体育。在开始这个项目之前,我研究了不同的运动数据。我选择的是 MySportsFeeds,因为他们提供免费的开发者帐户(我与他们没有任何关系)。为了访问实时数据,我注册了一个帐户,然后做了一笔小额捐款。捐款起价为 1 美元,数据每 10 分钟更新一次。这对于示例来说是有好处的。
您的帐户设置完毕后,您就可以继续设置对其 API 的访问权限。为了帮助实现这一点,我将使用他们的 NPM 包: npm install
mysportsfeeds-node --save
安装包后,可以按如下方式进行 API 调用:
const MySportsFeeds = require("mysportsfeeds-node"); const msf = new MySportsFeeds("1.2", true); msf.authenticate("********", "*********"); const today = new Date(); msf.getData('nhl', '2017-2018-regular', 'scoreboard', 'json', { fordate: today.getFullYear() + ('0' + parseInt(today.getMonth() + 1)).slice(-2) + ('0' + today.getDate()).slice(-2), force: true });
在上面的示例中,请务必将对验证函数的调用替换为您的用户名和密码。
以下代码执行 API 调用以获取今天的 NHL 记分牌。 fordate
变量是今天指定的。我还将 force
设置为 true
,以便始终返回响应,即使数据没有更改。
使用当前设置,API 调用的结果将写入文本文件。在最后一个例子中,这将被改变;但是,出于演示目的,可以在文本编辑器中查看结果文件以了解响应的内容。结果包含一个记分板对象。该对象包含一个名为 gameScore
的数组。该对象存储每场比赛的结果。每个对象都包含一个名为 game
的子对象。该对象提供有关谁正在玩的信息。
在游戏对象之外,还有一些变量提供游戏的当前状态。数据根据游戏状态而变化。例如,当游戏还没有开始时,只有几个变量告诉我们游戏没有进行并且还没有开始。
当游戏进行时,会提供有关得分、游戏进行的时间段以及剩余时间的附加数据。当我们进入下一节中显示游戏的 HTML 时,我们将看到这一点。
实时更新
我们已经掌握了拼图的所有碎片,所以现在是时候将拼图拼凑起来以揭示最终图片了。目前,MySportsFeeds 对向我们推送数据的支持有限,因此我们必须从他们那里轮询数据。幸运的是,我们知道数据每 10 分钟只更改一次,因此我们不需要通过过于频繁地轮询更改来增加开销。一旦我们轮询它们的数据,我们就可以将这些更新从服务器推送到所有连接的客户端。
为了执行轮询,我将使用 JavaScript setInterval
函数每 10 分钟调用一次 API(在我的例子中)以查找更新。收到数据后,会将一个事件发送到所有连接的客户端。当客户端收到事件时,游戏分数将在网络浏览器中使用 JavaScript 进行更新。
当 Node 应用程序首次启动时,MySportsFeeds 也会被调用。此数据将用于在第一个 10 分钟间隔之前连接的任何客户端。这存储在全局变量中。这个相同的全局变量作为间隔轮询的一部分进行更新。这将确保当任何新客户端在轮询后连接时,他们将拥有最新的数据。
为了帮助主 index.js 文件中的一些代码整洁,我创建了一个名为 data.js 的新文件。该文件将包含一个导出的函数(可在 index.js 文件中找到),该函数执行先前对 MySportsFeeds API 的调用。以下是该文件的完整内容:
const MySportsFeeds = require("mysportsfeeds-node"); const msf = new MySportsFeeds("1.2", true, null); msf.authenticate("*******", "******"); const today = new Date(); exports.getData = function () { return msf.getData("nhl", "2017-2018-regular", "scoreboard", "json", { fordate: today.getFullYear() + ("0" + parseInt(today.getMonth() + 1)).slice(-2) + ("0" + today.getDate()).slice(-2), force: true, }); };
导出 getData
函数并返回调用结果,在本例中是一个将在主应用程序中解析的 Promise。
现在让我们看看index.js文件的最终内容:
const app = require("express")(); const http = require("http").Server(app); const io = require("socket.io")(http); const data = require("./data.js"); // Global variable to store the latest NHL results let latestData; // Load the NHL data for when client's first connect // This will be updated every 10 minutes data.getData().then((result) => { latestData = result; }); app.get("/", function (req, res) { res.sendFile(__dirname + "/index.html"); }); http.listen(3000, function () { console.log("HTTP server started on port 3000"); }); io.on("connection", function (socket) { // when clients connect, send the latest data socket.emit("data", latestData); }); // refresh data setInterval(function () { data.getData().then((result) => { // Update latest results for when new client's connect latestData = result; // send it to all connected clients io.emit("data", result); console.log("Last updated: " + new Date()); }); }, 300000);
上面的前七行代码实例化了所需的库和全局 latestData
变量。最终使用的库列表是:Express、HTTP、Socket.io 以及刚刚创建的上述 data.js 文件。
完成必要的处理后,应用程序会为服务器首次启动时将连接的客户端填充 latestData
:
// Global variable to store the latest NHL results const latestData; // Load the NHL data for when client's first connect // This will be updated every 10 minutes data.getData().then((result) => { latestData = result; });
接下来的几行设置了网站根页面(http://localhost:3000/)的路由,并启动HTTP服务器监听3000端口。
接下来,设置 Socket.io 来查找连接。当收到新连接时,服务器会发出一个名为 data 的事件,其中包含 latestData
变量的内容。
最后,最后一段代码创建轮询间隔。当间隔发生时,latestData
变量将使用 API 调用的结果进行更新。然后,该数据向所有客户端发出相同的数据事件。
// refresh data setInterval(function() { data.getData().then((result) => { // Update latest results for when new client's connect latestData = result; // send it to all connected clients io.emit('data', result); console.log('Last updated: ' + new Date()); }); }, 300000);
您可能会注意到,当客户端连接并发出事件时,它会使用套接字变量发出事件。此方法将仅将事件发送到连接的客户端。在该间隔内,全局 io
用于发出事件。这会将事件发送给所有客户端。
服务器就完成了。让我们在客户端前端工作。在前面的示例中,我创建了一个基本的 index.html 文件,该文件设置客户端连接,该连接将记录来自服务器的事件并将事件发回。我将扩展该文件以包含已完成的示例。
因为服务器正在向我们发送一个 JSON 对象,所以我将使用 Preact,它就像 React 的优化版本(如果您不熟悉 React,那也没关系)。此外,我将使用 HTM。 HTM 将允许我使用像 React 的 JSX 这样的语法,而无需构建工具。此外,它还包括与 Preact 的集成。
首先,我需要创建一个 id 为 games
的 div
<div id="games"></div>
然后,我将创建模板。以下是模板的完整脚本(您需要将其放入主要 HTML 脚本中):
import { html, render } from "https://esm.sh/htm/preact"; import { signal } from "https://esm.sh/@preact/signals"; const games = signal([]); const socket = io(); socket.on("data", function (data) { games.value = data; }); function ordinalSuffix(input) { const tenRemainder = input % 10, hundredRemainer = input % 100; if (tenRemainder == 1 && hundredRemainer != 11) { return input + "st"; } if (tenRemainder == 2 && hundredRemainer != 12) { return input + "nd"; } if (tenRemainder == 3 && hundredRemainer != 13) { return input + "rd"; } return input + "th"; } function timeLeft(time) { const minutes = Math.floor(time / 60); const seconds = time - minutes * 60; return minutes + ":" + ("0" + seconds).slice(-2); } function stats() { return html`${games.value.forEach( (game) => html`<div class="game"> <div> ${game.game.awayTeam.City} ${game.game.awayTeam.Name} at at ${game.game.homeTeam.City} ${game.game.homeTeam.Name} </div> <div> ${(() => { if (game.isUnplayed) { return `Game Starts at ${game.game.time}`; } else if (game.isCompleted === "false") { return html`<div> Current Score: ${game.awayScore} - ${game.homeScore} </div> <div> ${(() => { if (game.currentIntermission) { return `${ordinalPrefix( game.currentIntermission )} Intermission`; } else if (game.currentPeriod) { return html`${ordinalPrefix( game.currentPeriod )}<br />${timeLeft( game.currentPeriodSecondsRemaining )}`; } else { return `1st`; } })()} </div>`; } else { return `Final Score: ${game.awayScore} - ${game.homeScore}`; } })()} </div> </div>` )}`; } render(stats, document.getElementById("games"));
这已经很多了!让我们一步步来看看。首先,我们导入 Preact、HTM 和称为 Preact Signals 的东西。我们稍后会详细讨论这一点。
接下来,我们建立 WebSocket 连接。此代码与我们之前的代码相同,除了事件名称和我们对数据执行的操作不同之外。您可能会注意到我们分配数据的对象是一个信号。这是在 Preact 中管理状态的快速方法。您可以在 Preact Signals 页面上阅读更多相关信息。
接下来,我们有一些辅助函数,稍后我们将在实际模板中使用它们。之后,我们就有了模板组件。首先,我们迭代所有游戏并返回每个游戏的标记。
标记的第一部分显示团队。然后,我们进入游戏数据的主要部分。
在下一节中,我们首先检查游戏是否已经开始。如果没有,我们将显示比赛何时开始。如果已经开始,我们会显示当前分数,以及当前时段和剩余时间。这是使用辅助函数的地方。
最后,如果比赛结束,我们只显示最终得分。脚本的最后一行只是在我们之前创建的 div 中渲染模板。
下面是混合了已完成的游戏、正在进行的游戏和尚未开始的游戏时的情况的示例。我不是一个很好的设计师,所以当开发人员制作自己的用户界面时,它看起来就像你所期望的那样。如果需要,您可以创建自己的 CSS 样式。

这是 HTML 和 JavaScript 的结合体。
Socket.IO Example <div id="games"></div>
启动 Node 应用程序并浏览到 http://localhost:3000 亲自查看结果!
X분마다 서버는 클라이언트에 이벤트를 보냅니다. 클라이언트는 업데이트된 데이터를 사용하여 게임 요소를 다시 그립니다. 그래서 웹사이트를 열어두고 정기적으로 확인해 보면 게임이 진행되는 동안 게임 데이터가 새로고침되는 것을 볼 수 있습니다.
결론
최종 제품은 Socket.io를 사용하여 클라이언트가 연결되는 서버를 생성합니다. 서버는 데이터를 받아 클라이언트에 보냅니다. 클라이언트가 데이터를 수신하면 디스플레이가 원활하게 업데이트될 수 있습니다. 클라이언트는 서버로부터 이벤트를 수신할 때만 작업을 수행하므로 서버의 부하가 줄어듭니다.
소켓은 한 방향으로 제한되지 않고 클라이언트가 서버에 메시지를 보낼 수도 있습니다. 서버가 메시지를 받으면 일부 처리를 수행할 수 있습니다.
채팅 앱은 일반적으로 이런 방식으로 작동합니다. 서버는 클라이언트로부터 메시지를 수신한 다음 연결된 모든 클라이언트에 이를 브로드캐스트하여 누군가가 새 메시지를 보냈음을 표시합니다.
제가 가장 좋아하는 스포츠 중 하나에 대한 라이브 스포츠 앱을 만들었기 때문에 이 게시물이 즐거웠기를 바랍니다!
이 게시물은 Jacob Jackson의 기여로 업데이트되었습니다. Jacob은 웹 개발자, 기술 작가, 프리랜서 및 오픈 소스 기고자입니다.
위 내용은 Node.js를 사용하여 실시간 스포츠 애플리케이션 만들기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

Python 또는 JavaScript는 경력 개발, 학습 곡선 및 생태계를 기반으로해야합니다. 1) 경력 개발 : Python은 데이터 과학 및 백엔드 개발에 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 적합합니다. 2) 학습 곡선 : Python 구문은 간결하며 초보자에게 적합합니다. JavaScript Syntax는 유연합니다. 3) 생태계 : Python에는 풍부한 과학 컴퓨팅 라이브러리가 있으며 JavaScript는 강력한 프론트 엔드 프레임 워크를 가지고 있습니다.

JavaScript 프레임 워크의 힘은 개발 단순화, 사용자 경험 및 응용 프로그램 성능을 향상시키는 데 있습니다. 프레임 워크를 선택할 때 : 1. 프로젝트 규모와 복잡성, 2. 팀 경험, 3. 생태계 및 커뮤니티 지원.

서론 나는 당신이 이상하다는 것을 알고 있습니다. JavaScript, C 및 Browser는 정확히 무엇을해야합니까? 그들은 관련이없는 것처럼 보이지만 실제로는 현대 웹 개발에서 매우 중요한 역할을합니다. 오늘 우리는이 세 가지 사이의 밀접한 관계에 대해 논의 할 것입니다. 이 기사를 통해 브라우저에서 JavaScript가 어떻게 실행되는지, 브라우저 엔진의 C 역할 및 웹 페이지의 렌더링 및 상호 작용을 유도하기 위해 함께 작동하는 방법을 알게됩니다. 우리는 모두 JavaScript와 브라우저의 관계를 알고 있습니다. JavaScript는 프론트 엔드 개발의 핵심 언어입니다. 브라우저에서 직접 실행되므로 웹 페이지를 생생하고 흥미롭게 만듭니다. 왜 Javascr

Node.js는 크림 덕분에 효율적인 I/O에서 탁월합니다. 스트림은 메모리 오버로드를 피하고 큰 파일, 네트워크 작업 및 실시간 애플리케이션을위한 메모리 과부하를 피하기 위해 데이터를 점차적으로 처리합니다. 스트림을 TypeScript의 유형 안전과 결합하면 Powe가 생성됩니다

파이썬과 자바 스크립트 간의 성능과 효율성의 차이는 주로 다음과 같이 반영됩니다. 1) 해석 된 언어로서, 파이썬은 느리게 실행되지만 개발 효율이 높고 빠른 프로토 타입 개발에 적합합니다. 2) JavaScript는 브라우저의 단일 스레드로 제한되지만 멀티 스레딩 및 비동기 I/O는 Node.js의 성능을 향상시키는 데 사용될 수 있으며 실제 프로젝트에서는 이점이 있습니다.

JavaScript는 1995 년에 시작하여 Brandon Ike에 의해 만들어졌으며 언어를 C로 실현했습니다. 1.C Language는 JavaScript의 고성능 및 시스템 수준 프로그래밍 기능을 제공합니다. 2. JavaScript의 메모리 관리 및 성능 최적화는 C 언어에 의존합니다. 3. C 언어의 크로스 플랫폼 기능은 자바 스크립트가 다른 운영 체제에서 효율적으로 실행하는 데 도움이됩니다.

JavaScript는 브라우저 및 Node.js 환경에서 실행되며 JavaScript 엔진을 사용하여 코드를 구문 분석하고 실행합니다. 1) 구문 분석 단계에서 초록 구문 트리 (AST)를 생성합니다. 2) 컴파일 단계에서 AST를 바이트 코드 또는 기계 코드로 변환합니다. 3) 실행 단계에서 컴파일 된 코드를 실행하십시오.

Python 및 JavaScript의 미래 추세에는 다음이 포함됩니다. 1. Python은 과학 컴퓨팅 분야에서의 위치를 통합하고 AI, 2. JavaScript는 웹 기술의 개발을 촉진하고, 3. 교차 플랫폼 개발이 핫한 주제가되고 4. 성능 최적화가 중점을 둘 것입니다. 둘 다 해당 분야에서 응용 프로그램 시나리오를 계속 확장하고 성능이 더 많은 혁신을 일으킬 것입니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

맨티스BT
Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기
