【问题标题】:browser as UDP (dgram) client浏览器作为 UDP (dgram) 客户端
【发布时间】:2017-03-11 11:15:29
【问题描述】:

我有一个用 node.js 编写的 UDP dgram 套接字服务器。 这是来自 server.js 的代码 sn-p

 var PORT = 50000;
 var HOST = '0.0.0.0';
 var dgram = require('dgram');
 var server = dgram.createSocket('udp4');

server.on('listening', function () {
var address = server.address();
console.log('UDP Server listening on ' + address.address + ":" +
address.port);
});

server.on('message', function (message, remote) {
console.log('Message',  message);
});

server.bind(PORT, HOST);

我有一个可以连接到这个服务器的客户端。 这是 client.js 文件:

var PORT = 50000;
var HOST = '0.0.0.0';
var dgram = require('dgram');
var message = null;

var client = dgram.createSocket('udp4');


client.on('listening', function () {
var address = client.address();
console.log('UDP Server listening on ' + address.address + ":" + 
address.port);
});

client.on('message', function (message, remote) {
console.log("got message from server ==> ",remote.address + ':' + 
remote.port +' - ' + message);
});

function sendMessage(message) {
    if (message) {
    client.send(message, 0, message.length, PORT, HOST, function (err, 
    bytes) {
        if (err) throw err;
        console.log('UDP message sent to ' + HOST + ':' + PORT);
       // client.close();
       });
   }
}

到这里为止...一切都很好.. 我需要的是:

我需要把这个客户端代码放到一个html或jade页面中......这样我就可以使用浏览器连接到服务器。我无法更改服务器代码:(

【问题讨论】:

  • (简答:你不能。)
  • @JoeClay: 没有办法解决......任何可以写的包装器......
  • 不,浏览器不能直接进行 UDP 通信。 WebRTC 是一个基于 UDP 的 API, 在浏览器中可用,但您必须重写服务器代码才能支持它。
  • @JoeClay:感谢您的澄清:)

标签: javascript html node.js sockets udp


【解决方案1】:

通过浏览器中的 Javascript,您根本无法进行普通的 UDP 连接。浏览器 Javascript 甚至不能做一个普通的 TCP 套接字。 Javascript可以做到:

因此,如果您希望通过直接浏览器 Javascript 直接与您的 UDP 服务器通信,那么从今天起您还不能这样做。

在不以任何方式更改 UDP 服务器的约束下,这是我能想到的唯一选项:

  1. 编写一个可以与您的服务器通信的浏览器插件,然后您的 Javascript 可以与浏览器插件通信。当然,客户端必须下载并安装浏览器插件。

  2. 编写一个可以作为 UDP 服务器代理的新服务器(可以在 node.js 中轻松完成)。如果新服务器是 webSocket 或 socket.io 服务器,那么新服务器可能会工作得最好,然后您的浏览器 Javascript 可以使用 webSocket 或 socket.io 直接与代理对话。然后代理将处理与您的 UDP 服务器的通信。


如果你解除了不修改服务器的限制,如果你把服务器改成webSocket服务器(或者可能是建立在webSocket之上并添加了一堆的socket.io),服务器设计可以与浏览器Javascript兼容有用的功能)。

【讨论】:

  • 似乎是一个繁琐的解决方案,但让我们看看我是否可以让它工作。我正在考虑一些代理服务器之类的事情,但后来有服务器限制..让我们看看我是否可以解脱无论如何这个约束..
  • 我不想投反对票,因为作者的创造力:) 但是如果您了解两者之间的主要区别,将 UDP 包装在 TCP (en.wikipedia.org/wiki/WebSocket) 中并不是您想要的那些 2.
  • @MladenB。 - 我不确定您的评论或指向 webSocket 描述的链接是什么意思。原始问题提出了一个您无法更改的 UDP 服务器,并希望从浏览器连接到它。由于浏览器不提供 UDP 接口,因此问题在这种方式上受到了过度限制,因此 kludges 是唯一的选择。
  • WebSockets 是通过 TCP 实现的,因此链接。由于这两种协议的故意差异,将 UDP 通信包装到 TCP 协议中是没有意义的。 TCP 设计用于应保证数据包交付的情况(例如下载文件),而 UDP 设计用于实时流式传输,您不在乎是否丢失了一些数据包,到达目的地的下一个数据包将继续显示直播...
  • @MladenB。 - 请不要试图在这里教任何人关于这个问题中 UDP 和 TCP 之间的区别。这根本不是这个问题或这个答案的重点,与手头的问题完全无关。 OP 有一个 UDP 服务,他们希望通过浏览器与之通信。没有 UDP 选项可以做到这一点,所以你必须通过 HTTP 或 webSocket 一起破解一些东西才能这样做。是的,这是一个 hack,但这是您从浏览器 Javascript 中唯一的选择。这个问题只是关于可用的选项,而不是理想的设计或理论。
【解决方案2】:

即使他们说它不能完成,但唯一不能塞进常规脚本文件的就是 require 语句。我仍然会尝试捆绑该代码并查看它是否有效。

var dgram = require('dgram');

就是这样。如果你能想出办法把它放进去,你的问题就会全部解决。您可以通过多种方式做到这一点。查看是否有此 dgram 库的客户端版本,您可以在将自己的客户端脚本包含到 html/jade 文档之前将其作为脚本包含在内。这可能是一个非常麻烦的解决方案,因为代码/语法甚至可能需要针对这样的客户端库进行更改。

我相信,更好的选择是使用 browserify。 Browserify 允许您在客户端使用需要其他文件/库的 commonJS 标准。因此,如果您开发一个名为 main.js 的前端文件,例如,您可以按照以下步骤让 browserify 使用您的 main.js 代码以及 dgram 库中的代码创建一个捆绑包,所有这些都混杂在一起:

1- npm install browserify 2- 进入 package.json 并按照测试脚本的格式创建一个新的 npm 脚本(在“scripts”对象内):

"bundle": "browserify path/to/jsfile/main.js -o path/to/outputfile/prod.js"

3- 创建 html/jade 文件并将其链接到 browserify 将输出的 prod.js 文件 4- 运行您创建的捆绑脚本:

npm run bundle

5- 测试 html 文件。

如果正确完成,上述过程将创建一个 prod.js 文件,其中包含所有要求。

【讨论】:

  • browserify 无法神奇地将 UDP 功能添加到浏览器。
  • @Victor Moreno:你有没有测试过你的代码......因为你的工作不起作用......浏览器控制台显示错误:prod.js:2019 Uncaught TypeError: dgram.createSocket is not一个函数(…)
  • @jfriend00 我不认为它会,我也不是暗示它肯定会起作用。我只是说如何创建一个工作流程,您的浏览器至少会运行该文件,以便他们可以试一试。 Nikhil,如果它说 dgram.createSocket 不是一个函数,则意味着该包没有被正确包含。但是,根据其他人提供的答案,Web 浏览器无法使用 UDP 套接字。
猜你喜欢
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 2019-06-13
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
  • 1970-01-01
相关资源
最近更新 更多