KEVIN SCHMID:大家好。 欢迎来到CS50研讨会 关于Node.js的 我的名字是凯文。 我是一个CS50 TF。 和我有点像真的很兴奋 关于本次研讨会。 我觉得Node.js的是非常酷的。 我希望,这次研讨会可以使用 作为一个好,我猜,跳板 一些最终的项目如果 你有兴趣使用 像Node.js的 排序我们将通过启动研讨会关​​闭 刚才谈到的一点点 样的背景可扩展性 Node.js的的观点,然后 我们将移动到一些代码示例。 而且我还会在网站上的代码, 你可以看一下代码。 并在研讨会后,我会整理的通话 有关如何设置的Node.js 您的计算机上。 确定。 所以,让我们开始吧。 所以,我想我只是想谈谈 Web服务器,真的,第一次。 并开始讨论,我 基本上有一个图,它是从 用于CS61的教科书,这 基本上显示了交互 一个客户端程序,就像你的网页之间 浏览器或像你的目标客户端或 类似的东西,和Web服务器。 所以这种看起来类似 您在讲座上看到的图片 周三在那里基本上我们有一些 客户端程序,如谷歌Chrome浏览器。 然后一步一个是 客户端发送一个请求。 这样就可以是这样的好,让我们 参观,我不知道,CS50.net。 因此,我们发出了请求。 并没有任何人记得名字 的协议,规定怎么说 请求应该被构成的? 没错。 观众:[听不清]。 凯文·施密德:没错。 所以它就像HTTP的,对不对? 所以基本上在如何规范 这一要求实际上应该被解雇 出来,因为在一天结束时, 该请求是真的只是喜欢 字符串,它基本上 说我想要这个。 和本说明书 因为这是HTTP。 所以这就像一个协议。 那么接下来的服务器接收 该请求。 所以,你们有安装一个Web服务器 在CS50设备。 这是Apache的。 而本周,当你的工作问题 设置7,你实际上是工作 与该Web服务器。 因此,服务器接收到请求, 那么它有一种划伤其 头,说喜欢什么好 我该怎么做? 那么基于它决定这样做,那么 它可能有联系的某种 的资源。 以及该资源可以是一个 很多不同的事情。 首先,它可能只是 就像一个静态的HTML文件。 所以它可能只是像一些 HTML是一样的 您的个人网站。 它可能是一个静态文件等的图像 或者像电影,你有。 它甚至可能不得不谈 以某种数据库 就像一个MySQL数据库。 因此它并不总是具有通信 用的资源,但在 某些情况下,它可以。 所以那么它要做的事情 之后就是它要 发送回响应。 与此响应为 还通过HTTP指定。 这样的话,客户端可以接收它。 它可以把它拆开,并对其进行处理。 然后你会得到一个网页 像谷歌或CS50.net或 不管你去。 好不好? 因此,这是基本的互动, 我们将要处理的。 而且我们几乎将是 专注于这部分的 相互作用,该服务器。 确定。 凉爽。 任何人有任何疑问这么远吗? 确定。 所以,当我们说,Web服务器接收 这个HTTP请求,然后发出这 HTTP响应。 而像我们谈到前, CS50家电网络服务器是Apache。 所以,当你们的工作P上设置7, 你将要与工作 Apache Web服务器。 你将永远不会有真正的工作 与Apache直接太多。 那种你配置Apache一点点 当你指定虚拟主机或 在V主机,我们会得到 要在一点点。 但基本上,Apache Web服务器 建立用PHP样的工作 的开箱即用。 所以当你去什么实际的情况是 您的网站公司,比如之一, 本地主机斜线的index.php什么的, 是您的浏览器发送一个 请求,然后Apache是​​坐 那里,计算出用它做。 和行动是执行 在index.php文件中的代码和 然后发送回其关闭。 因此,有一点。 所以我们有点谈过这个。 所以它可能只是成为一个静态文件 或者运行一些PHP代码,然后问题 的响应。 这样的话,可以来一个常见的​​问题 起来是好,我们怎么真正处理 具有多用户 在同一时间? 所以,如果你正在写一个web想象 服务器,如果你有一个Web服务器, 您试图在写东西 像C或类似的东西, 基本上你可以想想如何有 可能是某种形式的代码, 将接收请求,但随后 它必须做所有这些工作就可以了。 它可以具有,例如,直接从 数据库或类似的东西。 对不对? 然后它会做那种 处理,然后 发回的响应。 这就是像高 概述。 但它不会立即明显你如何 能做到这一点,让两个人或 甚至1000人可以与你的 Web服务器在同一时间。 让Apache使用的解决方案 被称为线程或进程。 所以,你可能听说过 这些条款之前。 这是确定的,如果你还没有,但只是觉得 关于线程或进程的途径 操作系统或用户程序或 类似的东西或Web服务器 排序执行多个 件事情。 所以,你可能已经听说过这个词 像执行的线程。 所以它有点像你 排序多任务。 如果你看过上的框中输入您的 笔记本电脑,或者类似的东西, 多核,你可以做的是,你可以 运行在不同的两个不同的线程 CPU的部分,以便它们可以 实际上发生在同一时间。 所以这真的很强大。 这是一种Apache的中 解决这个问题的。 那么,有没有一种像任何问题 这种方法虽然? 所以我想那种我写了他们那里。 但他们都有点 使用大量的内存。 这是非常昂贵的创建 一个线程或进程。 和推理的部分是,仅仅 就像当你正在运行一个C程序 喜欢你的主,那么该呼叫 另一个函数,有 某种堆栈。 因此,线程也需要一个完全 独立的堆栈, 可能相当大。 如果你能想象有万吨 在您的网站的用户,你将有 有很多不同的线程。 这是一个很大栈来 管理和维护。 所以它的内存消耗大户。 然后,也,让我们说你只有 一个CPU,还是让我们说你有 比你有更多的线程 这些多核。 对不对? 因此,让我们说你有10个线程 而你只有5个CPU。 有种你必须做这件事情的地方 您当前的之间切换 一个是因为你运行 不能运行所有10一次。 这就是所谓的上下文切换。 和这个词实际上有几个 不同的上下文,但我们只 把它当做交换 两个线程之间。 这可以是相当昂贵的,因为 基本上你需要做的就是你 要停止你正在做什么,救 即正在运行的线程的状态, 然后切换到别的地方去。 那种所以没有大家看到的 为什么线程和动机 过程可能会有点笨重? 和你有问题吗? 确定。 凉爽。 任何人有任何问题吗? 确定。 因此,如果我们退后一步一秒钟, 有一种像一个 观察,我们可以对 大量的Web应用程序。 那真的是他们中的很多 其实不这样做多少有用的 一个线程里面工作。 因此,有没有人在开始 p将7呢? 所以,你想也许描述 一些零件? 你处​​理过登录 或者类似的东西? 观众:号 KEVIN SCHMID:确定。 没关系。 抱歉。 但基本上,在P组,你 要挣很多样的 查询数据库得到一些 从该数据库中的信息。 和你的代码将被执行, 什么是Apache进程或 Apache的线程将要干什么 同时它具有与该 数据库是那种它的将是 坐在那里,这将是 等待数据库答辩。 现在,听起来并不像一个大 处理,因为数据库是你的 CS50家电,对不对? 但有一些类型的网络 等待时间也因为现在的网络 服务器必须发出自己的请求 数据库与沟通 数据库,然后得到 信息反馈。 所以,现在它就像好等我,我 打算去得到的东西从 数据库,然后有一个 很多等待事情。 这是否有道理? 而对于一些东西,它不是那么糟糕。 如果它仅仅具有例如 存取存储器,即不喜欢 可怕的I / O延迟。 当我说,I / O延迟,就是我 指的是像任何一种像 输入输出。 但访问磁盘上的文件,如 如果我想服务于静态HTML 文件,该文件是在我的网页或 这样的事情,我种得 停止位,读取该文件 在从磁盘,然后在 这个过程中我在等待。 我不是在做无用功。 这是不是一切的事实,但它 常见于像宝洁这样一套应用程序 七个很多的应用 你不是 实际上做了很多的思考。 当我说的思想,我的意思是 像计算工作。 所以计算工作可能会是 像,比如说,你想 编写一个能够计算一个Web服务器 第n个Fibonacci数。 这听起来并不像一个特别 有趣的Web服务器。 就像我不希望该网站是 下一个Facebook,但这是一些 样的计算工作。 你能想象更换与 一些其他类型的有趣的 计算工作。 比方说,你写的东西 该计算出的度 两个人之间的分离 或者类似的东西。 所以,这的确涉及某种 计算的,对不对? 即使如此,要做到这一点你仍然有 做了很多的等待也许 你必须查询数据库看看 了谁是朋友谁或 类似的东西。 因此,有那种概念 的计算工作。 这是否有道理? 没有任何人有任何问题吗? 哦,我想我把聊天服务器有 因为聊天服务器是一种 这另一个很好的例子。 一个聊天服务器不具备 做太多的思考。 它只是要等待的人 发送消息,然后当 他们,送他们。 好不好? 因此,只是为了再次回顾一下,Apache和 像叉子类似的Web服务器 大量的线程和进程的这 可以是种浪费。 所以我想这可能出现的问题 从正在做我们需要有 多线程和进程? 如果我们只是有一个? 因此,让我们种的画画 什么这会是什么样子。 因此,让我们只使用一个线程。 好不好? 所以,想象一下这一个线程。 让我们假设我们并没有真正做 那么多有用的 - 当我说 有用的,我的意思是计算工作 - 在之前的多个线程。 因此,让我们种的巩固 一切都在一个线程。 那么,如果我们有一个线程的那种 只是绕着中环和 不断检查,做了一件 新的情况发生。 因此,例如,新的东西发生了 可能意味着我得到的东西从后面 数据库,或有人送 我一个新的HTTP请求。 因此,这些都是这类事件 这种情况发生,对不对? 然后我能做些什么时,这些新 事情发生在这同一个线程 执行的,这个单线程 执行,我可以调用一些代码, 将处理特定的事情。 因此,举例来说,如果我得到的东西回来 从数据库,我可以运行我 它小的计算部分的 实际上只是准备的事情 发回给用户。 因此,没有那种有意义吗? 但什么是真正的 这意味着什么呢? 对不对? 因为我们已经写了 大量的代码 - 我只是要跳跃前进 在幻灯片中,如果这是确定。 所以,如果你不介意,我只是 要退一步。 所以这种事情是 称为一个事件循环。 好不好? 而且它是一种基本的 背后Node.js的想法 那么,什么Node.js的是真正做一个网站 服务器是有一个单独的线程 这基本上是绕来绕去在一个循环 像一阵一种下 Node.js的引擎盖那不断 检查,我们没有收到新的东西? 然后它会运行处理程序 您设置。 但是一个很好的问题要问的是, 我们如何才能做到这一点 与现有的东西? 所以我把行C代码在这里, 基本上看起来像它的打开 文件,对不对? 我她刚出来的时候带一张专辑。 因此,我不得不打开她的一个新的文件。 所以,我们的方式操作的C代码 - 我猜我选择文件的原因是 因为这是一种程度 我们已经用C在完成I / O的工作 从某种意义上说,有输入输出。 所以我们称这个代码 这是否f开。 然后在我们的下一行 程序,我们现在可以与f工作。 因此,这将是东西的例子 这就像同步或 在那第一线阻断,因为 有我们在等待,直到我们 得到的文件打开。 因此,在第二行,我们知道,我们 可以与f工作,但是这意味着 那第二行不能真正运行 直到第一行被完成。 这是否有道理? 因此,这将是坏把 在事件处理程序。 和用于该原因是 这种等待,对吗? 因此,这将恢复我们回 同样的事情。 现在我们甚至不会有 多线程的利益或 进程,因为我们得到了 在Node.js的一个线程 这是否是有意义的人呢? 观众:请等待。 那么,有什么替代? KEVIN SCHMID:哦,所以是的。 所以我打算去 更换。 确定。 那么,如果我们有一些东西 这看起来是这样? 那么,如果现在我编辑的 F打开一点点? 所以我通过在同一个 两个参数和以前一样。 我仍然爱新曲 她想出了。 但我传递的第三件事, 在这个变量调用的代码。 但是,什么是真正的代码 在此上下文中? 是不是像一个普通的C变量? 这是一个函数,对不对? 而这可能是一个有点古怪,因为 我其实像现在传递 函数到另一个函数。 所以,有两件事情需要注意这一点。 一,我没有实际调用 对码功能。 所以,你不看代码的 左括号,右括号。 我只是路过的代码。 而在C中,这是什么实际上会做 是给我一个指针,它指向的实际 代码,那么这可能会运行它。 但只是想想而已,你是 通过代码运行时 该文件被打开。 但是,这是什么意思是,现在的 其余的我的程序中哪些可以做 其他的东西,可以继续做其他的 东西,而我们,没有真正等待,但 只是在我们头上的那回 当该文件的打开,运行 在上面的代码。 这是否有道理? 现在Node.js的背后的想法是, 在做的东西与f的代码 部分应该是很短,简单 而直接的,而不是真的 非常密集的计算。 它可能需要打开另一个文件,但 这也应该是相当快 因为它应该只是说做一套f 打开,然后调用该其他代码。 因此,只要是完全清楚,在F 打开,做了新的Katy Perry的歌 做过MP3,那将相当 多立即返回。 然后我们就可以继续做 其他的东西,因为所有的,现在f 公开征集没有被告知基本 底层F打开代码打开这个文件 而当你完成打开此 文件或当你把它找回来, 然后运行该代码。 但它实际上并没有执行该代码。 和你有一个问题吗? 观众:你似乎暗示了几个 ,添加计算时代 排序密集型代码破解 [听不清]驱动系统。 [听不清]? KEVIN SCHMID:这是一个很大的问题。 所以,我其实有多么的例子 你可以计算整合 在一点点密集型代码。 所以,当我们到达的代码示例, 我一定会拉那一个。 这样可以吗? 谢谢。 你叫什么名字? 观众:亚伦。 KEVIN SCHMID:亚伦带来了一个非常 好点的,那就是如果我有 在某些计算密集型代码 与f的一部分,其余的做的东西 我的程序不能运行,不能听 新的请求或任何东西,直到所有 这些东西完成。 所以,如果我写代码的节点一般 除非我们做一些像我要去 后来建议,当我们看 代码示例,我必须确保 我的代码不会占用 此事件循环。 这是否有道理? 确定。 凉爽。 所以Node.js的提供了这种框架, 驱动你可以建立这些事件 服务器用。 所以它有这类异步 非阻塞I / O库,而 我们已经得到了标准C函数库 用,工作一样,如果你只是 使用他们,因为我们已经以同样的方式 一直在使用他们与f打开, 的东西,那些被封锁,因为 你居然要等 该文件将其打开。 但Node.js的给你,和它 基本上是关系到谷歌的V8 JavaScript引擎,这是什么原因 认为Chrome是在处理如此之快 JavaScript的,因为它 有这样的V8发动机。 所以我知道这听起​​来像一个 WWDC开发者大会的事情 在那里,他们只是扔了一堆的 信号东西处理器 并说这是太酷了。 但它很酷,他们没有 这是因为JavaScript的 - 也许,如果你不熟悉 JavaScript尚未因为我们还没有 其上的演讲 - 但是JavaScript是一种解释性 语言。 这是一个重要的点了。 所以这是我们的重要 服务器要快,对不对? 如果我们只是运行的JavaScript 这被解释与代码只是 任何旧的解释器可能会很慢。 从有这个所以节点的好处 超快速的V8翻译。 我不知道他们把它命名为 因为在额头上的V8引擎耳光 的事情,但确定。 所以,我准备了一些例子 在此URL。 会后,我有点要 谈谈你如何能得到的节点集 了,但现在,我只是有点想 步行通过一些代码示例。 所以,如果你想跟着,所有的 源代码可以在那里。 好不好? 所以我会离开这个网址 向上一点点。 然后,我只是要 切换到端子。 是大家用好这个网址? 所以,我要切换 在这里我的终端。 因此,这里的代码, 我有今天。 为什么我们不开始 simpler.js文件? 另一件事是,所有这一切 代码将要被写在 JavaScript的,你可能会或 可能不熟悉。 我想有两件事情是,很多 JavaScript代码是什么样的 语法和结构是非常相似的 C,太客气了,你可以把它捡起来作为 你走。 我试着写了很多的 这在某种程度上是起始码 类似于C,使得它的 多一点可读。 但是,正如我们进步,我会 展示一些额外的 JavaScript的功能, 是挺酷的。 但是让我们看看这个示例程序。 我想一切都切断了那里。 我只是去解决,真正的 快,如果这是确定与否。 我不知道这是什么要做。 那是好一点? 你可以看到var和东西? 确定。 所以,第一行是像JavaScript的 版本的变量 声明。 因此,只是为了突出这是什么会 看起来像在C因此,这就像 我说指数等于三 或者类似的东西。 所以我没有指定类型。 JavaScript的确实有类型的,但它的 非常的自然动态类型,所以 没有提供它的任何一种类型的。 所以它只是变种。 这就像变量。 好不好? 而且我调用这个变量的HTTP。 而在我的右手边,我有 我希望把HTTP中的表达。 这表示需要HTTP。 因此,这是种类似于包含。 这是一个有点像强大的比 包括在包含感 将刚才复制并粘贴头 文件中的函数原型或 无论与类型定义。 但要求其实已在进行 让我们的代码。 所以,你可以把它看作 导入一些代码。 因此,在某处Node.js的模块中 系统或什么,他们有这一切 HTTP服务器代码,所以我只是 取它为我自己 个人使用此计划。 好不好? 于是我有这个功能 我写。 并请注意,我没有指定 返回类型或的类型 争论了。 所以,那种松散的类型 那种感觉。 两个参数,它需要的, 请求和响应。 所以这是概念上有点像 事实是,我们有熟悉的画面 在屏幕上,因为前 我们得到这个要求,我们 有来自用户。 然后我们有一个响应 我们可以写的东西。 所以这个第一行不 res.writeHead 200,然后该 内容类型文本平原。 因此,让我们这一块分开一点点。 所以让我们只专注于res.write 一点点。 这样写是基本上和写头, 只是方式来排序的写出来 活动的响应。 好不好? 所以写头,如果有人记得 从HTTP讲座,做你们 记得头在 的HTTP的东西上面? 那么,为什么不让我演示 头真正的快。 请问这是否有帮助吗? 排序还是应该只是 - 确定。 当然可以。 所以,当您的浏览器去google.com 或类似的东西, 那里实际上是一个多一点 - 这就像一个秘密 - 有像一个小的更多信息 这是通过管道不仅仅是 小查和一切。 所以,向你展示这一点,我要去 使用一个名为卷曲的程序。 好不好? 因此,这是东西,你可以在运行 您的Mac OSX命令行或在 电器或什么的。 所以,如果我不卷曲的HTTP google.com, 我要看到HTML。 这就是,在公平,公正的 HTML类型的,它告诉你 重定向到www如果您的浏览器不 自动处理 重定向。 所以这只是HTML,但我要去 要添加到这个蜷缩连字符I标志。 好不好? 这是要告诉 我的头。 所以这也是自带信息 通过当我得到这个答复。 好不好? 所以在顶部,你看这 HTTP 301永久移动。 这是一种重要的,因为 这指的是状态代码。 因此,这里的301状态码, 这基本上只是一个整数 ,告诉浏览器或谁是 读这篇文章,如果你假装 你是一个浏览器,你看到这一点, 基本上现在如果你看一下 这一点,你看到一个301,你知道我有 做基于一些特别的东西 301,什么特别的事发生 基于301。 所以说,永久移动。 然后,基本上,我们也 一堆键值对。 所以我们得到的位置 是www.google.com。 然后那种所有这些其他的东西, 但基本上,位置是什么 说是新的位置 是在www.google.com。 所以,现在如果你去到google.com,你会 排序看到浏览器那种闪烁的 一秒钟,然后重定向 右后卫上www.google.com。 这样的反应可以包含 这些头文件。 和几件事情要指出。 所以我们说,我们实际上是成功的 在访问一个网页。 所以让我去 - 什么是一个好的网站? 我是坏的好思路 当场网站。 观众:维基百科。 KEVIN SCHMID:确定。 让我们做维基百科。 所以在这里我很感动。 哦,等等。 是我? 是的,我是。 确定。 所以,我必须做的www。 所以我要做的www。 正如你可以看到,这里的所有的HTML 该浏览器将处理 维基百科。 但是,如果我继续在这里滚动起来, 我会看到在顶部 - 哇,有很多的 HTML在维基百科 - 但我可以在上面看到这里 这200状态码,相对于 301,我在前面看到的。 并注意到它有一个很好的 友好确定它旁边。 因此,这是像好状态代码。 这是否200号眼熟? 是的,因为当我做simpler.js, 我写了一个200那里。 所以这基本上是说告诉 浏览器或任何人试图去 这一点,他们是成功的。 或者说,有点像我们的 是成功了。 还有的这种特殊的语法 在Javascript中用于声明一个 映射这些键,如内容类型 而像纯文本这些值。 所以,如果你看一下反应,我们 得到了来自维基百科回来之前, - 我要去尝试滚动 起来快一点 - 你有这些按键像服务器 并且这些值的Apache。 所以,你有键和值。 而且你可以指定此 节点是什么送回去。 因此,这是一种实际上,在某些 方式,并在某些方面它不是 真的,但它是一个低一点的水平 比你可能会对PHP代码 写作对于P设置7,因为PHP和 排序阿帕奇采取一些护理 这些东西给你。 在PHP中,你可以覆盖默认 行为通过编写自己的头。 但对于这个目的,我们得到 写出自己的头。 那么,这行是有意义的 大家好,写磁头线? 确定。 真棒。 所以后来我做的是我最终的响应 说你好的世界。 确定。 但是这只是一个函数 被称为请求处理程序。 所以,现在我居然有一种做 一些与这一功能,对不对? 所以在这里我要做的就是有这个 这确实变种服务器等号线 HTTP.create服务器,然后我 通过在请求处理程序。 因此,这是一种对节点 创建服务器的方式。 并注意到我传递 在请求处理程序。 因此,这是告诉createServer 函数,我要你为我做 服务器,并且当该服务器接收 一个回应,我需要你调用这个 请求处理函数。 好不好? 因此,该行几乎 结束的时候了。 因此,无功服务器产品线是做正确的 你这样做之后漂亮多了。 我的意思是,它必须设置一些内部 状态要知道,你将不得不 调用请求处理功能,但 它不会坐在那里, 比如说有发送用户 我还请求? 有用户发过来的请求了吗? 所以它不会阻止。 好不好? 那么,这带给我们的是它基本上 现在存储一个指向这段代码, 申请的处理函数,然后 将运行该代码,当有人 发出请求。 然后我们做server.listen。 该1337有相当随意的。 我没有特别的原因 用于拾取该号码。 这是完全随机的。 但是,这只是指定端口。 所以大多数Web服务器,你会看到他们 使用80端口,因为这是一种 像的惯例。 所以,如果我去喜欢的东西, 我不知道,Wikipedia.org, 我把结肠8 - 哇哦,你看不到这一点。 对不起。 但如果我这样做维基百科 - 我会在这里写出来只是让 很明显在相机上。 但是,如果我拿这与一个浏览器 一个冒号80,指定去 Wikipedia.org在端口80。 所以它就像美国如何有 喜欢在那里你可以出货多个端口 事情来样。 所以它就像去这个特殊的 放在该服务器上。 确定。 所以,我只是选择了1337。 有数字的整个范围 你可以挑选。 这不是完全特殊。 但我现在打算怎么办 是我要运行节点。 让我真正进入,一对夫妇 台词背下来了,这样你可以看到它。 我要做节点,和我 要运行simpler.js。 我们将讨论如何获得 节点设置在一点点。 但现在它只是运行的服务器。 因此,有一点我们可以尝试这可能不 是,令人兴奋的是,我们实际上可以 尝试访问它的卷曲。 所以我可以做卷发,和我 机器是本地主机。 您还可以看到这样写 这样有时。 本地主机和127.0.0.1是善良 像您的家用电脑。 所以它就像说话 您自己的电脑。 确定。 然后我可以说1337。 所以,如果我运行这行代码, 它说的hello world。 如果我想看到的东西, 有内容类型的文本或纯 什么,我什至可以把这个在这里。 并注意到它说OK。 和我有文字平原。 再有就是那种所有这些其他 的东西,节点将加入 还有我。 这不是超级重要。 我的意思是,有某种技术 在客气的方面 爽谈,但只是为了显示 你,我也有权力 围绕改变这些。 所以,我可以再补充了一堆 之类的东西。 然后现在,如果我看在我 输出,它将是。 所以,这些头的意思是某些事情 以浏览器之类的东西。 和头基本上可以告诉浏览器 如何应对一些东西。 如果你曾经听说过的饼干之前, 或者如果你曾经去过恼火 通过网页设置cookie, 或开启cookie的块或 类似的东西。 实际上,你可以设置Cookie 在这些头。 所以他们告诉浏览器如何 行为的情况。 确定。 所以这是simpler.js。 没有任何人有任何疑问, 该源代码文件? 确定。 凉爽。 因此,让我们从除去R 看看simple.js。 所以这是相当多 相同的程序。 我刚写的有点不同 因为我想排序亮点 JavaScript的某些功能。 所以请注意,请求处理程序 功能已经完全消失了。 哦,是的,你有问题吗? 观众:是的,论据 传递给该 函数,它们是什么? KEVIN SCHMID:因此,这些都是 JavaScript对象。 在Node.js的文档,它 基本上说用什么方法都 适用于他们。 我们只是碰巧有访问 这种方法被称为写开头和结尾 和类似的东西。 但有一大堆 更多的方法。 并举例说,像他们中的一个 特别是在拍摄,你可以做 像rec.method这将 告诉你,无论它是一个HTTP GET或 HTTP POST请求和 这样的事情。 因此,有各种不同的 属性,但他们都 JavaScript对象,而他们只是有 重视他们的功能,你 可以写的东西。 好不好? 所以请注意,请求处理程序 是完全消失了。 但是,我不得不在请求的代码 处理程序仍然存在。 我仍然有这个res.writeHead 我仍然有这个res.end。 和这个是什么的一个例子 JavaScript是这个想法的 匿名函数。 和匿名就像是一个合适的名字 它,因为它字面上不 有一个名字。 有没有功能要求 处理程序在里面。 没有名字,但它仍然 是采取一种说法。 所以我还是得到了REC和水库。 而且我仍然有代码。 这是完全正常 JavaScript代码。 因此,我可以声明一个函数不 明确地给它起名字。 这是起初有点混乱。 还有一些像有用的东西 你可以用做 这些匿名函数。 没有任何人对此有任何疑问, 或者是它确定只是,现在, 只是有点接受它 会做同样的事情? 没错? 观众:首先功能 在JavaScript类? KEVIN SCHMID:他们是第一 类中的JavaScript。 而只知道这些概念 传递像一个匿名函数 这适用于JavaScript的你 可以写在您的最终项目 Web浏览器也。 因此,例如,在JavaScript中 您的浏览器,它也有些事件 在这个意义上推动了什么,你会 已经是当用户点击这个 按钮,我希望你能运行此代码。 所以它的同类的想法 客户端当用鼠标点击或者 鼠标在一些图像上的 网页,运行此代码。 这可以应用到服务器。 所以这是一种像令人兴奋 之所以JavaScript是一个非常 适合或有些人认为这是一个 合适的语言为这种 事件驱动的服务器,因为你有 这些匿名函数。 你的整体思路 这个异步代码。 确定。 任何人有任何问题吗? 确定。 所以这是simple.js。 因此,让我们再看一个 或一对夫妇更多。 因此,这是sleep.js。 所以,是任何人都熟悉 C函数的睡眠? 从早期的讲座可能是一 或者类似的东西? 所以基本上你可以通过在我认为 秒数,或者如果你使用U形 睡了一毫秒数 或纳秒。 和基本程序将停止 运行的时间量。 对不对? 然后它最终会醒来, 然后它会只是继续运行 该方案。 排序所以这台服务器提供 睡觉的印象。 所以请注意,我们有相同的 res.writeHead 200与作为头 之前,但随后我们调用这个 函数调用设置超时。 设置超时也可用于 您的Web浏览器谷歌浏览器 或Safari或什么的。 基本上它在做什么在这里 是它采取的一个函数。 通知,再次,它是一个 匿名函数。 所以这是一种很酷的,因为我们是 使用中的匿名函数 匿名函数 可以是一个有点怪异。 但它采取这一功能,这是 基本上说 - 而这方式 作品是在5,000毫秒,我想 您可以执行功能, 刚刚结束的响应,并写入哎。 所以,这给像印象 睡觉,但这种方式实际上 工作原理是,我们将通过运行 这条线非常快。 我们只是写东西。 然后,我们还可以通过运行 这条线非常快。 因此,我们没有真正去 等待五秒钟。 我们只是要运行 这段代码瞬间。 再有就是,同样,这一点 事件循环,现在有这个东西 寄存器,基本上只是 不断绕来绕去转了一圈 并期待在一个单一的时钟 螺纹和说法,有5秒 通过了吗? 然后它看到时,所述第二 手已经搬到像五秒钟 什么,那么它唤醒并说, 哦,我有什么做的? 哦,我要运行此代码。 然后它会 运行res.end哎。 所以,再一次,我们永远在这里等待。 所以它不是说的这里面的代码 此功能是要取五 跑秒。 此代码将运行几乎 瞬间,至少相对于 5秒钟,我们在谈论 关于早期之前。 所以,只是为了显示这个动作, 我可以做Node.sleep.js。 和我做了乱七八糟的东西? 也许吧。 抱歉。 让我们看看我们能做些什么来解决这个问题。 确定。 所以,一定要使用Node.js的 我只是在开玩笑。 确定。 只要一秒钟。 确定。 我知道它是什么。 所以,问题是,在我的其他选项卡 在这里,我已经上运行的节点 该相同的地址,1337。 所以错误,这扔,如果我们看一下 它真正的紧密结合,是在地址 使用,EADDRINUSE。 所以,我已经使用1337这里。 所以,如果我关这一关,然后我现在 试图运行此,希望一切 将被罚款。 确定。 所以,你只能有一件事排序 的端口上监听一次。 另一种解决方案已经为我 只是编辑程序,并 它是像1338或东西 这样的。 但现在睡眠运行。 因此,让我们真正尝试出来的 浏览器这个时间,因为它是一个 小平平无奇,看看 它在一个终端。 所以我只是去那 127地址又在1337。 如果你能看到它 - 我不知道你能不能 - 但我 浏览器采取了很长很长 时间来加载或类似的五秒钟。 然后在这之后,它终于 结束了回应。 而你看不到它,因为事情 移过一点,但如果我做 这个有点小,你 可以看到它说,哎。 所以我得到了哎,但 后五秒钟。 它可能是一个小吸尘器看 在这里在终端上,所以我 要做一个 - 让我们做在这里 - 让我们做卷曲的地址 再次与1337。 我只是那种有坐 这里五秒钟。 但是请注意,该服务器 可以接受新的回应。 所以它打印哎。 并演示这一点,基本上是什么 我可以做这个的其他标签 - 所以让我们说我这样做是在另一个选项卡, 我打算做卷曲和相同 事情再次。 我要去尝试踢这些 关闭家伙在同一时间。 所以,我要做到这一点,而且我 去比赛在这里,我 要再做一次。 让我们做它,以便您 可以看到他们两个。 这一个印刷哎并且一个 印哎一路在 - 让我们做实验了。 其实,让我们用这个 欺骗,如果这是确定。 所以我打算使用shell的事情, 让我基本上跑两个副本 这个程序并行的。 所以它会运行的第一个程序,并 并联的第二程序。 所以,现在如果我按下Enter键,它会 作出这样的要求几乎 瞬时地在同一时间。 因此,让我们给这个一杆。 所以,现在发现它说两个过程。 如果你很好奇,那27,000 数基本上是进程ID。 然后请注意,他们印制 哎在同一时间。 这不像我们不得不等待五 为1,然后经过该秒, 五秒钟后获得的第二个。 所以这样的,在某些方面,它的 没有真正的证据,但它的 直观的证据表明,它不只是 喜欢等待五秒钟,阻断 整个主题。 好凉。 因此,阿龙问了一个问题早些时候, 是,还有什么,如果我们不做些什么 - 没错? 观众:请等待。 如何是,从不同的 printf的缓冲,但? 没有它会自动做呢? 我们为什么要担心呢? KEVIN SCHMID:哦,你可以 说一次吗? 观众:不喜欢printf的缓冲 做同样的事情? KEVIN SCHMID:在printf的缓冲? 观众:是啊。 确定。 在他们的测验之一是不 谈到如何,如果你正确的printf 的东西,然后有它停顿1 第二个,然后你把它圈10 有时,它会等待十秒钟, 然后printf的一切融合在一起? KEVIN SCHMID:哦,好吧。 观众:难道做同样的 事情那么在这种情况下? KEVIN SCHMID:所以现在的问题是 基本上在前测验之一 什么的,有一个问题, 基本上,如果你说的打印F 10 在一个时间的事情,然后睡在像 这些打印出来的过程中, 在端由于某种原因,它会 只转储所有那些在屏幕上。 因此,有一种两个不同的 概念在这里。 所以我想有一件事是,在这 情况下,我们正在处理两个不同的 样的人要求服务器 事情的同时。 而且该printf的那种原因 等待这样的,它转储全力以赴 一次更多的是 printf的怎么样 - 所以printf的方式实际上是 实行的是它基本上有 聊到操作系统来写 这些东西到控制台。 因此,它并不想这样做了这一切 当你说printf的东西立刻 一些字符串,因为它可以 得到昂贵的,如果它有 做每一次。 所以,如果你做的printf哎,你的程序 实际可能不打印 马上到控制台。 它可能会说,好吧,我写的。 然后那种等待你给 之前确实有点多 写它输出到控制台。 所以这是这种情况的原因 - 它是种无关 到睡眠 - 是,睡眠是那种刚 注射在那里展示 事实上,它并没有写 它同步。 但对于其原因仅仅是 性能,让您不必 让很多接触, 该操作系统。 但在这里,我们真正要做的 这种睡眠事情就是秀 当我们有两个人访问 这个网站,它不会把 他们在一个行,其中它会说 我一定要帮你,然后当我 完全完成,帮助你以后这些 五秒钟,然后我要去 移动到下一个人。 所以第一人的要求不 占用的事件循环 如果是有道理的。 但这里实际上是一个例子 的东西,将配合 了事件循环。 所以这里有一个可怕的功能 计算第n个斐波那契数。 这是字面上的糟糕方式,您可以 计算第n个Fibonacci数。 这其实只是承认 这哪里是来自, 实际上,有 - 我的意思是,你可以尝试去找到它 - 但 有没有像一个非常漫长的博客 后有人写道。 这就像那些书签交易的事情之一。 但有人批评Node.js的,并 他们用这个作为一个例子。 样的,所以我想只显示两个 不同的观点只是为了得到 概念的一般理解 后面这两个东西。 但这个选择只是一个可怕的, 可怕的低效计算 密集的方式来计算 第n个Fibonacci数。 因此,正如一个侧面说明,为什么 它像可怕的一种方式? 没错? 观众:说你开始 用1,000。 1,000分裂成999和998。 每一个这样分割成两件事情。 每一个这样分割成两件事情。 凯文·施密德:对。 观众:一路下来。 凯文·施密德:没错。 因此,只要重复的摄像头,如果我 打电话撒谎像1,000或东西 这样,它显然不低于 或等于一所以我要去 去这个东西的情况下,然后我要去 打电话撒谎999加些小谎998。 然后几乎所有的 FIB表999做的工作是 那种在这个水平。 如果你去了,它甚至更多的冗余 比,但如果你只是 想计算FIB 998得到 我们非常接近,撒谎999。 所以,我们真的应该多一点 关于巧样的,我们如何重复使用 这些,但我们不重用 这些东西都没有。 所以你可以想象这个庞大的, 巨大的树,这只是太可怕了。 但无论如何,确定。 所以这是谎。 它只是需要一段时间来运行。 没错? 观众:[听不清]。 KEVIN SCHMID:哦,你可以 重复的问题? 观众:[听不清]。 KEVIN SCHMID:哦所以这只是代码 这将是某种对 服务器端。 因此,这是不会被发现 在浏览器或任何东西。 这基本上是我们所拥有的是,当 这里的用户几乎使 他们的要求再次,当某种我们 提出一个请求,我们将调用 此功能在服务器端。 然后我们会得到结果返回 从调用该函数。 然后我们将只打印 它给用户。 所以用户并没有真正处理 使用此功能太多。 是这个问题吗? 这是否有道理? 确定。 凉爽。 所以,再一次,我们做这整个res.writeHead 在这里我们打印出来的东西 头。 然后我做最终的反应 神奇的数字是FIB 45。 因此,让我们只需运行该服务器。 所以我要做一个节点fib.js. 所以现在我的FIB服务器正在运行。 然后在这里,我要去 做其中之一。 好不好? 所以,我只是想说,卷曲。 因此,这将需要一些时间,但 希望很快就会完成, 它会打印出45次 斐波纳契数。 观众:[听不清]。 KEVIN SCHMID:应该 得到很快完成。 所以应该采取5〜6秒。 我不知道,只是V8发动机被超 快,但在任何情况下,这是一个 很简单的例子,并故意 不雅的不平凡 计算。 因此,一段时间后,它得到这一点。 但现在,如果我做同一种 实验和以前一样,我做 在同一时间两个请求? 所以在这里我要对卷曲 该地址,我要去 另做卷曲。 请记住,当我们这样做的 睡觉的服务器,当我们基本上有它 五秒钟后,他们很 两个多回来权利 大约在同一时间。 所以它不是特别绑起来。 但是,让我们现在就来试试。 好了,我们得到了我们的两个过程。 还记得那些是进程ID。 这将是一个小 尴尬的同时,我们搪塞。 因此,让我们住在这儿等待。 所以,他们中的一个应该是 回来后像 - 好了,一个人回来。 但后来为什么没有第二 1回来,只是还没有? 没错? 观众:服务器不能做任何事情 而它的计算是大数目。 凯文·施密德:对。 因此,反应只是服务器 真的不能做任何事情,而 它的计算是斐波那契数。 所以,现在我刚刚拿到我的两个东西回来。 但我猜只是想想代码 多一点,它是如何工作的 和一切。 所以这个功能在这里是代码, 我已经告诉这台服务器,当它运行 接收到新的传入请求。 所以它只是通过这个运行 整个代码,然后它会去 回到事件循环,然后继续 检查是否有新的事件。 所以基本上我们所发生的事情 是服务器 听新的东西。 第一个人问什么45。 我们运行这个代码来计算它。 此代码需要大约五 六秒运行。 然后我们回到事件循环 并检查是否有新的要求。 所以这是一个如何一个例子,如果 有事情是所谓的计算 约束,或者使用大量的计算, 没有权力,但有一样 计算密集型 - 我想有一件事要说一下,这是 这个函数是做完全, 在大多数情况下,很 有用的工作权利。 整个时间的回调 功能正在运行,它是非常 多花大部分时间只是 计算的第n个斐波那契数。 但我们只有一个线程 对付。 在Apache的模型中,当两个人 就该好好撒谎45的要求,我们 将有两个不同的线程。 然后操作系统的作业 本来,或者用户级别 用于管理线程中的代码,会一直 一直到切片,截至上 CPU的,甚至如果你有多个CPU, 均匀地分布它们在整个CPU的 让他们都完成 大约在同一时间。 因此,只是为了告诉你如何可以排序的 - 这不是一个完美的总 排序的解决方案,但我们如何能 赚回来这里做 好一点点。 那么,我这里是一个调用程序 FIB C.这基本上使用 的节点的模块,另外一个叫 子进程模块。 所以,我已经包括了在上面种 像我会做一斤包括 孩子PROCESS.H什么的。 现在我有机会使用新的CP变量 里面有我所有的功能。 所以,现在我在做什么在此回应 处理程序是我运行这个程序 点斜线FIB 45。 所以我做了什么 - 我只是去 走出这一计划的一个 点点 - 是我写了一个C程序 基本计算 第n个Fibonacci数。 因此,这里只是我写了一个程序 C语言,计算这一点。 我可以编译它,我可以运行 它在命令行中。 并且它要计算 第45斐波那契数。 所以,注意它只是需要 相当多长。 我大概也可以使用破折号03 优化它或类似的东西, 但我就是不喜欢常规 编译器设置。 而且它打印出来。 但现在,我是什么样的做什么? 哦,对不起,错了文件。 所以我做同样的东西用 如之前的标头。 然后,我这样做cp.exec。 那么,这是怎么回事做的是它的 要运行此程序。 但这种工作方式是, 它不会等待 该程序来完成。 它只是基本上说 执行此程序。 所以基本上键入此进 命令提示符样的。 然后,当你与完成 它,运行此功能。 那种所以现在我们得到这个 整个恢复的事情 就像我们不能等待。 这是否一种有意义吗? 没错? 观众:[听不清]? KEVIN SCHMID:这实际上这样 开辟一个新的进程来做到这一点。 所以实际上,在某些方面, 邪恶的,不是超级邪恶的,但它是 重要的是说,这是一种 回去,一方面,Apache的 模型中,我们做的线程和进程 对于每个请求,或 进程为每个请求。 因此,这是一种类似于 什么阿帕奇一样。 在某些情况下,将仅使用一个新的 线程,这是一点光 重量比的过程,但是Apache可以 最终派生一个新的进程 这是什么样的,我们在这里做的 含蓄地做点斜线FIB 45。 然后在这种情况下,我们种产生 的过程相同的开支。 所以这只是一件事情你可以做。 但只是为了显示这种运行。 而这次谈话只是真正目的 提出这些类型的节目作为 的方式展现不同的视角 如何设计这样的服务器。 所以这个正在运行,那么现在如果我这样做 这一次,我有两个进程ID。 让我们只谈 事情要指出。 所以请注意,他们是增量。 这很酷。 因为它是27,122前。 但现在通知他们回来 在大致相同的时间。 而现在,一个很好的问题请教一下 为什么是这样的,他的工作 是现在它的排序,使这些东西 那种与各自发挥公平 其他的,这两个实例 点斜线FIB 45,我跑了 或者说节点跑? 那种谁使得它公平,他们都 一种得到平衡的运行时间? 观众:[听不清]。 KEVIN SCHMID:是啊。 所以基本上,当我做点斜线谎 45或类似的东西,现在它的 种到操作系统来 处理这些程序的运行时间。 现在它可以安排他们 在不同的CPU或 可以安排他们。 时间可以切片,一个 CPU得到它,或者他们得到 在一个CPU上运行。 所以,这背后的想法。 这是否是有意义的人呢? 所以,现在的节点是不是真的打了 参与瓜分这些任务。 确定。 所以这是几乎它的例子。 我只是想表明一件事 因为很多这样的成绩一直 不完全超实用 在某些情况下。 我能想象在这之后回家 说话和东西,并说像, 好样的我离开了那个说话的那 我可以做一个斐波那契服务器 我最后的项目。 因此,这里只是排序的又一个例子 希望这将是 - 也许不是,但也许 - 多一点 排序相关的最终项目和 超前的思维对这样的事情。 因此,这是chat.js. 因此,这是一种像一些示例 您可以使用服务器端代码 设置像一个小的聊天服务器 你可能已经看到在 Facebook的聊天或什么的。 所以,我并不是说这是像Facebook 聊天,但是这是一种 是个不错的 - 也许不是很好,但也许 好 - 起点聊天 服务器为您的网站 对于最终的项目。 因此,让我们来看看它在做什么。 因此,我们得到这个特别的事情 在顶部,此估计亏损风险SIO 等于要求Socket.IO。 因此,这是它不另外一回事 居然来捆绑 节点,但你可以安装它。 这是一个节点模块。 所以它只是像一些 扩展节点。 SocketIO实际上是真的 挺酷的。 这是一个抽象的概念,基本上是什么 它的作用是是它可以让你 有这种通信流 网络之间 浏览器和Web服务器。 因此,在大多数情况下,到目前为止,我们已经有 这些非常快速一两秒钟 网络之间的第二通信 浏览器和Web服务器。 所以它基本上去到google.com,GET 的东西,送它回去,然后 我们就大功告成了。 我们从来没有再说话,直到 在别的用户类型。 但是Socket.IO和类似那种 事情 - 和SocketIO实际上是1 那是建立在作为东西 WebSocket的是那种可 作为HTML5的一部分 - 这可以让你有这样的 继续对话。 这是非常有用的在聊天服务器 之类的话,因为它是 有点像在一个持续对话 某些方面,因为如果你聊天 某人,你只要发送一个 消息向下的管子,然后将 服务器可以发送消息了下来 管其他人你 与聊天。 然后你就可以有这样的 交换这样的。 所以这是什么样的 SocketIO是好的。 这SocketIO使用的WebSockets的原因 作为一件事是,在 除了只是普通的旧的WebSockets, 它也做了一些技巧,基本上 让浏览器兼容。 因此,浏览器,如Internet Explorer 不幸的是不支持的WebSockets 正确的开箱即用。 因此它使用了一些其他类型的很酷的整齐 使用Adobe Flash的东西,让 你有跨浏览器支持。 所以这是非常有用的。 而实际上,我知道我是那种 在运行时间在这里,但CS50 讨论,你见过的东西 喜欢,我不知道,空白某某是 回复这个帖子什么的 这样,该功能? 这是SocketIO。 所以,当有人开始输入的 讨论箱作出答复或 什么,你的浏览器是什么 叫SocketIO发出某种 倘若某人说的 回复这个帖子。 然后,服务器说,OK, 我有什么做的? 现在好了,我要告诉那些其他人 谁是对CS50讨论寻找 这个帖子有人回复的。 所以这是什么样的SocketIO是 好,这种持续样的 对话流。 确定。 因此,我在这里 - 我们只是 将忽略该连接阵列 一点点 - 我做的是我另一个听。 所以,这只是Socket.IO的方式 说让我们来听听这个端口上。 然后我做这个连接。 所以,这只是基本的Socket IO的 的说法,当我们收到一个方法 就此,我想你 要运行此代码。 并注意而不是有录音的 和水库在那里通过我的Socket。 与此Socket的想法基本上是这样 你可以写和读的东西 从具有该用户的 消息可能。 并且,你会发送邮件 可以通过该插座。 这是否有道理? 所以它的这种持续的事情。 所以,我做的是我称之为Socket.emit。 并发出需要相当 多两个参数。 第一个参数是一个字符串 刚刚代表的类型 你发光的东西。 因此,对于这种情况下,我已经使用 这个字符串新的消息。 而这只是基本上是说, 这个东西的类型,就是我 发送,是一个新的消息。 所以,你可以侦听特定类型 像新的消息或什么 使用点上。 因此,连接和用户发送那里,如果 你看看,我们称之为点上, 这些都是代表其他字符串 类型的用户的消息。 所以基本上你可以有这个EMIT 1这些消息类型,并 然后做一些回应 这些消息类型之一 所以我发这个新的消息。 我们打​​算忽略connections.push 一秒钟。 后来我说,Socket.on用户发送。 所以现在有点像当 用户向我发送一条消息,我想 你要运行此代码。 并注意到,该匿名函数 正在这个变量 所谓数据,基本上会 有用户的信息。 所以,现在让我们有种谈 连接阵列。 因此,这是专为聊天客户端 在那里,基本上每个人的那种在 同一个聊天室。 所以基本上,我们需要保持 周围是一些阵列,基本上 代表所有的人聊天 从某种角度来说,如果是有道理的。 对不对? 因为我们需要知道是谁那些家伙 那么,我们可以向他们发送消息 其他人发送给我们。 所以这段代码的功能是什么,当用户 发送一个消息 - 这是类型 事件 - 我们要运行此代码。 而我们要做的是,我们通过这个运行 数组,我们称之为连接。 和几乎每一个连接 除了一个是我们的,这是 这是什么码说,我们发送一个新的 与附加的邮件消息 信息。 所以,如果你在这里看到,我就是这样做的时候 用户实际上使得新 连接我与加 JavaScript.push方法,这是 基本上只是说像添加 该插座作为一个值 我们的连接阵列。 所以,现在这个代码运行时,它会 送东西给那些特定的 连接。 所以这可能是一个很好的起点 制作一个聊天服务器 或类似的东西。 和那种很酷的事情是, 你在这里看到的像和代码 发射和类似的东西是一样的 样的JavaScript代码,你会 写在浏览器中进行互动 用服务器。 所以这就是为什么SocketIO是怎么样的 整齐并以这种方式非常有用。 呵呵,只是一件事真正的快。 有一个CS50最终项目去年 基本上实现了一个聊天 在Node.js的服务器 我认为这是Harvardchats.org 但我不是 - 确定。 我不知道该URL是什么,但 我后来送了出来。 但是,这是一种什么降温 你可以用Node.js的做 所以我希望,在一般情况下,你们有一个 什么样的Node.js是很有用的感觉不错 并如何可以或许申请 您的最终项目。 我将派出更多一些 随着这个资源。 谢谢你的光临。 谢谢。 [掌声]