sReto 3.0.0

sReto 3.0.0

测试已测试
语言语言 SwiftSwift
许可 MIT
发布上次发布2017年12月
SPM支持SPM

Stephan Krusche维护。



sReto 3.0.0

Reto:Swift实时协作的P2P框架。

sReto 2.0与Swift 3兼容!若要支持Swift 2,请使用旧版本,例如1.4.1。

注意:还有适用于Windows和Unix的Java版本jReto

关于

Reto是一个可扩展的P2P网络框架,用Swift和Java 8实现,两种语言提供相同的API。

框架的最重要特性包括

  • 查找点对点
  • 建立点之间连接
  • 执行可取消的数据传输
  • 支持路由连接(即无法直接通信的点仍然可以被发现并使用其他点转发数据)

Reto设计用于通过实现Reto "模块"轻松扩展以使用其他网络技术;默认情况下,它提供了两个模块

  • WlanModule:通过使用Bonjour进行查找和使用标准TCP/IP连接进行数据传输,在局域网内启用查找和连接
  • RemoteP2PModule:使用在线服务器促进点之间的通信。此模块使点能够相互发现并通过互联网通信;但是需要远程P2P服务器。

安装

安装sReto的推荐方法是使用CocoaPods包管理器,因为它提供灵活的依赖关系管理。

sReto 2.0可以作为框架集成到iOS 9.0+和OS X 10.9+。尽管它是用Swift实现的,但它可以在Objective-C和Swift项目中使用。以下是使用CocoaPods包含Reto所需的步骤。

使用

开始发现/广告

广告和发现由LocalPeer类管理。LocalPeer需要一个或多个Reto模块才能运行。在此示例中,我们将使用WlanModule

Swift

// 1. Create the WlanModule
let wlanModule = WlanModule(type: "ExampleType", dispatchQueue: DispatchQueue.main)
// 2. Create the LocalPeer
let localPeer = LocalPeer(modules: [wlanModule], dispatchQueue: DispatchQueue.main)
// 3. Starting the LocalPeer
localPeer.start(
  onPeerDiscovered: { peer in print("Discovered peer: \(peer)") },
  onPeerRemoved: { peer in print("Removed peer: \(peer)") },
  onIncomingConnection: { peer, connection in print("Received incoming connection: \(connection) from peer: \(peer)"") },
  displayName: "MyLocalPeer"
)

Objective-C

// 1. Create the WlanModule
WlanModule* wlanModule = [[WlanModule alloc] initWithType: "ExampleType" dispatchQueue: dispatch_get_main_queue()];
// 2. Create the LocalPeer
LocalPeer* localPeer = [[LocalPeer alloc] initWithModules: @[wlanModule] dispatchQueue: dispatch_get_main_queue())
// 3. Starting the LocalPeer
[localPeer startOnPeerDiscovered:^(RemotePeer *peer) {
  NSLog(@"Found peer: %@", peer);
} onPeerRemoved:^(RemotePeer *peer) {
  NSLog(@"Removed peer: %@", peer);
} onIncomingConnection:^(RemotePeer *peer, Connection *connection) {
  NSLog(@"Received incoming connection: %@ from peer: %@", connection, peer);
} displayName: @"MyLocalPeer"];

使用同一类型参数的WlanModule的任何两个应用程序将在局域网中发现彼此。因此,您应选择一个独特的类型参数。

在Swift和Java中,将一个dispatch queue传递给LocalPeer;所有网络操作都使用此队列执行。此外,所有回调也在此队列上发生。

Java中也使用相同的原则;这里使用Executor代替了调度队列。所有回调都是通过这个Executor的线程进行分发的。

在很多情况下,使用主调度队列/在GUI线程上运行的Executor是可以的,因为Reto不会在队列上执行任何阻塞操作。但是,如果有很多数据正在发送和处理,将操作移动到后台线程可能是个好主意。

当启动LocalPeer时,三个闭包作为参数传递。

  • 每当发现新的对等节点时,都会调用onPeerDiscovered闭包。
  • 每当丢失对等节点时,都会调用onPeerRemoved闭包。
  • 每当RemotePeerLocalPeer建立连接时,都会调用onIncomingConnection闭包。

第一个闭包可以让你访问到RemotePeer对象,这些对象可以用来与那些对等节点建立连接。

建立连接和发送数据

Swift

// 1. Establishing a connection
let connection = someRemotePeer.connect()
// 2. Registering a callback the onClose event
connection.onClose = { connection in print("Connection closed.") }
// 3. Receiving data
connection.onData = { data in print("Received data!") }
// 4. Sending data
connection.send(data: someData)

Objective-C

// 1. Establishing a connection
Connection *connection = [someRemotePeer connect];
// 2. Registering a callback the onClose event
connection.onClose = ^(Connection* connection) {
  NSLog(@"Connection closed.");
};
// 3. Receiving data
connection.onData = ^(Connection* connection, NSData* data) {
  NSLog(@"Received data!");
}
// 4. Sending data
[connection sendData: someData];

可以通过在RemotePeer上简单调用connect方法来建立连接。

这允许你注册一些用于不同事件的回调,例如,当连接关闭时被调用的onClose。然而,这些回调大多是可选的,但如果你想通过连接接收数据,则必须设置onTransferonData回调。

在这个例子中,设置了onData回调,当接收到数据时会被调用。对于更细粒度的数据传输控制,请使用onTransfer回调。

数据传输

虽然上述技术可以用来发送数据,但你可能需要更多的信息。`Transfer`类提供了更多信息和工具。以下仅给出使用这些特性的简短示例;然而,`Transfer`类还提供了更多方法和功能。请检查类文档以了解更多信息。

Swift

// 1. Configuring a connection to receive transfers example
someConnection.onTransfer = { 
  connection, transfer in 
  // 2. Configuring a transfer to let you handle data as it is received, instead of letting the transfer buffer all data
  transfer.onPartialData = { transfer, data in print("Received a chunk of data!") }
  // 3. Registering for progress updates
  transfer.onProgress = { transfer in print("Current progress: \(transfer.progress) of \(transfer.length)") }
}

// 4. Sending a transfer example with a data provider
let transfer = someConnection.send(dataLength: someData.length, dataProvider: { range in return someData })
// 5. Registering for progress updates
transfer.onProgress = { transfer in print("Current progress: \(transfer.progress) of \(transfer.length)") }

Objective-C

// 1. Configuring a connection to receive transfers example
connection.onTransfer = ^(Connection* connection, InTransfer* transfer) {
  // 2. Configuring a transfer to let you handle data as it is received, instead of letting the transfer buffer all data
  transfer.onPartialData = ^(Transfer* transfer, NSData* data) {
    NSLog(@"Received a chunk of data!");
  };
  // 3. Registering for progress updates
  transfer.onProgress = ^(Transfer* transfer) {
    NSLog(@"Current progress: %li of %li", transfer.progress, (long)transfer.length);
  };
};
// 4. Sending a transfer example with a data provider
Transfer* transfer = [connection sendWithDataLength: 1 dataProvider:^NSData *(NSRange range) {
  return somehowProvideDataForRange(range);
}];
// 5. Registering for progress updates
transfer.onProgress = ^(Transfer* transfer) {
  NSLog(@"Current progress: %li of %li", transfer.progress, transfer.length);
};