vue使用python_如何使用Python和Vue创建两人游戏

vue使用python

by Neo Ighodaro

由新Ighodaro

如何使用Python和Vue创建两人游戏 (How to create a two-player game with Python and Vue)

In this tutorial, we will create a realtime tic-tac-toe game using Python and Pusher channels. Here’s a demo of how the game will look and behave upon creation:

在本教程中,我们将使用Python和Pusher通道创建一个实时井字游戏。 以下是游戏制作后的外观和行为演示:

You will need Python 3+, virtualenv, and Flask installed on your machine.The advent of the PC and the internet has redefined the term “entertainment” and the means by which it can be obtained. While a console or some special hardware would have been required to play games in the past, games are only a click away in today’s world of technology.

您将需要在计算机上安装Python 3 +,virtualenv和Flask。PC和Internet的出现重新定义了“娱乐”一词及其获取方式。 尽管过去需要使用控制台或某些特殊的硬件才能玩游戏,但在当今的技术世界中,只需单击一下鼠标即可。

This multiplayer game will allow a player to connect using their preferred username (or generate a random username where a player doesn’t connect with a username) and choose to play with another player from a list of other online players.

这款多人游戏将允许玩家使用其首选用户名进行连接(或在不与用户名建立联系的情况下生成随机用户名),并从其他在线玩家列表中选择与另一位玩家一起玩。

The game itself follows the conventional principles of the popular tic-tac-toe game. The “online player(s)” feature is powered by Pusher presence channels and the realtime updates of a player’s move across multiple windows is powered by Pusher private channels. The source code for this tutorial is available here GitHub.

游戏本身遵循流行的井字游戏的传统原理。 “在线播放器”功能由Pusher存在通道支持 ,而播放器跨多个窗口的移动的实时更新由Pusher专用通道支持。 该教程的源代码可在GitHub上找到 。

Let’s get started.

让我们开始吧。

先决条件 (Prerequisites)

To follow along, a basic knowledge of Python, Flask, JavaScript (ES6 syntax) and Vue is required. You will also need the following installed on your machine:

接下来,需要具备Python,Flask,JavaScript(ES6语法)和Vue的基础知识。 您还将需要在计算机上安装以下软件:

  1. Python (v3.x)

    Python(v3.x)

  2. Virtualenv

    虚拟环境

  3. Flask

    烧瓶

Virtualenv is great for creating isolated Python environments, so we can install dependencies in an isolated environment without polluting our global packages directory.

Virtualenv非常适合创建隔离的Python环境,因此我们可以在隔离的环境中安装依赖项而不会污染我们的全局包目录。

搭建环境 (Setting up the environment)

We will create the project folder and activate a virtual environment within it:

我们将创建项目文件夹并在其中激活虚拟环境:

$ mkdir python-pusher-mutiplayer-game$ cd python-pusher-mutiplayer-game$ virtualenv .venv$ source .venv/bin/activate # Linux based systems$ \path\to\env\Scripts\activate # Windows users

We will install Flask using this command:

我们将使用以下命令安装Flask :

$ pip install flask

设置推送器 (Setting up Pusher)

To integrate Pusher into the multiplayer game, we need to create a Pusher channels application from the Pusher dashboard. If you don’t already have a Pusher account, head over to the Pusher website and create one.

要将Pusher集成到多人游戏中,我们需要从Pu​​sher仪表板创建Pusher频道应用程序。 如果您还没有Pusher帐户,请转到Pusher网站并创建一个。

After creating an account, create a new channels application and enable client events from the application dashboard. To enable client events, click on App settings and scroll to the bottom of the page then select the option that says Enable client events, and update the App settings.

创建帐户后,创建一个新的渠道应用程序并从应用程序仪表板启用客户端事件。 要启用客户端事件,请单击“ 应用程序设置”并滚动到页面底部,然后选择“ 启用客户端事件 ”选项然后更新应用程序设置。

构建后端服务器 (Building the backend server)

Back in the project directory, let’s install the Python Pusher library with this command:

