Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

swift-nio のアーキテクチャーと RxHttpClient

241 views

Published on

2018/09/13 に開催された俺コン2日目の発表資料です
https://orecon.connpass.com/event/94867/

主に Swift-NIO のアーキテクチャーについて解説しています

Published in: Technology
  • Be the first to comment

swift-nio のアーキテクチャーと RxHttpClient

  1. 1. Swift-NIO RxHttpClient orecon_ios(day: 2) Date(“2018-09-13(THU)”) (@mike_neck : “L is B”, : )
  2. 2. • try! Swift 2018 (1) - • try! Swift 2018 (2) - Swift-NIO • Swift-NIO RxHttpClient
  3. 3. try! Swift 2018 (1)
  4. 4. Swift-NIO • try! Swift 2018 • HTTP TCP/UDP • Norman Maurer Java Netty • Swift-NIO Netty • Swift Netty
  5. 5. Netty NIO • java.nio Netty (2004 6 version 2.1.0) • Java 1.3(J2SE 1.3) I/O read/write Blocking I/ O ( Old blocking I/O=OIO ) • Java 1.4(J2SE 1.4) select (New) I/O(IO) (2002) • select ( epoll/kqueue) I/O Non-blocking I/O • NIO( NIO Non-blocking I/O )
  6. 6. OIO socket_fd = socket(AF_INET, SOCK_STREAM, 0); bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)); listen(socket_fd, 20); while(1) { len = sizeof(client); sock = accept(socket_fd, (struct sockaddr *)&client, &len); memset(buf, 0, sizeof(buf)); recv(sock, buf, sizeof(buf), 0); // read send(sock, buf, (int)strlen(buf), 0); // write close(buf); }
  7. 7. fork/ socket_fd = socket(AF_INET, SOCK_STREAM, 0); bind(socket_fd, (struct sockaddr *)&addr, sizeof(addr)); listen(socket_fd, 20); while(1) { len = sizeof(client); sock = accept(socket_fd, (struct sockaddr *)&client, &len); memset(buf, 0, sizeof(buf)); recv(sock, buf, sizeof(buf), 0); // read send(sock, buf, (int)strlen(buf), 0); // write close(buf); } /
  8. 8. Pool OIO fork / Thread/proc Thread/proc Thread/proc accept DispatchQueue 64
  9. 9. OIO recv/ write I/O recv write recv write write recv write recv write recv block block block block block block OIO CPU I/O
  10. 10. OIO • CPU • • ( ) • • AWS/Azure/GCP
  11. 11. I/O kqueue(BSD) epoll(Linux)
  12. 12. I/O (I/O Multiplexing) • • read/write • OIO -> Thread/process read/write • I/O -> read/write read/write • I/O -> Non-Blocking I/O
  13. 13. I/O ( kqueue) /// … socket/socketsetopt/bind/listen int kq = kqueue(); struct kevent events; EV_SET(&event, socket_fd, EVFILT_READ, EV_ADD, 0, 0, NULL); kevent(kq, &event, 1, NULL, 0, NULL); while(1) { kevent(kq, NULL, 0, &event, 1, &timeout); if (event.ident == spcket_fd) { int client = accept_client(event.ident); // accept EV_SET(&event, client, EVFILT_READ, EV_ADD|EV_CLEAR, 0, 0, NULL); kevent(kq, &event, 1, NULL, 0, NULL); } else if (event.flags & EVFILT_READ) { char buf[8192]; read_message(event.ident, &buf); // read prepare_write(&event, &buf); // EV_SET EVFILT_WRITE kevent(kq, &event, 1, NULL, 0, NULL); } else { write_message(&event); // write } } epoll(Linux)
  14. 14. socket I/O EVFILT_READ EVFILT_WRITE kevent() accept()/read() write()/close() read()/write()
  15. 15. ( )OIO recv write recv write write recv write recv write recv block block block block block block OIO CPU I/O
  16. 16. I/O recv write recv writewrite recv writerecv write recv I/O • • CPU • 1
  17. 17. I/O • • OIO • read/write
  18. 18. Swift-NIO • I/O Swift • • API • Linux(Ubuntu)/MacOSX • API Non-Blocking I/O • • MacOS 14 Network (swift-nio-transport- services) • SSL/TLS (swift-nio-ssl)
  19. 19. try! Swift 2018 (2)
  20. 20. EventLoopGroup Swift-NIO EventLoop ChannelPipeline EventLoop Channel Channel Channel ChannelHandler Bootstrap
  21. 21. EventLoop & EventLoopGroup // while true { let events = multiplexer.findEvents() for event in events { event.channel.handleEvent(event) } }
  22. 22. EventLoop & EventLoopGroup • EventLoop • Swift-NIO • EventLoop Thread • Channel/ChannelHandler Thread • EventLoopGroup • Channel EventLoop
  23. 23. Channel • • read/write/close/connect/bind • ChannelFuture • 1 ChannelPipeline /
  24. 24. ChannelPipeline & ChannelHandler Channel read channelRead channelRead write write writewriteToSocket ChannelInboundHandler /ChannelOutboundHandler
  25. 25. ChannelPipeline • • ChannelHandler • ( ) head tail • head -> tail • tail -> head
  26. 26. ChannelHandler • ( ) • ChannelInboundHandler - (read) • ChannelOutboundHandler - (write) • Handler ByteBuffer String HTTP Header HTTP bodyByteBuffer SSLHandler HTTPDecoder
  27. 27. Bootstrap • • • (bind/listen) • (connect) • EventLoopGroup • ChannelOption(socket option) • ChannelHandler
  28. 28.
  29. 29. Swift-NIO GitHub https://github.com/mike-neck/swift-nio-showcase
  30. 30. Swift-NIO HTTP
  31. 31. Swift-NIO Http Client 1. ClientBootstrap host 2. ChannelPipeline ChannelHandler • https host OpenSSLHandler • HTTPRequestEncoder/HTTPResponseDecoder/ ChannelHandler 3. HTTPRequestPart Channel write 4. OpenSSLHandler SSL/TLS
  32. 32. Swift-NIO Http Client 5. HTTPRequestEncoder write HTTPRequestPart ByteBuffer 6. OpenSSLHandler write ByteBuffer Channel 7. OpenSSLHandler (ByteBuffer) channelRead 8. HTTPResponseDecoder channelRead ByteBuffer HTTPResponsePart 9. ChannelHandler HTTPResponsePart
  33. 33. • Bootstrap EventLoopGroup( 1 2 ) • ChannelOption /ChannelInitializer • Bootstrap host • connect EventLoopFuture<Channel> • ( ) EventLoopFuture let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) let bootstrap = ClientBootstrap(group: eventLoopGroup) .channelOption(soReuseeAddr, 1) // let future = bootstrap.connect(host: “example.com”, port: 443) 1.ClientBootstrap host
  34. 34. • ClientBootstrap channelInitializer ChannelHandler ChannelPipeline • ChannelPipeline (head) (tail) • HttpClient • https OpenSSLHandler • HttpRequestEncoder/HttpResponseDecoder • ChannelInboundHandler .channelInitializer { channel in if https { let openSslHandler = OpenSSLHandler( context: sslContext, serverHostname: “example.com”) channel.pipeline.add(handler: openSslHandler) } _ = channel.pipeline.addHTTPClientHandlers() return channel.pipeline.add(handler: HttpResponseHandler()) } 2. ChannelPipeline
  35. 35. • http / HTTPClientRequestPart • .head(HTTPRequestHead) • .body(ByteBuffer) • .end(HTTPRequestHead?) • HTTPRequestHead • HTTPVersion / HTTPMethod / url • HTTPHeaders(name value (String,String) ) • channel write writeAndFlush EventLoopFuture<Void> var request = HTTPRequestHead( version: HTTPVersion(major:1,minor:1), method: HTTPMethod.GET, url: “https://example.com/api/1/foo?query=bar”) request.headers = HTTPHeaders([ (“Host”,”example.com”), (“User-Agent”,”swift-nio”), (“Accept-Encoding”,”identity”),(“Accept”,”application/json”),]) _ = channel.write(HTTPClientRequestPart.head(request)) let future = channel.writeAndFlush(HTTPClientRequestPart.end(nil)) 3. HTTPRequestPart( ) Channel
  36. 36. Swift-NIO Http Client 4. OpenSSLHandler SSL/TLS 5. HTTPRequestEncoder write HTTPRequestPart ByteBuffer 6. OpenSSLHandler write ByteBuffer Channel 7. OpenSSLHandler (ByteBuffer) channelRead 8. HTTPResponseDecoder channelRead ByteBuffer HTTPResponsePart Swift-NIO
  37. 37. • http / HTTPClientRequestPart • .head(HTTPRequestHead) • .body(ByteBuffer) • .end(HTTPRequestHead?) • HTTPRequestHead • HTTPVersion / HTTPMethod / url • HTTPHeaders(name value (String,String) ) • channel write writeAndFlush EventLoopFuture<Void> typealias InboundIn = HTTPClientResponsePart func channelRead(ctx:ChannelHandlerContext,data:NIOAny) { let responsePart = unwrapInboundIn(data) switch responsePart { case .head(let header): // case .body(let byteBuffer): // case .end(_): // 9. HttpResponseHandler
  38. 38. Swift-NIO • • ChannelHandler • channelRead -> channelReadComplete -> channelRead • ChannelOption
  39. 39. RxHttpClient • EventLoopFuture ChannelOption Channel Swift-NIO • HTTP URL • (? ) RxSwift
  40. 40. let eventLoopGroup = … let client: HttpClient = RxHttpClient.newClient( share: eventLoopGroup) let response: Single<Response> = httpClient .get(.https(“example.com”)) .path(“/api/1/team/users”) .authorization(.bearer(“XXXX”)) .header(“Accept”, “application/json”) .asSingle() response.flatMap { $0.bodyAs(UserList.Type) } .subscribe { print($0) } RxHttpClient
  41. 41. https://github.com/mike-neck/RxHttpClient
  42. 42. For further study… • swift-nio(GitHub) • https://github.com/apple/swift-nio • README • SwiftNIO Docs • https://apple.github.io/swift-nio/docs/current/NIO/index.html • API • Netty in Action(Norman Maurer/Marvin Allen Wolfthal) • https://amzn.to/2QgrAZj • Netty • ( ) Netty(@mike_neck) • https://www.slideshare.net/mikeneck/jjug-ccc-2018-spring-i7-netty • Netty &
  43. 43. • • https://www.irasutoya.com/

×