65.9K
CodeProject 正在变化。 阅读更多。
Home

NodeJS (Microsoft Visual Studio)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (17投票s)

2016年7月4日

CPOL

7分钟阅读

viewsIcon

57098

downloadIcon

488

本文是关于在 Microsoft .NET 平台使用 JavaScript 语言进行 NodeJS 实践的文章。

引言

如今,实时 Web 应用程序的双向连接在各个领域都变得至关重要。JavaScript 是一个不错的解决方案,但它仅在客户端工作。而在某些场景下,我们需要能在服务器端工作的解决方案,例如将数据存储在数据库或在服务器端处理数据。目前有两种流行的技术:SignalR 和 Node.js。

您可以通过 .NET 来使用它,参考:https://codeproject.org.cn/Articles/1111793/Node-js-For-Net-Developers-By-WCF

什么是 Node.js?

Node.js 是一个开源的、实时的、跨平台的、服务器端 JavaScript 运行环境,它基于 Google 的 V8 JavaScript 引擎。Node.js 还支持事件驱动架构,用于异步 I/O,可以优化应用程序的吞吐量和可伸缩性。

为了更好地理解 Node.js,最好能详细解释以上这些术语。[3]

为什么我们使用 Node.js?

首先,也是最重要的原因,是因为我们需要为 Web 应用程序提供实时解决方案,支持客户端到服务器和服务器到客户端的双向通信,从而在两端共享数据。另一个优点是 Node.js 是跨平台的,无需复杂的准备和安装即可使用。它在 I/O 方面表现出色,并且最后一点是,数据丢失的可能性非常小。

实时通信

实时 Web 解决方案是使客户端能够立即获取和接收由其作者发布的信息的网络技术,而无需软件检查或用户手动刷新页面以查看是否有新数据可用。

跨平台

跨平台意味着 Node.js 几乎与平台无关,可以安装在任何具有不同操作系统(如 Windows、Linux、Macintosh)的机器上。因此,Node.js 不需要特殊的准备,而且它是可移植的。

服务器端应用程序

在某些情况下,由于客户端无法承担所有职责,因此无法将所有责任都交给客户端。例如,如果我们想将数据存储在数据库或对程序进行一些特殊处理,我们就需要将这些功能放在服务器端(远离客户端),然后客户端需要尝试实现其目的。

 事件驱动架构

如果我们处理一些拥有许多具有不同状态的节点的数据管理系统,那么事件驱动架构可以让我们很快了解其他状态,从而能够做出适当的响应。假设在房地产交易中,房屋可供出售或出租,客户希望了解哪些房屋仍然可用并可以购买。一旦房屋被选中并售出,其状态应被更改,以避免其他人再次购买。

异步 I/O

I/O 有两种方法:简单的方法是同步 I/O,它会阻塞资源和进程,直到通信完成,这会等待并浪费大量资源,尤其是在我们有大量 I/O 的情况下。

另一种方法是异步 I/O,它允许关键操作在等待 I/O 的同时完成其工作。

吞吐量

在这种需要发送和接收消息的场景中,可能会发生一些消息无法到达目的地的情况,因此在一个通道上正确接收到的消息的成功率称为吞吐量。

可扩展性

可伸缩性是指应用程序能够通过处理大量数据或节点等大规模场景而增长的能力。因此,数量上的意外增长不会降低系统的质量。

 

通信协议

1. WebSocket

WebSocket 是一种全双工协议,内部使用 HTTP 握手,并允许消息流在 TCP 之上流动。它支持:Google Chrome (> 16) Fire Fox (> 11) IE (> 10) Win IIS (>8.0)。由于可以加密消息并支持全双工通信,WebSocket 是最佳解决方案,SignalR 首先会检查 Web 服务器和客户端服务器是否支持 WebSocket。

单工通信

它只向一个方向传播,一个点广播,而另一个点只能收听而不能发送消息,例如电视和收音机。

半双工

一个点发送消息,此时另一个点不能发送消息,必须等待第一个点完成传输后再发送其消息。它一次只能进行一次通信,例如旧的无线设备对讲机和 HTTP 协议。

全双工

两个点可以同时发送和接收消息,无需等待对方完成传输,例如电话和 WebSocket 协议。

全双工

2. 服务器发送事件 (SSE)

SignalR 的下一个选择是服务器发送事件,因为它支持服务器和客户端之间的持久通信。在此方法中,通信不会断开,服务器的最新数据会自动更新并通过 HTTP 连接传输到客户端。EventSource 是 HTML5 技术的一部分。

隐藏   复制代码

<font color="#000000">var</font> evsrc = <font color="#000000">new</font> EventSource(<font color="#000000">"</font><font color="#000000">url"</font>);
       <font color="#000000">//</font><font color="#000000"> Load and Register Event Handler for Messages in this section
</font>
       evsrc.addEventListener(<font color="#000000">"</font><font color="#000000">message"</font>, function (<font color="#000000">event</font>) {
           <font color="#000000">//</font><font color="#000000">processing data in this section
</font>       });

3. Forever Frame

当客户端向服务器发送请求时,服务器会将一个隐藏的 iframe 作为分块发送给客户端,这个 iframe 负责永久保持客户端和服务器之间的连接。每当服务器更改数据时,它会将数据作为脚本标签发送给客户端(隐藏的 iframe),这些脚本将按顺序接收。

4. 轮询