回到项目目录,让我们使用以下命令安装Python Pusher库 :

$ pip install pusher

We will create a new file and call it app.py, this is where we will write all the code for the Flask backend server. We will also create a folder and call it templates, this folder will hold the markup files for this application.

我们将创建一个新文件并将其app.py ,这是我们将编写Flask后端服务器的所有代码的地方。 我们还将创建一个文件夹并将其称为templates ,该文件夹将保存此应用程序的标记文件。

Let’s write some code to register the endpoints for the game and serve the view, open the app.py file and paste the following code:

让我们编写一些代码来注册游戏的端点并提供视图,打开app.py文件并粘贴以下代码:

// File: ./app.pyfrom flask import Flask, render_template, request, jsonify, make_response, jsonfrom pusher import pusherapp = Flask(__name__)pusher = pusher_client = pusher.Pusher(app_id='PUSHER_APP_ID',key='PUSHER_APP_KEY',secret='PUSHER_APP_SECRET',cluster='PUSHER_APP_CLUSTER',ssl=True)name = ''@app.route('/')def index():return render_template('index.html')@app.route('/play')def play():global namename = request.args.get('username')return render_template('play.html')@app.route("/pusher/auth", methods=['POST'])def pusher_authentication():auth = pusher.authenticate(channel=request.form['channel_name'],socket_id=request.form['socket_id'],custom_data={u'user_id': name,u'user_info': {u'role': u'player'}})return json.dumps(auth)if __name__ == '__main__':app.run(host='0.0.0.0', port=5000, debug=True)name = ''

Replace the PUSHER_APP_* keys with the values on your Pusher dashboard.

PUSHER_APP_*键替换为Pusher仪表板上的值。

In the code above, we defined three endpoints, here’s what they do:

在上面的代码中,我们定义了三个端点,这是它们的作用:

  • / - renders the front page that asks a player to connect with a username.

    / -呈现要求玩家使用用户名进行连接的首页。

  • /play - renders the game view.

    /play play-渲染游戏视图。

  • /pusher/auth - authenticates Pusher’s presence and private channels for connected players.

    /pusher/auth为连接的播放/pusher/auth验证Pusher的状态和专用通道。

建立前端 (Building the frontend)

In the templates folder, we will create two files:

templates文件夹中,我们将创建两个文件:

  1. index.html

    index.html

  2. play.html

    play.html

The index.html file will render the connection page, so open the templates/index.html file and paste the following code:

index.html文件将呈现连接页面,因此请打开templates/index.html文件并粘贴以下代码:

<!-- File: ./templates/index.html --><!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><meta name="description" content=""><meta name="author" content="Neo Ighodaro"><title>TIC-TAC-TOE</title><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"><style>:root {--input-padding-x: .75rem;--input-padding-y: .75rem;}html,body, body > div {height: 100%;}body > div {display: -ms-flexbox;display: flex;-ms-flex-align: center;align-items: center;padding-top: 40px;padding-bottom: 40px;background-color: #f5f5f5;}.form-signin {width: 100%;max-width: 420px;padding: 15px;margin: auto;}.form-label-group {position: relative;margin-bottom: 1rem;}.form-label-group > input,.form-label-group > label {padding: var(--input-padding-y) var(--input-padding-x);}.form-label-group > label {position: absolute;top: 0;left: 0;display: block;width: 100%;margin-bottom: 0; /* Override default `<label>` margin */line-height: 1.5;color: #495057;cursor: text; /* Match the input under the label */border: 1px solid transparent;border-radius: .25rem;transition: all .1s ease-in-out;}.form-label-group input::-webkit-input-placeholder {color: transparent;}.form-label-group input:-ms-input-placeholder {color: transparent;}.form-label-group input::-ms-input-placeholder {color: transparent;}.form-label-group input::-moz-placeholder {color: transparent;}.form-label-group input::placeholder {color: transparent;}.form-label-group input:not(:placeholder-shown) {padding-top: calc(var(--input-padding-y) + var(--input-padding-y) * (2 / 3));padding-bottom: calc(var(--input-padding-y) / 3);}.form-label-group input:not(:placeholder-shown) ~ label {padding-top: calc(var(--input-padding-y) / 3);padding-bottom: calc(var(--input-padding-y) / 3);font-size: 12px;color: #777;}</style></head><body><div id="app"><form class="form-signin"><div class="text-center mb-4"><img class="mb-4" src="https://thestore.gameops.com/v/vspfiles/photos/Tic-Tac-Go-14.gif" alt="" width="72" height="72"><h1 class="h3 mb-3 font-weight-normal">TIC-TAC-TOE</h1><p>PUT IN YOUR DETAILS TO PLAY</p></div><div class="form-label-group"><input type="name" id="inputUsername" ref="username" class="form-control" placeholder="Username" required="" autofocus=""><label for="inputUsername">Username</label></div><div class="form-label-group"><input type="email" id="inputEmail" ref="email" class="form-control" placeholder="Email address" autofocus="" required><label for="inputEmail">Email address</label></div><button class="btn btn-lg btn-primary btn-block" type="submit" @click.prevent="login">Connect</button><p class="mt-5 mb-3 text-muted text-center">© 2017-2018</p></form></div><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script>var app = new Vue({el: '#app',methods: {login: function () {let username = this.$refs.username.valuelet email = this.$refs.email.valuewindow.location.replace(`/play?username=${username}&email=${email}`);}}})</script></body></html>

