Skip to content

Repository files navigation

swift-tokio-kcp

workflow status

swift-tokio-kcp provides kcp network communication capabilities to swift.

Kcp is a fast and reliable ARQ protocol targeting low latency network communication and is expected to work more stable than TCP in network environments with certain packet loss. swift-tokio-kcp is a binding of tokio_kcp.

Features

  • Since the core part of kcp communication is handled by tokio_kcp, which is a rust implementation, swift-tokio-kcp is expected to offer better performance, i.e. low latency and reduces cpu/memory consumption, compared to pure swift implementations.

write_10mb_profile

  • The exported swift package contains only pre-built libraries, so you don't need a rust environment to use this package. See the code in tags for detail, e.g. tag 0.1.0.

Example

Client example:

import TokioKcp

func clientExample() async throws {
  // Initialize a tokio runtime. This should be done only once before you de-init the runtime.
  // You can call `KcpStream.deinitTokioRuntime()` to de-init the runtime.
  try await KcpStream.initTokioRuntime()

  // Create a kcp stream that will conncet to 127.0.0.1:3100.
  let stream = KcpStream(addr: "127.0.0.1:3100")
  // Set kcp conifg. You can also manually modify `stream.config` before `connect()`.
  stream.setFastestConfig()
  // Connect the stream.
  try await stream.connect()
  let dataToWrite = "Hello!".data(using: .utf8)!
  // Write some data to the remote.
  try await stream.write(data: dataToWrite)
  // Read some data from the remote.
  let data = try await stream.read()
  print("[client] receive: \(String(data: data, encoding: .utf8)!)")
}

You can also start a kcp server for testing if you don't have one:

import TokioKcp

func serverExample() async throws {
  // Should call `KcpStream.initTokioRuntime()` if you don't have.

  // Create a kcp listener that will bind to 0.0.0.0:3100.
  let listener = KcpListener(addr: "0.0.0.0:3100")
  // Set kcp conifg. You can also manually modify `listener.config` before `bind()`.
  listener.setFastestConfig()
  // Bind the listener.
  try await listener.bind()

  while true {
    do {
      // Accept new clients
      let stream = try await listener.accept()
      Task {
        // Use the stream to write or read some data to/from the remote.
        // ....
      }
    } catch {
      print("failed to accept stream, error \(error)")
    }
  }
}

Build from Source

Install dependenceis:

make prepare-apple

Build:

cargo run -p builder -- --release

Then, the swift package can be found in the output folder.

Publish

After build:

rm -rf output/.git
make move-dot-git-and-files
cd output
git add -A && git commit -m "release x.x.x"
git tag x.x.x && git push origin x.x.x
cd ../ && rm -rf output/.git && git clean -df

References

  • tokio_kcp A Kcp implementation for tokio
  • kcp KCP - A Fast and Reliable ARQ Protocol
  • uniffi-rs a multi-language bindings generator for rust
  • uniffi-rs-fullstack-examples Build Rust for Android and iOS (with potential for all mobile platforms, Windows, Mac and Web*)

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages