1tp 中文文档教程
1tp
一个传输协议来统治它们——在各种通信协议之上提供网络套接字抽象
Summary
1tp 的目标是提供一个单一的解决方案来连接任何两个可用的端点——公共的、私有的、移动的、位于 NAT 盒后面的……为此,1tp 充当各种现有传输的包装器,例如 UDP、TCP、WebRTC 和 TURN(更多将在以后的版本中出现)。 这些传输的内部细节通过类似于节点的网络 API 的 API 隐藏,使用套接字和流。 此外,1tp 在两个端点之间建立连接时总是尝试使用“最便宜”的传输。 例如,如果两个端点共享同一网络,则 1tp 将设置 UDP 或 TCP 连接。 如果两个端点位于对称 NAT 框后面,则 1tp 将通过共享中继服务器协商 TURN 或 WebRTC 会话。
Features
- stream based API, highly inspired by node's net API
- current version includes UDP, TCP, WebRTC and TURN connectors -- extending UDP with hole punching + integrating other transports such as websockets, GCM and tor is WiP.
- connection setup mechanism tries to select the 'cheapest' transport -- using different schedulers to execute connection handshakes sequential (default) or in parallel (experimental)
- can be browserified (to be used in chrome and cordova apps)
Install
npm install 1tp
Usage
'use strict'
var onetp = require('1tp')
var net = onetp.net
// 1tp transports
var UdpTransport = onetp.transports.udp
var TcpTransport = onetp.transports.tcp
var TurnTransport = onetp.transports.turn
var WebRtcTransport = onetp.transports.webrtc
// local signaling service to exchange turn handshake messages
var LocalSignaling = onetp.signaling.local
var localSignaling = new LocalSignaling()
// 1tp-registrar signaling service to exchange turn handshake messages
var WebSocketSignaling = onetp.signaling.websocket
// specify which server transports to 'activate'
var serverTransports = []
serverTransports.push(new UdpTransport())
serverTransports.push(new TcpTransport())
serverTransports.push(new TurnTransport({
turnServer: IP_ADDRESS,
turnPort: PORT,
turnUsername: USERNAME,
turnPassword: PASSWORD,
//signaling: localSignaling,
signaling: new WebSocketSignaling({
url: ONETP_REGISTRAR
})
}))
serverTransports.push(new WebRtcTransport({
config: { iceServers: [ { url: 'stun:stun.l.google.com:19305' } ] },
//signaling: localSignaling,
signaling: new WebSocketSignaling({
url: ONETP_REGISTRAR
})
}))
// create server instance
var onetpServer = net.createServer(serverTransports, function (connection) {
console.log('server connection established')
// create echo channel
connection.pipe(connection)
})
// listen for connect event
onetpServer.on('listening', function () {
// specify which client transports to 'activate'
var clientTransports = []
clientTransports.push(new UdpTransport())
clientTransports.push(new TcpTransport())
clientTransports.push(new TurnTransport({
turnServer: IP_ADDRESS,
turnPort: PORT,
turnUsername: USERNAME,
turnPassword: PASSWORD,
//signaling: localSignaling,
signaling: new WebSocketSignaling({
url: ONETP_REGISTRAR
})
}))
clientTransports.push(new WebRtcTransport({
config: { iceServers: [ { url: 'stun:23.21.150.121' } ] }
//signaling: localSignaling,
signaling: new WebSocketSignaling({
url: ONETP_REGISTRAR
})
}))
//
var onetpClient = net.createConnection(onetpServer.address(), clientTransports, function () {
console.log('client connection established')
onetpClient.write('hello world')
})
onetpClient.on('data', function (data) {
console.log(data.toString())
})
})
// launch server
onetpServer.listen()
API
var server = new Server([transports][, connectionListener])
创建一个新的 1tp 服务器实例。
可选的 connectionListener
参数自动设置为 connection
事件的侦听器。
transports
参数指定此服务器实例必须激活的可选传输协议数组。 1tp 的当前实现包括以下传输(另请参见上面的示例):
onetp.transports.udp
-- creates UDP dgram socketonetp.transports.tcp
-- creates TCP net server socketonetp.transports.turn
-- creates TURN socketonetp.transports.webrtc
-- creates WebRTC socket
onetp.transports.udp
和 onetp.transports.tcp
不需要额外的属性。 onetp.transports.turn
,相比之下,接受以下规范:
turnServer
(mandatory): IP address of the TURN server to interact withturnPort
(mandatory): port number of that TURN serverturnUserName
(mandatory): username to access this TURN serverturnPassword
(mandatory): user password to access TURN serverturnProtocol
(optional): transport protocol to interact with TURN server -- default is UDP, see example for using TCP insteadsignaling
(mandatory): specify which signaling server to use (loopback or 1tp-registrar). When using 1tp-registrar), you need to specify the URL of the server
onetp.transports.webrtc
还需要指定它应该使用的signaling
服务器. 此外,此传输接受所有 simple-peer(数据通道)选项。
在未指定要使用的传输方式的情况下创建服务器实例时,1tp
- activates the transports that are compatible with the runtime -- see compatibility table below, and
- activates TURN if environment variables
TURN_ADDR
,TURN_PORT
,TURN_USER
,TURN_PASS
andONETP_REGISTRAR
are all set
server.listen([listeningInfo][, callback])
指示 1tp 服务器开始接受连接。
listeningInfo
参数指定一个可选的传输绑定属性数组。 1tp 在指示它们开始接受连接时将这些参数传递给关联的传输协议。 下面的示例说明了一个 listeningInfo
对象通知 1tp 将其 udp 传输绑定到 127.0.0.1/20000 并将其 tcp 传输绑定到 127.0.0.1/20001 请
[{
transportType: 'udp',
transportInfo: {
address: '127.0.0.1',
port: 20000
}
}, {
transportType: 'tcp',
transportInfo: {
address: '127.0.0.1',
port: 20001
}
}]
注意 listeningInfo
数据是指示性的. 如果由于 listeningInfo
数据不正确(例如地址不可用)导致监听操作失败,则 1tp 服务器会在没有 listeningInfo
的情况下重试执行此操作。
可选的 callback
参数自动设置为 listening
事件的侦听器。
server.listenP([listeningInfo])
指示 1tp 服务器开始接受连接。 此函数不会触发 listening
事件,而是返回一个承诺,一旦所有已注册的传输协议都接受连接,该承诺就会实现。 此 promise 返回与 server.address()
相同的 connectionInfo
—— 见下文
server.address()
返回活动传输生成的 connectionInfo
。 此 connectionInfo
是传输特定端点信息的数组。 下面的示例说明了 1tp 服务器的 connectionInfo
地址
[ { transportType: 'udp',
transportInfo: { address: '192.168.1.30', port: 61773 },
version: '0.17.4' },
{ transportType: 'udp',
transportInfo: { address: '192.168.241.1', port: 61773 },
version: '0.17.4' },
{ transportType: 'tcp',
transportInfo: { address: '192.168.1.30', port: 61564 },
version: '0.17.4' },
{ transportType: 'tcp',
transportInfo: { address: '192.168.241.1', port: 61564 },
version: '0.17.4' },
{ transportType: 'turn-tcp',
transportInfo:
{ type: 'websocket-signaling',
uid: '1636e5e5437eb1733e1d22d21a50e478',
url: 'http://1.2.3.4/' },
version: '0.17.4' } ]
server.close()
阻止服务器接受新连接并保持现有连接。 此函数是异步的,当所有连接结束并且服务器发出“关闭”事件时,服务器最终关闭。 一旦“关闭”事件发生,将调用可选的回调。 [从 nodejs 文档复制]
var socket = new Socket([transports][, args])
创建一个新的 1tp 套接字(客户端)对象。
可选的 transports
参数指定此套接字应该使用哪些传输协议来建立与 1tp 服务器的连接。 有关这些传输协议规范的更多详细信息,请参见上文。
可选的 args
对象包括指定此套接字行为的附加标志。 目前,仅支持 parallelConnectionSetup
标志,指示套接字并行而不是顺序安排所有连接尝试(这是默认行为)。 请注意,这仍然是一个高度实验的功能。
socket.connect(connectionInfo[, connectListener])
设置与 1tp 服务器的连接。
connectionInfo
参数指定要连接的 1tp 服务器。 如上所述,此 connectionInfo
对象是传输特定端点信息的集合。
可选的 connectListener
参数自动设置为 connect
事件的侦听器。
socket.isConnected()
如果其中一种传输协议已与 1tp 服务器建立连接,则返回 true。
socket.remoteAddress
包含已连接对等方的 connectionInfo
。
socket.destroy()
关闭套接字,完成此操作后无法再进行通信。 关闭连接时发出 close
事件。
socket.end()
半关闭套接字,服务器可能仍会结束一些数据。
socket.setTimeout(timeout[, callback])
在 timeout
毫秒不活动后将套接字设置为超时。 套接字然后触发 timeout
事件。
如果 timeout
为 0,则禁用现有的空闲超时。
可选的 callback
自动设置为 timeout
事件的一次性侦听器。
socket.write(data[, encoding][, callback])
在套接字上发送数据。
net.createServer([transports][, connectionListener])
创建并返回一个新的 1tp 服务器实例。
transports
参数指定此服务器实例必须激活的可选传输协议数组。 有关更多详细信息,请参见上文。
可选的 connectionListener
参数自动设置为 connection
事件的侦听器。
net.createConnection(connectionInfo[, transports][, args][, connectListener])
创建并返回一个新的 1tp 套接字实例。
connectionInfo
参数指定要连接的端点。 如上所述,此 connectionInfo
是传输特定端点信息的数组。
可选的 transports
参数指定此套接字应该使用哪些传输协议来建立与 1tp 服务器的连接。 有关这些传输协议规范的更多详细信息,请参见上文。
可选的 args
对象包括指定此套接字行为的附加标志。 有关此选项的更多详细信息,请参见上文。
可选的 connectListener
参数自动设置为 connect
事件的侦听器。
Events
server.on('connection', function(socket) {})
建立新连接时发出。 socket
是 1tp 的 net.Socket
的实例。
server.on('error', function(error) {})
发生错误时发出。
server.on('listening', function() {})
在调用 server.listen
后所有已注册的传输协议都接受连接时发出。
socket.on('connect', function() {})
当成功建立套接字连接时发出——即传输协议之一已与 1tp 服务器建立连接。
socket.on('data', function(data) {})
收到数据时发出。 data
参数是一个缓冲区。
socket.on('end', function() {})
当连接的套接字结束其写入流时发出。
socket.on('finish', function() {})
当套接字的读取流中没有更多数据可供使用时发出。
socket.on('close', function() {})
在套接字完全关闭后发出——在执行 socket.destroy
socket.on('error', function(error) {})
发生错误时发出。
socket.on('timeout', function() {})
如果套接字因不活动而超时,则发出——通知套接字已空闲。
Chrome and cordova apps
gulp browserify [--production]
在 build
文件夹中创建 1tp.debug.js
和 1tp.min.js
,可用于 chrome 和 cordova 应用程序。 在cordova应用中集成1tp时,使用cordova-plugin-chrome-apps-sockets-udp
和cordova-plugin-chrome-apps-system-network
插件~~和 cordova-plugin-chrome-apps-sockets-tcp
和 cordova-plugin-chrome-apps-sockets-tcpserver plugins
~~(tcp cordova 插件产生错误):
cordova plugin add cordova-plugin-chrome-apps-sockets-udp
cordova plugin add cordova-plugin-networkinterface
Compatibility -- current status
UDP | TCP | TURN+UDP | TURN+TCP | WebRTC | |
---|---|---|---|---|---|
node.js x86 | + | + | + | + | + |
node.js arm | + | + | + | + | - |
chrome browser | - | - | - | - | + |
chrome app | + | + | + | + | + |
cordova android | + | - | + | - | + |
cordova ios | + | - | + | - | - |
Examples
见示例目录。
1tp
One transport protocol to rule them all -- offering net socket abstraction on top of various communication protocols
Summary
Goal of 1tp is to offer a single solution for connecting any two available endpoints -- public, private, mobile, located behind NAT boxes, … To accomplish this, 1tp acts as a wrapper around various existing transports such as UDP, TCP, WebRTC and TURN (more to come in later releases). The internal details of these transports are concealed via an API similar to node's net API, using sockets and streams. Furthermore, 1tp always tries to use the 'cheapest' transport when establishing a connection between two endpoints. If both endpoints are sharing the same network, for instance, then 1tp will setup a UDP or a TCP connection. If two endpoints are located behind symmetric NAT boxes, then 1tp will negotiate a TURN or a WebRTC session via a shared relay server.
Features
- stream based API, highly inspired by node's net API
- current version includes UDP, TCP, WebRTC and TURN connectors -- extending UDP with hole punching + integrating other transports such as websockets, GCM and tor is WiP.
- connection setup mechanism tries to select the 'cheapest' transport -- using different schedulers to execute connection handshakes sequential (default) or in parallel (experimental)
- can be browserified (to be used in chrome and cordova apps)
Install
npm install 1tp
Usage
'use strict'
var onetp = require('1tp')
var net = onetp.net
// 1tp transports
var UdpTransport = onetp.transports.udp
var TcpTransport = onetp.transports.tcp
var TurnTransport = onetp.transports.turn
var WebRtcTransport = onetp.transports.webrtc
// local signaling service to exchange turn handshake messages
var LocalSignaling = onetp.signaling.local
var localSignaling = new LocalSignaling()
// 1tp-registrar signaling service to exchange turn handshake messages
var WebSocketSignaling = onetp.signaling.websocket
// specify which server transports to 'activate'
var serverTransports = []
serverTransports.push(new UdpTransport())
serverTransports.push(new TcpTransport())
serverTransports.push(new TurnTransport({
turnServer: IP_ADDRESS,
turnPort: PORT,
turnUsername: USERNAME,
turnPassword: PASSWORD,
//signaling: localSignaling,
signaling: new WebSocketSignaling({
url: ONETP_REGISTRAR
})
}))
serverTransports.push(new WebRtcTransport({
config: { iceServers: [ { url: 'stun:stun.l.google.com:19305' } ] },
//signaling: localSignaling,
signaling: new WebSocketSignaling({
url: ONETP_REGISTRAR
})
}))
// create server instance
var onetpServer = net.createServer(serverTransports, function (connection) {
console.log('server connection established')
// create echo channel
connection.pipe(connection)
})
// listen for connect event
onetpServer.on('listening', function () {
// specify which client transports to 'activate'
var clientTransports = []
clientTransports.push(new UdpTransport())
clientTransports.push(new TcpTransport())
clientTransports.push(new TurnTransport({
turnServer: IP_ADDRESS,
turnPort: PORT,
turnUsername: USERNAME,
turnPassword: PASSWORD,
//signaling: localSignaling,
signaling: new WebSocketSignaling({
url: ONETP_REGISTRAR
})
}))
clientTransports.push(new WebRtcTransport({
config: { iceServers: [ { url: 'stun:23.21.150.121' } ] }
//signaling: localSignaling,
signaling: new WebSocketSignaling({
url: ONETP_REGISTRAR
})
}))
//
var onetpClient = net.createConnection(onetpServer.address(), clientTransports, function () {
console.log('client connection established')
onetpClient.write('hello world')
})
onetpClient.on('data', function (data) {
console.log(data.toString())
})
})
// launch server
onetpServer.listen()
API
var server = new Server([transports][, connectionListener])
Create a new 1tp server instance.
The optional connectionListener
argument is automatically set as a listener for the connection
event.
The transports
argument specifies an optional array of transport protocols this server instance must activate. The current implementation of 1tp includes the following transports (see also example above):
onetp.transports.udp
-- creates UDP dgram socketonetp.transports.tcp
-- creates TCP net server socketonetp.transports.turn
-- creates TURN socketonetp.transports.webrtc
-- creates WebRTC socket
onetp.transports.udp
and onetp.transports.tcp
don't require additional attributes. onetp.transports.turn
, in contrast, accepts the following specs:
turnServer
(mandatory): IP address of the TURN server to interact withturnPort
(mandatory): port number of that TURN serverturnUserName
(mandatory): username to access this TURN serverturnPassword
(mandatory): user password to access TURN serverturnProtocol
(optional): transport protocol to interact with TURN server -- default is UDP, see example for using TCP insteadsignaling
(mandatory): specify which signaling server to use (loopback or 1tp-registrar). When using 1tp-registrar), you need to specify the URL of the server
onetp.transports.webrtc
also requires to specify what signaling
server it should use. Additionally, this transports accepts all simple-peer (data channel) options.
When creating a server instance without specifying which transports to use, 1tp
- activates the transports that are compatible with the runtime -- see compatibility table below, and
- activates TURN if environment variables
TURN_ADDR
,TURN_PORT
,TURN_USER
,TURN_PASS
andONETP_REGISTRAR
are all set
server.listen([listeningInfo][, callback])
Instruct the 1tp server to begin accepting connections.
The listeningInfo
parameter specifies an optional array of transport binding attributes. 1tp passes these parameters to the associated transport protocols when instructing them to begin accepting connections. The example below illustrates a listeningInfo
object informing 1tp to bind its udp transport to 127.0.0.1/20000 and its tcp transports to 127.0.0.1/20001
[{
transportType: 'udp',
transportInfo: {
address: '127.0.0.1',
port: 20000
}
}, {
transportType: 'tcp',
transportInfo: {
address: '127.0.0.1',
port: 20001
}
}]
Mind that listeningInfo
data is indicative. If the listen operation fails due to incorrect listeningInfo
data (such as an unavailable address), then the 1tp server retries executing this operation without listeningInfo
.
The optional callback
argument is automatically set as a listener for the listening
event.
server.listenP([listeningInfo])
Instruct the 1tp server to begin accepting connections. Instead of firing a listening
event, this function returns a promise that gets fulfilled once all registered transport protocols are accepting connections. This promise returns the same connectionInfo
as server.address()
-- see below
server.address()
Return the connectionInfo
generated by the active transports. This connectionInfo
is an array of transport specific endpoint information. The example below illustrates the connectionInfo
address of a 1tp server
[ { transportType: 'udp',
transportInfo: { address: '192.168.1.30', port: 61773 },
version: '0.17.4' },
{ transportType: 'udp',
transportInfo: { address: '192.168.241.1', port: 61773 },
version: '0.17.4' },
{ transportType: 'tcp',
transportInfo: { address: '192.168.1.30', port: 61564 },
version: '0.17.4' },
{ transportType: 'tcp',
transportInfo: { address: '192.168.241.1', port: 61564 },
version: '0.17.4' },
{ transportType: 'turn-tcp',
transportInfo:
{ type: 'websocket-signaling',
uid: '1636e5e5437eb1733e1d22d21a50e478',
url: 'http://1.2.3.4/' },
version: '0.17.4' } ]
server.close()
Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event. The optional callback will be called once the 'close' event occurs. [copied from nodejs docs]
var socket = new Socket([transports][, args])
Create a new 1tp socket (client) object.
The optional transports
argument specifies which transport protocols this socket should use to establish a connection with a 1tp server. See above for more details about the specification of these transport protocols.
The optional args
object includes additional flags that specify the behavior of this socket. Currently, only the parallelConnectionSetup
flag is supported, instructing the socket to schedule all connection attempts in parallel rather than sequential (which is the default behavior). Note that this is still a highly experimental feature.
socket.connect(connectionInfo[, connectListener])
Setup a connection with a 1tp server.
The connectionInfo
argument specifies the 1tp server to connect with. As specified above, this connectionInfo
object is a collection of transport specific endpoint information.
The optional connectListener
argument is automatically set as a listener for the connect
event.
socket.isConnected()
Returns true if one of the transport protocols has established a connection with a 1tp server.
socket.remoteAddress
Contains the connectionInfo
of the connected peer.
socket.destroy()
Closes the socket, no more communication possible after completing this operation. Emits a close
event when connection is closed.
socket.end()
Half-closes the socket, server may still end some data.
socket.setTimeout(timeout[, callback])
Sets the socket to timeout after timeout
milliseconds of inactivity. The socket then fires a timeout
event.
If timeout
is 0, then the existing idle timeout is disabled.
The optional callback
is automatically set as a one time listener for the timeout
event.
socket.write(data[, encoding][, callback])
Send data on the socket.
net.createServer([transports][, connectionListener])
Create and return a new 1tp server instance.
The transports
argument specifies an optional array of transport protocols this server instance must activate. See above for more details.
The optional connectionListener
argument is automatically set as a listener for the connection
event.
net.createConnection(connectionInfo[, transports][, args][, connectListener])
Create and return a new 1tp socket instance.
The connectionInfo
argument specifies the end-point to connect with. As specified above, this connectionInfo
is an array of transport specific endpoint information.
The optional transports
argument specifies which transport protocols this socket should use to establish a connection with a 1tp server. See above for more details about the specification of these transport protocols.
The optional args
object includes additional flags that specify the behavior of this socket. See above for more details about this option.
The optional connectListener
argument is automatically set as a listener for the connect
event.
Events
server.on('connection', function(socket) {})
Emitted when a new connection is made. socket
is an instance of 1tp's net.Socket
.
server.on('error', function(error) {})
Emitted when an error occurs.
server.on('listening', function() {})
Emitted once all registered transport protocols are accepting connections after calling server.listen
.
socket.on('connect', function() {})
Emitted when a socket connection is successfully established -- i.e. one of the transport protocols has established a connection with a 1tp server.
socket.on('data', function(data) {})
Emitted when data is received. The data
argument is a Buffer.
socket.on('end', function() {})
Emitted when the connected socket has ended its write stream.
socket.on('finish', function() {})
Emitted when there is no more data to be consumed from the socket's read stream.
socket.on('close', function() {})
Emitted once the socket is fully closed -- after executing socket.destroy
socket.on('error', function(error) {})
Emitted when an error occurs.
socket.on('timeout', function() {})
Emitted if the socket times out from inactivity -- notifying that the socket has been idle.
Chrome and cordova apps
gulp browserify [--production]
Creates 1tp.debug.js
and 1tp.min.js
in build
folder, which can be used in chrome and cordova apps. When integrating 1tp in a cordova app, use the cordova-plugin-chrome-apps-sockets-udp
and cordova-plugin-chrome-apps-system-network
plugins ~~and cordova-plugin-chrome-apps-sockets-tcp
and cordova-plugin-chrome-apps-sockets-tcpserver plugins
~~ (tcp cordova plugins generate errors):
cordova plugin add cordova-plugin-chrome-apps-sockets-udp
cordova plugin add cordova-plugin-networkinterface
Compatibility -- current status
UDP | TCP | TURN+UDP | TURN+TCP | WebRTC | |
---|---|---|---|---|---|
node.js x86 | + | + | + | + | + |
node.js arm | + | + | + | + | - |
chrome browser | - | - | - | - | + |
chrome app | + | + | + | + | + |
cordova android | + | - | + | - | + |
cordova ios | + | - | + | - | - |
Examples
See examples directory.