When a player visits the connection page and puts in a username and email, the browser window will be redirected to the game view.

当玩家访问连接页面并输入用户名和电子邮件时,浏览器窗口将被重定向到游戏视图。

Let’s write the markup for the game view. Open the play.html file and paste the following code:

让我们为游戏视图编写标记。 打开play.html文件并粘贴以下代码:

<!-- file: ./templates/play.html --><!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"><title>TIC-TAC-TOE</title></head><body><div id="app" class="container-fluid"><div class="container-fluid clearfix mb-3 shadow"><img class="float-left my-3" src="https://thestore.gameops.com/v/vspfiles/photos/Tic-Tac-Go-14.gif" height="62px" width="62px"/><div class="float-right w-25 py-3"><img class="my-3 mx-3 rounded-circle border" src="http://dfsanonymous.club/wp-content/uploads/2017/11/DFSAnonymous-NewLogo.png"height="62px" width="62px" /><p class="d-inline"> {% raw %} {{ username }} {% endraw %} </p></div></div><div class="row mx-5" style="height: 50vh"><div class="col-8 h-50 align-self-center"><div class="row border rounded invisible h-50 w-75 m-auto" style="font-size: 3.6rem" ref="gameboard" @click="playerAction"><div class="h-100 pr-2 col border border-dark" data-id="1" ref="1"></div><div class="col pr-2 border border-dark" data-id="2" ref="2"></div><div class="col pr-2 border border-dark" data-id="3" ref="3"></div><div class="w-100"></div><div class="h-100 pr-2 col border border-dark" data-id="4" ref="4"></div><div class="col pr-2 border border-dark" data-id="5" ref="5"></div><div class="col pr-2 border border-dark" data-id="6" ref="6"></div><div class="w-100"></div><div class="h-100 pr-2 col border border-dark" data-id="7" ref="7"></div><div class="col pr-2 border border-dark" data-id="8" ref="8"></div><div class="col pr-2 border border-dark" data-id="9" ref="9"></div></div></div><div class="col-4 pl-3"><div class="row h-100"><div class="col border h-75 text-center" style="background: rgb(114, 230, 147);"><p class="my-3"> {% raw %} {{ players }} {% endraw %} online player(s) </p><hr/><li class="m-auto py-3 text-dark" style="cursor: pointer;" v-for="member in connectedPlayers" @click="choosePlayer">{% raw %} {{ member }} {% endraw %}</li></div><div class="w-100"></div><div class="col text-center py-3 border h-25" style="background: #b6c0ca; font-size: 1em; font-weight: bold">{% raw %} {{ status }} {% endraw %}</div></div></div></div></div><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script src="https://js.pusher.com/4.2/pusher.min.js"></script><script></script></body></html>

