Ios Swift NIO安全websocket服务器
我正在尝试在我的iOS应用程序中创建websocket服务器和客户端,在这里的示例实现的帮助下,我成功地做到了这一点。()-所以当前的工作情况是,我在应用程序启动时运行websocket服务器,然后将客户端加载到可以连接到它的webview中 现在我的问题是我希望我的服务器是安全的websocket服务器(基本上是从HTTPS html页面连接到websocket服务器) 我是网络编程新手,至少可以说Swift nio文档是缺乏的。据我所知,我可以使用() 我找到了这个线程,这正是我所需要的--我可以禁用TLS身份验证,因为我不在乎我的用例,只要我可以连接websocket 所以我的问题是如何扩展我的客户机()和服务器()以使用swift nio传输服务 我可以添加Ios Swift NIO安全websocket服务器,ios,swift,websocket,server,swift-nio,Ios,Swift,Websocket,Server,Swift Nio,我正在尝试在我的iOS应用程序中创建websocket服务器和客户端,在这里的示例实现的帮助下,我成功地做到了这一点。()-所以当前的工作情况是,我在应用程序启动时运行websocket服务器,然后将客户端加载到可以连接到它的webview中 现在我的问题是我希望我的服务器是安全的websocket服务器(基本上是从HTTPS html页面连接到websocket服务器) 我是网络编程新手,至少可以说Swift nio文档是缺乏的。据我所知,我可以使用() 我找到了这个线程,这正是我所需要的--
NIOSSLContext
之类的东西,但我想我需要添加EventLoopGroup
和新的bootstrap
方法。我知道答案就在那里。。。。但我似乎无法准确地指出这一点
任何指示都将不胜感激
谢谢 要将简单的
NIO
服务器转换为NIOTransportServices
服务器,您需要进行以下更改:
NIOTransportServices
的依赖项添加到服务器multi-threadedeventloopgroup
更改为NIOTSEventLoopGroup
ClientBootstrap
更改为niotconnectionbootstrap
ServerBootstrap
更改为niotlistenerbootstrap
ChannelOption
s在NIOTransportServices
中不起作用,但大多数都起作用:确认事情正常运行的最简单方法是快速测试公共流
这不会给您的应用程序添加任何额外的功能,但它会使用iOS API为您提供相同的功能
要将TLS添加到niotConnectionBootstrap
或niotListenerBootstrap
,可以使用.tlsOptions
函数。例如:
NiotListenerBootstrap(组:组)
.tlsOptions(myTLSOptions())
配置NWProtocolTLS.Options
有些棘手。您需要获得一个SecIdentity
,它需要与钥匙链交互。奎因对此进行了一些讨论
一旦您有了SecIdentity
,您就可以这样使用它:
func myTLSOptions()->NWProtocolTLS.Options{
let options=NWProtocolTLS.options()
让yourSecIdentity=//您必须在这里实现一些东西
sec_协议(选项)设置(本地)标识(options.securityProtocolOptions),sec_标识(yourSecIdentity)
返回选项
}
一旦你编写了代码,一切都会顺利进行
作为一个扩展,如果您想在Linux上保护NIO服务器,您可以使用。这有单独的配置,因为密钥链API不可用,因此您可以从文件中加载更多的密钥和证书。我需要一个安全的websocket,而不需要使用
SecIdentity
或NIOTransportServices
,所以请放心关于@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()
let configuration=TLSConfiguration.forServer(certificateChain:try!NIOSSLCertificate.fromPEMFile(“/path/to/your/tlsCert.pem”).map{.certificate($0)},privateKey:.file(“/path/to/your/tlsKey.pem”))
让sslContext=try!NIOSSLContext(配置:配置)
让upgradePipelineHandler:(Channel,HTTPRequestHead)->EventLoopFuture={Channel,req in
服务器(在:通道上){ws-in
发送(“您已连接到WebSocket”)
ws.onText{ws,字符串输入
打印(“收到的文本:\(字符串)”)
}
ws.onBinary{ws,缓冲区在
//我们不接受任何二进制数据
}
ws.onClose.whenSuccess{中的值
打印(“onClose”)
}
}
}
self.eventLoopGroup=multi-threadedeventloopgroup(线程数:2)
let端口:Int=5759
让promise=self.eventLoopGroup!.next().makePromise(of:String.self)
_=try?ServerBootstrap(组:self.eventLoopGroup!)
//指定backlog并为服务器本身启用SO_REUSEADDR
.serverChannelOption(ChannelOptions.backlog,值:256)
.serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr),值:1)
.childChannelInitializer{channel in
let handler=NIOSSLServerHandler(上下文:sslContext)
_=channel.pipeline.addHandler(处理程序)
让webSocket=NIOWebSocketServerUpgrader(
应升级:{通道,请求在
返回channel.eventLoop.makeSucceededFuture([:])
},
upgradePipelineHandler:upgradePipelineHandler
)
返回channel.pipeline.configureHTTPServerPipeline(
使用服务器升级:(
升级者:[webSocket],
completionHandler:{ctx in
//完整的
})
)
}.bind(主机:“0.0.0.0”,端口:port).wait()
_=尝试!承诺。未来结果。等待()
尝试!服务器。关闭(模式:。全部)。等待()
我设法让客户端和服务器按照您的建议使用NIOTransportServices运行。因此,现在我正试图让SecIdentity
正常工作。因此我猜SecIdentity\u协议\u选项\u设置\u对等身份验证\u所需(options.securityProtocolOptions,false)
仍然损坏?我需要获得自签名证书吗