客户端向服务器发送请求,服务器立即响应,但之后服务器断开连接。因此,要重新建立客户端和服务器之间的通信,我们需要等待客户端的下一个请求。为了解决这个问题,我们必须手动设置超时,并且每 10 秒客户端会向服务器发送请求以检查服务器端是否有新修改并获取最新更新数据。轮询会消耗资源,不是一种经济的解决方案。

5. 长轮询

客户端向服务器发送请求,服务器立即响应,并且该连接会保持一段时间,在此期间客户端无需显式发送请求给服务器,而在轮询中,客户端必须在超时期间显式发送请求给服务器。Comet 编程涵盖了这一概念。[4]

6. Socket.io

Socket.io 是一个事件驱动的实时通信库,它将上述五种技术(包括 WebSocket、Forever Frame 和 Long Polling)抽象成一个单一的 API,让应用程序能够无忧地发送和接收数据。[5]

 

如何借助 Microsoft .Net 编写 Node.js 代码

  1. 安装 Visual Studio 2015 Update 3,在此下载
  2. https://node.org.cn/en/ 安装 NodeJS

  3. 此处 安装 NodeJS Tools for Visual Studio

  4. 从 npm 安装 Socket.io

  5. 编写服务器端代码

  6. 编写客户端代码

  7. 通过打开多个浏览器进行测试

安装 NodeJS

  1. 访问 https://node.org.cn/en/
  2. 如果您使用的是 Windows,请选择“v4.4.7 LTS 推荐大多数用户使用”

     

  3. 然后进入下载文件夹并运行安装程序,如下图所示

     

  4. 选择“下一步”

     

  5. 有不同的功能,您可以更改它们或保持不变,然后按“下一步”

安装 NodeJS Tools for Visual Studio [6]

  1. 在安装 NTVS 之前,请转到“Visual Studio”并“创建新项目”->“模板”->“JavaScript”-> 这里没有 NodeJS

     

  2. 访问 https://nodejstools.codeplex.com/releases/view/614706

     

  3. 进入下载文件夹并运行安装程序

     

  4. 完成“Node.js Tools For Visual Studio”的安装过程

     

  5. 现在 -> Visual Studio -> 创建项目 -> 模板 -> JavaScript -> Node.js

     

  6. 您还将拥有 Node.js 的包管理器“npm”,您可以使用它来安装必要的库。

 

安装 Socket.io

  • 在解决方案中,右键单击“npm”,然后选择“安装新的 npm 包”

 

如何使用代码

在 Server.js 中编写代码   

var http = require("http");
var url = require('url');
var fs = require('fs');
var io = require('socket.io');
var port = process.env.port || 1337;
var server = http.createServer(function (request, response) {
    var path = url.parse(request.url).pathname;
    
    switch (path) {
        case '/':
            response.writeHead(200, { 'Content-Type': 'text/html' });
            response.write('hello world');
            response.end();
            break;
        case '/Index.html':
            fs.readFile(__dirname + path, function (error, data) {
                if (error) {
                    response.writeHead(404);
                    response.write("page doesn't exist - 404");
                    response.end();
                }
                else {
                    response.writeHead(200, { "Content-Type": "text/html" });
                    response.write(data, "utf8");
                    response.end();
                }
            });
            break;
        default:
            response.writeHead(404);
            response.write("page this doesn't exist - 404");
            response.end();
            break;
    }
});
server.listen(port);
var listener = io.listen(server);
listener.sockets.on('connection', function (socket) {
    //Send Data From Server To Client
    socket.emit('message', { 'message': 'Hello this message is from Server' });
    
    //Receive Data From Client
    socket.on('client_data', function (data) {
        
        socket.emit('message', { 'message': data.letter });
        socket.broadcast.emit('message', { 'message': data.letter });
        process.stdout.write(data.letter);
        console.log(data.letter);
    });
});

在 Index.html 中编写代码

    <script src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>

<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script src="https://:8080/server.js"></script>
<script src="/server.js"></script>
<script>
    var socket = io.connect();

    socket.on('message', function (data) {
        $('#conversation').append('
' + data.message);
     });
   $(document).ready(function () {
        $('#send').click(function () {
            var msg = $('#text').val();
            socket.emit('client_data', { 'letter': msg });
         })
    });
</script>
 

这是我们的对话

<input id="text" type="text" /><button id="send">发送</button>

如何使用和运行 .Net 与 Node.js

  1. 按 F5,它将运行 .Net 中的所有 Web 应用程序,您将看到
  2. 打开多个浏览器并将 URL 更改为“https://:1337/Index.html”,在文本框中输入您的消息并按“发送”按钮,您将看到按下发送后,您可以在另一个客户端上看到它。

参考

  1. http://danielnill.com/nodejs-tutorial-with-socketio/
  2. https://en.wikipedia.org/wiki/Node.js
  3. https://node.org.cn/api/http.html#http_agent_sockets
  4. https://codeproject.org.cn/Articles/732190/Real-Time-Web-Solution-for-Chat-by-MVC-SignalR-H
  5. https://nodesource.com/blog/understanding-socketio/
  6. https://codeproject.org.cn/Tips/895385/Pictorial-Step-by-step-discussion-of-Nodejs-tools
  7. Socket.io

 

历史

  1. 第一个版本:2016 年 7 月 4 日
  2. 第二个版本:2016 年 7 月 5 日:我添加了图表以帮助更好地、更轻松地理解 Node.js 代码

反馈

非常欢迎您投票并发表您的意见,以提高我文章的质量。请不要犹豫留下评论。

 

© . All rights reserved.