The code above defines the layout of the game view but does not contain any interactivity or realtime features. In the scripts section, before the closing body tag, we included the Vue and Pusher libraries because they are required for the game to work.

上面的代码定义了游戏视图的布局,但不包含任何交互性或实时功能。 在脚本部分的结束body标签之前,我们包含了Vue和Pusher库,因为它们是游戏正常运行所必需的。

Let’s include the JavaScript code that will drive the entire game process and define its logic.

让我们包括将驱动整个游戏过程并定义其逻辑JavaScript代码。

In the same file, add the code below in between the script tag that is just before the closing body tag:

在同一文件中,将以下代码添加在script标签之间,即结束body标签之前:

var app = new Vue({el: '#app',data: {username: '',players: 0,connectedPlayers: [],status: '',pusher: new Pusher('PUSHER_APP_KEY', {authEndpoint: '/pusher/auth',cluster: 'PUSHER_APP_CLUSTER',encrypted: true}),otherPlayerName: '',mychannel: {},otherPlayerChannel: {},firstPlayer: 0,turn: 0,boxes: [0, 0, 0, 0, 0, 0, 0, 0, 0]},created () {let url = new URL(window.location.href);let name = url.searchParams.get("username");if (name) {this.username = namethis.subscribe();this.listeners();} else {this.username = this.generateRandomName();location.assign("/play?username=" + this.username);}},methods: {// We will add methods here}});

Replace the PUSHER_APP_* keys with the keys on your Pusher dashboard.

PUSHER_APP_*键替换为Pusher仪表板上的键。

Above, we create a new instance of Vue and we target the #app selector. We define all the defaults in the dataobject and then in the create() function which is called automatically when the Vue component is created, we check for a user and assign the user to the username if one was supplied.

上面,我们创建了Vue的新实例,并以#app选择器为目标。 我们在data对象中定义所有默认值,然后在create() Vue组件时自动调用的create()函数中,检查用户并将用户分配给用户名(如果提供了用户名)。

We also make calls to the subscribe and listeners methods. Let’s define those inside the methods object. Inside the methods object, paste the following functions:

我们还调用subscribelisteners方法。 让我们在methods对象中定义它们。 在methods对象内,粘贴以下函数:

// [...]subscribe: function () {let channel = this.pusher.subscribe('presence-channel');this.myChannel = this.pusher.subscribe('private-' + this.username)channel.bind('pusher:subscription_succeeded', (player) => {this.players = player.count - 1player.each((player) => {if (player.id != this.username)this.connectedPlayers.push(player.id)});});channel.bind('pusher:member_added', (player) => {this.players++;this.connectedPlayers.push(player.id)});channel.bind('pusher:member_removed', (player) => {this.players--;var index = this.connectedPlayers.indexOf(player.id);if (index > -1) {this.connectedPlayers.splice(index, 1)}});},listeners: function () {this.pusher.bind('client-' + this.username, (message) => {if (confirm('Do you want to start a game of Tic Tac Toe with ' + message)) {this.otherPlayerName = messagethis.otherPlayerChannel = this.pusher.subscribe('private-' + this.otherPlayerName)this.otherPlayerChannel.bind('pusher:subscription_succeeded', () => {this.otherPlayerChannel.trigger('client-game-started', this.username)})this.startGame(message)} else {this.otherPlayerChannel = this.pusher.subscribe('private-' + message)this.otherPlayerChannel.bind('pusher:subscription_succeeded', () => {this.otherPlayerChannel.trigger('client-game-declined', "")})this.gameDeclined()}}),this.myChannel.bind('client-game-started', (message) => {this.status = "Game started with " + messagethis.$refs.gameboard.classList.remove('invisible');this.firstPlayer = 1;this.turn = 1;})this.myChannel.bind('client-game-declined', () => {this.status = "Game declined"})this.myChannel.bind('client-new-move', (position) => {this.$refs[position].innerText = this.firstPlayer ? 'O' : 'X'})this.myChannel.bind('client-your-turn', () => {this.turn = 1;})this.myChannel.bind('client-box-update', (update) => {this.boxes = update;})this.myChannel.bind('client-you-lost', () => {this.gameLost();})},// [...]

In the subscribe method, we subscribe to our Pusher presence channel, and then subscribe to the private channel for the current user. In the listeners method we register the listeners for all the events we are expecting to be triggered on the private channel we subscribed to.

subscribe方法中,我们订阅Pusher在线状态频道,然后订阅当前用户的专用频道。 在listeners方法中,我们为希望在订阅的私有频道上触发的所有事件注册侦听器。

Next, we will add other helper methods to our methods class. Inside the methods class, add the following functions to the bottom after the listeners method:

接下来,我们将其他辅助方法添加到我们的方法类中。 在方法类内部,将以下函数添加到listeners方法的底部:

// Generates a random string we use as a name for a guest usergenerateRandomName: function () {let text = '';let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';for (var i = 0; i < 6; i++) {text += possible.charAt(Math.floor(Math.random() * possible.length));}return text;},// Lets you choose a player to play as.choosePlayer: function (e) {this.otherPlayerName = e.target.innerTextthis.otherPlayerChannel = this.pusher.subscribe('private-' + this.otherPlayerName)this.otherPlayerChannel.bind('pusher:subscription_succeeded', () => {this.otherPlayerChannel.trigger('client-' + this.otherPlayerName, this.username)});},// Begins the gamestartGame: function (name) {this.status = "Game started with " + namethis.$refs.gameboard.classList.remove('invisible');},// User declined to playgameDeclined: function () {this.status = "Game declined"},// Game has ended with current user winninggameWon: function () {this.status = "You WON!"this.$refs.gameboard.classList.add('invisible');this.restartGame()},// Game has ended with current user losinggameLost: function () {this.turn = 1;this.boxes = [0, 0, 0, 0, 0, 0, 0, 0, 0]this.status = "You LOST!"this.$refs.gameboard.classList.add('invisible');this.restartGame()},// Restarts a gamerestartGame: function () {for (i = 1; i < 10; i++) {this.$refs[i].innerText = ""}this.$refs.gameboard.classList.remove('invisible');},// Checks tiles to see if the tiles passed are a matchcompare: function () {for (var i = 1; i < arguments.length; i++) {if (arguments[i] === 0 || arguments[i] !== arguments[i - 1]) {return false}}return true;},// Checks the tiles and returns true if theres a winning playtheresAMatch: function () {return this.compare(this.boxes[0], this.boxes[1], this.boxes[2]) ||this.compare(this.boxes[3], this.boxes[4], this.boxes[5]) ||this.compare(this.boxes[6], this.boxes[7], this.boxes[8]) ||this.compare(this.boxes[0], this.boxes[3], this.boxes[6]) ||this.compare(this.boxes[1], this.boxes[4], this.boxes[7]) ||this.compare(this.boxes[2], this.boxes[5], this.boxes[8]) ||this.compare(this.boxes[2], this.boxes[4], this.boxes[6]) ||this.compare(this.boxes[0], this.boxes[4], this.boxes[8])},// Checks to see if the play was a winning playplayerAction: function (e) {let index = e.target.dataset.id - 1let tile = this.firstPlayer ? 'X' : 'O'if (this.turn && this.boxes[index] == 0) {this.turn = 0this.boxes[index] = tilee.target.innerText = tilethis.otherPlayerChannel.trigger('client-your-turn', "")this.otherPlayerChannel.trigger('client-box-update', this.boxes)this.otherPlayerChannel.trigger('client-new-move', e.target.dataset.id)if (this.theresAMatch()) {this.gameWon()this.boxes = [0, 0, 0, 0, 0, 0, 0, 0, 0]this.otherPlayerChannel.trigger('client-you-lost', '')}}},

Above, we have added several helper methods that the game needs to function properly and before each method, we have added a comment to show what the method does.

上面,我们添加了游戏需要正常运行的几种辅助方法,在每种方法之前,我们添加了注释以显示该方法的功能。

Let’s test the game now.

让我们现在测试游戏。

测试游戏 (Testing the game)

We can test the game by running this command:

我们可以通过运行以下命令来测试游戏:

$ flask run

Now if we visit localhost:5000, we should see the connection page and test the game:

现在,如果我们访问localhost:5000 ,我们应该看到连接页面并测试游戏:

结论 (Conclusion)

In this tutorial, we have learned how to leverage the Pusher SDK in creating an online multiplayer game powered by a Python backend server.

在本教程中,我们学习了如何利用Pusher SDK创建由Python后端服务器提供支持的在线多人游戏。

The source code for this tutorial is available on GitHub

本教程的源代码可在GitHub上找到

This post first appeared on the Pusher Blog

这篇文章首先出现在Pusher Blog上

翻译自: https://www.freecodecamp.org/news/how-to-create-a-two-player-game-with-python-and-vue-4220c5592d53/

vue使用python

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/393474.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

掩码图制作photoshop__新手用

1.首先你得有一张图&#xff0c;比如这样的&#xff1a; 2.用PS打开他 3.左边工具栏里&#xff08;快速选择工具W&#xff09;&#xff0c;选想显示的部分 4.ctrlc复制一下&#xff0c;新建一张黑底图粘贴上去或者白底图时选中显示区即花瓣右键反向右键填充成黑色 5.菜单栏->…

leetcode287. 寻找重复数(二分法)

给定一个包含 n 1 个整数的数组 nums&#xff0c;其数字都在 1 到 n 之间&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。假设只有一个重复的整数&#xff0c;找出这个重复的数。 示例 1: 输入: [1,3,4,2,2] 输出: 2 代码 class Solution {…

os-enviroment

pip3 install PyUserInput ping 是不带协议的转载于:https://www.cnblogs.com/liuweimingcprogram/p/10957592.html

java 压缩 乱码_如何解决java压缩文件乱码问题

用java来打包文件生成压缩文件&#xff0c;有两个地方会出现乱码&#xff1a;内容的中文乱码问题&#xff1a;修改sun的源码。使用开源的类库org.apache.tools.zip.ZipOutputStream和org.apache.tools.zip.ZipEntry&#xff0c;这两个类ant.jar中有&#xff0c;可以下载使用即可…

Unity3D手机斗地主游戏开发实战(02)_叫地主功能实现

大体思路 前面我们实现了点击开始游戏按钮&#xff0c;系统依次给玩家发牌的逻辑和动画&#xff0c;并展示当前的手牌。这期我们继续实现接下来的功能--叫地主。 1.首先这两天&#xff0c;学习了DOTween&#xff0c;这是一个强大的Unity动画插件&#xff0c;大家可以参考&#…

TensorFlow 学习(十)—— 工具函数

1. 基本 tf.clip_by_value() 截断&#xff0c;常和对数函数结合使用 # 计算交叉熵crose_ent -tf.reduce_mean(tf.log(y_*tf.clip_by_value(y, 1e-10, 1.))) a tf.reshape(tf.range(6, dtypetf.float32), [2, 3]) tf.clip_by_value(a, 2.5, 4.5) # 将值限定在 2.5 …

delphi5开发人员指南_非设计人员的网页设计开发人员指南

delphi5开发人员指南I created my first website as a school project when I was 14. The task was simple: create a very basic site including some text, images, and a table. My usual attitude to school projects was to completely forget about them and later come…

leetcode1292. 元素和小于等于阈值的正方形的最大边长(二分法+前缀和)

给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold。 请你返回元素总和小于或等于阈值的正方形区域的最大边长&#xff1b;如果没有这样的正方形区域&#xff0c;则返回 0 。 示例 2&#xff1a; 输入&#xff1a;mat [[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2…

java 反射 获取成员_java 反射获取成员

package com.wxjaa; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class TestReflect { public static void main(String[] args) throws Exception { // getDeclaredField 可以获取私有成员&#xff0c; …

Koa 中实现 chunked 数据传输

有关于 Transfer-Encoding:chunked 类型的响应&#xff0c;参见之前的文章HTTP 响应的分块传输。这里看 Koa 中如何实现。 Koa 中请求返回的处理 虽然官方文档有描述说明不建议直接调用 response.write&#xff1a; Bypassing Koas response handling is not supported. Avoid …

git 短写设置_如何在短短几分钟内设置一个Git客户端

git 短写设置Today we’re going to talk about Git. You’re going to learn what Git is and how to set up a Git client on your computer.今天我们将讨论Git。 您将学习什么是Git&#xff0c;以及如何在计算机上设置Git客户端。 什么是Git&#xff1f; (What is Git?) I…

P1977 出租车拼车

P1977 出租车拼车 题目背景 话说小 x 有一次去参加比赛&#xff0c;虽然学校离比赛地点不太远&#xff0c;但小 x 还是想坐 出租车去。大学城的出租车总是比较另类&#xff0c;有“拼车”一说&#xff0c;也就是说&#xff0c;你一个人 坐车去&#xff0c;还是一堆人一起&#…

leetcode1011. 在 D 天内送达包裹的能力(二分查找)

传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。 传送带上的第 i 个包裹的重量为 weights[i]。每一天&#xff0c;我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。 返回能在 D 天内将传送带上的所有包裹送达的船的最低运载…

java集合概念_JAVA集合概念

Java集合是使程序能够存储和操纵元素不固定的一组数据。 所有Java集合类都位于java.uti包中。与Java数组不同&#xff0c;Java集合中不能存放基本数据类型&#xff0c;只能存放对象的引用。但是在JDK5.0以后的版本当中&#xff0c;JAVA增加了“自动装箱”和“自动拆箱”的机制&…

项目计划总结

项目计划总结 任务 日期 听课&#xff08;min&#xff09; 编程&#xff08;min&#xff09; 阅读课本&#xff08;min&#xff09; 日总结&#xff08;min&#xff09; 2017/3/13 120 70 190 2017/3/14 80 80 2017/3/15 90 30 120 2017/3/16 …

HTML5新特性之Mutation Observer

Mutation Observer&#xff08;变动观察器&#xff09;是监视DOM变动的接口。当DOM对象树发生任何变动时&#xff0c;Mutation Observer会得到通知。 要概念上&#xff0c;它很接近事件。可以理解为&#xff0c;当DOM发生变动会触发Mutation Observer事件。但是&#xff0c;它与…

leetcode230. 二叉搜索树中第K小的元素(中序遍历)

给定一个二叉搜索树&#xff0c;编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。说明&#xff1a; 你可以假设 k 总是有效的&#xff0c;1 ≤ k ≤ 二叉搜索树元素个数。示例 1:输入: root [3,1,4,null,2], k 13/ \1 4\2 输出: 1解题思路 变量 cnt:统计已经按序遍…

Python操作MongoDB - 极简教程

2019独角兽企业重金招聘Python工程师标准>>> Python 连接 MongoDB 安装PyMongo模块 pip install pymongo使用MongoClient建立连接 from pymongo import MongoClient # 以下为三种建立连接的方式 #client MongoClient() #client MongoClient(localhost, 27017) #cl…

nuxt.js的核心代码_Nuxt.js中的通用应用程序代码结构

nuxt.js的核心代码by Krutie Patel通过克鲁蒂帕特尔(Krutie Patel) Nuxt.js中的通用应用程序代码结构 (Universal application code structure in Nuxt.js) Nuxt.js中的源代码结构的简要摘要 (A brief summary of source code structure in Nuxt.js) Are you new to the Nuxt.…

java 省市区三级联动_AJAX省市区三级联动下拉菜单(java版)

此小程序的功能主要是采用异步请求方式从数据库中调取省市区信息显示到下拉列表&#xff1a;代码如下&#xff1a;建立数据库中的代码和一些配置文件信息就省略了&#xff0c;主要有JavaScript中的代码为&#xff1a;$(document).ready(function(){$.get("getProvince.do&…