我正在尝试在我的iOS应用程序中创建websocket服务器和客户端,我在这里的示例实现的帮助下成功地做到了这一点。(https://github.com/apple/swift-nio/tree/master/Sources/NIOWebSocketServer) -所以目前的工作情况是,我在应用程序启动时运行websocket服务器,然后在可以连接到它的webview中加载客户端。
现在我的问题是我想让我的服务器保护websocket服务器(基本上是从一个HTTPS html页面连接到websocket服务器)
我是网络编程的新手,至少可以说,Swift-nio文档是缺乏的。据我所知,我可以使用(https://github.com/apple/swift-nio-transport-services)
我找到了这个线程,这正是我需要的- https://github.com/apple/swift-nio-transport-services/issues/39 -我可以禁用TLS身份验证,因为我不在乎我的用例,只要我能连接上websocket。
所以我的问题是如何扩展我的客户机(https://github.com/apple/swift-nio/tree/master/Sources/NIOWebSocketClient)和服务器(https://github.com/apple/swift-nio/tree/master/Sources/NIOWebSocketServer)以使用swift-nio-transport-service。
我可以添加NIOSSLContext之类的东西,但我认为我需要添加EventLoopGroup和新的bootstrap方法。我知道答案就在那里……但我似乎就是找不到它。
任何指针都将不胜感激。
谢谢。
发布于 2019-08-13 02:52:56
要将简单的NIO服务器转换为NIOTransportServices服务器,您需要进行以下更改:
NIOTransportServices的依赖项添加到您的服务器。MultiThreadedEventLoopGroup更改为NIOTSListenerBootstrap.ServerBootstrap to NIOTSConnectionBootstrap.ServerBootstrap并运行您的代码。一些ChannelOption不能在NIOTransportServices中工作,但大多数可以:确认一切正常工作的最简单方法是快速测试公共流。
这不会向您的应用程序添加任何额外的功能,但它确实为您提供了使用iOS API的相同功能。
要将TLS添加到NIOTSConnectionBootstrap或NIOTSListenerBootstrap,可以使用.tlsOptions函数。例如:
NIOTSListenerBootstrap(group: group)
.tlsOptions(myTLSOptions())配置NWProtocolTLS.Options是一件有点棘手的事情。您需要获取一个SecIdentity,这需要与密钥链交互。Quinn已经在某种程度上讨论了here。
一旦你有了SecIdentity,你就可以像这样使用它:
func myTLSOptions() -> NWProtocolTLS.Options {
let options = NWProtocolTLS.Options()
let yourSecIdentity = // you have to implement something here
sec_protocol_options_set_local_identity(options.securityProtocolOptions, sec_identity_create(yourSecIdentity)
return options
}一旦你写好了代码,一切都应该很顺利!
作为一个扩展,如果您想保护Linux上的NIO服务器,可以使用swift-nio-ssl来实现。这有单独的配置,因为密钥链API不可用,因此您需要从文件加载更多的密钥和证书。
发布于 2020-11-17 08:55:48
我需要一个不使用SecIdentity或NIOTransportServices的安全websocket,所以基于@Lukasa关于swift-nio-ssl的提示,我拼凑了一个看起来工作正常的示例。
我不知道它是否正确,但我把它放在这里,以防其他人能从中受益。为简洁起见,省略了try故障时的错误处理和中止。
let configuration = TLSConfiguration.forServer(certificateChain: try! NIOSSLCertificate.fromPEMFile("/path/to/your/tlsCert.pem").map { .certificate($0) }, privateKey: .file("/path/to/your/tlsKey.pem"))
let sslContext = try! NIOSSLContext(configuration: configuration)
let upgradePipelineHandler: (Channel, HTTPRequestHead) -> EventLoopFuture<Void> = { channel, req in
WebSocket.server(on: channel) { ws in
ws.send("You have connected to WebSocket")
ws.onText { ws, string in
print("Received text: \(string)")
}
ws.onBinary { ws, buffer in
// We don't accept any Binary data
}
ws.onClose.whenSuccess { value in
print("onClose")
}
}
}
self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 2)
let port: Int = 5759
let promise = self.eventLoopGroup!.next().makePromise(of: String.self)
_ = try? ServerBootstrap(group: self.eventLoopGroup!)
// Specify backlog and enable SO_REUSEADDR for the server itself
.serverChannelOption(ChannelOptions.backlog, value: 256)
.serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
.childChannelInitializer { channel in
let handler = NIOSSLServerHandler(context: sslContext)
_ = channel.pipeline.addHandler(handler)
let webSocket = NIOWebSocketServerUpgrader(
shouldUpgrade: { channel, req in
return channel.eventLoop.makeSucceededFuture([:])
},
upgradePipelineHandler: upgradePipelineHandler
)
return channel.pipeline.configureHTTPServerPipeline(
withServerUpgrade: (
upgraders: [webSocket],
completionHandler: { ctx in
// complete
})
)
}.bind(host: "0.0.0.0", port: port).wait()
_ = try! promise.futureResult.wait()
try! server.close(mode: .all).wait()https://stackoverflow.com/questions/57465854
复制相似问题