For*_*vin 10 javascript tcp websocket socket.io webrtc
当服务器发送websocket消息并且数据包丢失时,客户端将不会看到任何消息,直到服务器意识到数据包丢失,重新发送等等它实际到达客户端...正如您所想象的那样,这可能会导致实时应用程序出现不必要的大量滞后.
我知道这是通过设计发生的,因为TCP可确保以正确的顺序传送数据包.
但我想知道是否有任何类似socket.io的库可以解决这个问题.从头开始编写类似的内容似乎要做很多工作.
通过解决我的意思是例如使用UDP而不是TCP使用新的WebRTC功能甚至更简单,只需创建多个websocket连接并确保通过不同的连接发送连续的消息.
我知道客户端可能会以这种方式接收过时的信息,但忽略它们可以轻松弥补.您只需要为每条消息添加一个递增ID.
例如,socket.io的包装器会很好.具有相同接口但内部创建多个连接的东西.我试图开始为此编写一个包装类,但我真的不确定如何在包装器和socket.io实例之间正确传递事件.
我的意思是,如果我只是将在套接字上触发的所有事件传递给包装器类,并将包装类上触发的所有事件传递给其中一个socket.io实例,那么每个事件都将永远循环.
const EventEmitter = require('events');
const Server = require('socket.io');
class ServerWrapper extends EventEmitter {
constructor() {
/* instanciation manual:
new ServerWrapper(httpServer[, options][, connectionCount])
new ServerWrapper(port[, options][, connectionCount])
new ServerWrapper(options[, connectionCount])
(connectionCount is the number of socket.io instances that will be used)
*/
let port, srv, opts; // not really necessary
let connCount = 5; //default
let args = arguments;
// The following if statements are used to maintain full compatibility with the original socket.io constructor (https://socket.io/docs/server-api/)
if (arguments.length === 0)
return;
else if (arguments.length === 1)
opts = arguments[0];
else if (arguments.length === 2) {
if (typeof arguments[0] === 'object' && arguments[1] === 'object') {
srv = arguments[0];
opts = arguments[1];
} else if (typeof arguments[0] === 'number' && arguments[1] === 'object') {
port = arguments[0];
opts = arguments[1];
} else if (typeof arguments[0] === 'object' && arguments[1] === 'number') {
opts = arguments[0];
connCount = arguments[1];
args = arguments.pop();
}
} else if (arguments.length === 3) {
opts = arguments[1];
connCount = arguments[2];
if (typeof arguments[0] === 'number')
port = arguments[0];
else
srv = arguments[0];
args = arguments.pop();
}
// Create X socket.io instances and store them in this array
this._io = [];
for (let i=0; i<connCount; i++)
this._io.push(new Server(args));
// Pass all socket.io events to this wrapper class
this._io.forEach(io=>{
io.on("*",this.emit);
});
// Pass all events fired on this wrapper class to one of the socket.io instances:
this.nextConn = 0;
this.on("*", (event,data) => {
this._io[this.nextConn].emit(...arguments);
this.nextConn++;
if (this.nextConn >= this.connCount)
this.nextConn = 0;
});
let sioProps = ['sockets'];
sioProps.forEach(prop=>{ // map all socket.io properties from the first instance to 'this[prop]'
this[prop] = this._io[0][prop];
});
let sioMethods = ['seveClient','path','adapter','origins','attach','listen','bind','onconnection','of','close'];
sioMethods.forEach(fName=>{ // redirect all socket.io function calls to all the socket.io instances
this[fName] = () => {
this._io.forEach(io=>{
this[fName] = io[fName](...arguments);
});
};
});
}
}
module.exports = ServerWrapper;
Run Code Online (Sandbox Code Playgroud)
目前无法通过 WebRTC 从浏览器启动任意 UDP 连接。这里有一篇非常好的文章。
然而,浏览器插件当然可以与 UDP 通信 - 因此,如果这是一个可接受的方式,您的应用程序可能需要在这种情况下使用插件。
预构建解决方案有一些选项,特别是以下一个:
netcode.io是一个面向游戏开发人员的网络代码库,它实现了一些与 TCP over UDP 相同的面向连接的逻辑,但没有可交付性保证。
netcode.io-browser是适用于 Firefox 和 Chrome 的浏览器插件,允许您使用 netcode.io,而无需开发自己的浏览器扩展。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
207 次 |
| 最近记录: |