Skip to content

Commit

Permalink
add swiftnio implement
Browse files Browse the repository at this point in the history
  • Loading branch information
huiping192 committed Dec 17, 2023
1 parent 170d5e6 commit 751a0d5
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 6 deletions.
32 changes: 32 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"pins" : [
{
"identity" : "swift-atomics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-atomics.git",
"state" : {
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
"version" : "1.2.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "a902f1823a7ff3c9ab2fba0f992396b948eda307",
"version" : "1.0.5"
}
},
{
"identity" : "swift-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio",
"state" : {
"revision" : "702cd7c56d5d44eeba73fdf83918339b26dc855c",
"version" : "2.62.0"
}
}
],
"version" : 2
}
11 changes: 5 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,22 @@ import PackageDescription

let package = Package(
name: "HPRTMP",
platforms: [.iOS(.v14),.macOS(.v11)],
platforms: [.iOS(.v14), .macOS(.v11)],
products: [
.library(
name: "HPRTMP",
targets: ["HPRTMP"]
),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/apple/swift-nio", from: "2.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "HPRTMP",
dependencies: []),
dependencies: [
.product(name: "NIO", package: "swift-nio")
]),
.testTarget(
name: "HPRTMPTests",
dependencies: ["HPRTMP"]),
Expand Down
93 changes: 93 additions & 0 deletions Sources/HPRTMP/RTMPClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Foundation
import NIO

final class RTMPClientHandler: ChannelInboundHandler {
typealias InboundIn = Data
private let responseCallback: (Data) -> Void

init(responseCallback: @escaping (Data) -> Void) {
self.responseCallback = responseCallback
}

func channelRead(context: ChannelHandlerContext, data: NIOAny) {
let data = self.unwrapInboundIn(data)
responseCallback(data)
}
}

final class DataDecoder: ByteToMessageDecoder {
typealias InboundIn = ByteBuffer
typealias InboundOut = Data

func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState {
var data = Data()
buffer.readWithUnsafeReadableBytes { ptr in
data.append(ptr.baseAddress!.assumingMemoryBound(to: UInt8.self), count: ptr.count)
return ptr.count
}
context.fireChannelRead(wrapInboundOut(data))
return .continue
}
}

final class DataEncoder: MessageToByteEncoder {
typealias OutboundIn = Data
typealias OutboundOut = ByteBuffer

func encode(data: Data, out: inout ByteBuffer) throws {
out.writeBytes(data)
}
}

class RTMPClient {
private let group: EventLoopGroup
private var channel: Channel?
private let host: String
private let port: Int
private var responseCallback: ((Data) -> Void)?

init(host: String, port: Int) {
self.group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
self.host = host
self.port = port
}

func connect(responseCallback: @escaping (Data) -> Void) {
self.responseCallback = responseCallback
let bootstrap = ClientBootstrap(group: group)
.channelInitializer { channel in
channel.pipeline.addHandlers([
ByteToMessageHandler(DataDecoder()),
MessageToByteHandler(DataEncoder()),
RTMPClientHandler(responseCallback: self.responseReceived)
])
}

do {
self.channel = try bootstrap.connect(host: host, port: port).wait()
print("Connected to \(host):\(port)")
} catch {
print("Failed to connect: \(error)")
}
}

func send(data: Data) {
guard let channel = channel else {
print("Connection not established")
return
}
channel.writeAndFlush(data, promise: nil)
}

private func responseReceived(data: Data) {
responseCallback?(data)
}

func shutdown() {
do {
try group.syncShutdownGracefully()
} catch {
print("Error shutting down: \(error)")
}
}
}

0 comments on commit 751a0d5

Please sign in to comment.