使用Kitura在Swift中进行全栈编程

Swift成为了完全开放源代码(Apache 2.0许可)项目,并且走得更远,这使得Swift不仅可以在Darwin设备上运行,而且可以在Linux和其他平台(例如Android,raspberry-pi,大型机)上运行。 所有繁重的工作都是由Swift社区完成的,以使Swift可以在Linux和多个平台上使用,并且还在不断增长。 这意味着在大多数平台上都可以使用Foundation API,Swift语言,所有标准库以及用于并发的Dispatch。 现在大约有数十种可用的框架,包括IBM的Kitura,PerfectlySoft的Perfect,基于Swift语言的Q理论的Vapor。

为什么选择Swift?

  • Swift是Java之类的高性能语言
  • Swift的内存使用率低
  • 重用客户端代码,工作空间,工具和组件可以加快开发速度并提高生产率

IBM的Kitura

Kitura是使用IBM开发的Swift语言编写的服务器端模块化框架。 Swift语言主要用于为Apple App Store创建基于iOS的应用程序。 开发人员必须为Java,Python,Ruby等后端编程选择不同的语言,基于Swift的客户端可以将其连接以进行CRUD操作。 Kitura使iOS开发人员更容易使用一种语言进行前端和后端编程,并创建完整的应用程序。

Kitura框架的重点

  • 基于模块化和打包的Web框架
  • 开箱即用,并利用Foundation API在macOS和Linux上创建应用程序。
  • Swift具有高性能,安全性和表现力,因此具有Kitura的特质。
  • 轻松部署到IBM Bluemix和Watson集成等云平台,以创建Cognitive应用程序。
  • Xcode支持可实现更快,更轻松的开发
  • Yeoman生成器可在几分钟内创建和部署您的应用

全栈演示

使用ServerSide Kitura,IBM Watson和IoT平台控制由PI驱动的机器人

我们将为Raspberry PI驱动的机器人创建一个Remote,并使用服务器端Kitura作为中间件。 该机器人还将与Watson Text-To-Speech服务集成在一起。 遥控器将能够控制机器人的两件事:

  • 输入文字让机器人说出来
  • 选择一种颜色让机器人闪烁

建筑

遥控器使用swift构建并运行在iOS设备上。RobotRemote Control应用程序使用公开的REST API与基于Kitura的服务器进行通信。 该服务器具有CRUD API以及一个接受远程输入并将其发送到IBM IoT平台的API。 服务器上的API从远程应用程序接收JSON数据,并以MQTT消息的形式发布到IoT平台。 服务器使用Aphid MQTT客户端将消息发布到IBM IoT平台上的某个主题。 该机器人是使用raspberry-PI构建的。 LED和扬声器已连接到raspberry-PI。 PI运行一个nodejs应用程序,该应用程序正在侦听来自IoT平台的MQTT消息,该主题与基于Kitura的服务器发布消息的主题相同。 接收到MQTT消息后,将使用Watson开发人员云SDK将接收到的文本转换为语音,并将其通过管道传输到安装在raspberry-PI中的扬声器。 树莓派PI还运行Python代码,将正确的颜色信号发送到LED,使其闪烁。

创建远程机器人服务器

先决条件:

  1. 确保已安装Node.js 8.0:
    节点— v
  2. 如果未安装Node.js,则可以下载并安装它:
    https://nodejs.org/download/release/v8.0.0/node-v8.0.0.pkg
  3. 安装Yeoman:
    npm install -g yo
  4. 安装Swift Server Generator:
    npm install -g generator-swiftserver

生成Swift服务器

您可以立即生成swift服务器,如下图所示。 一旦有了脚手架,就可以开始创建自己的路线和路线逻辑。

创建模型对象

您可以再次使用生成器来创建应用程序所需的模型对象,如图所示。

生成的代码

这将为模型对象生成CRUD API,并且位于Generated目录中。 RobotContentResource包含可访问的CRUD API的路由器。 默认情况下,API将通过路径公开

  / api / RobotContents 
/ api / RobotContents /:id

该项目具有Application.swift类,该类为服务器启动设置了初始配置。 它公开创建要创建的路由的路由器对象,一个ConfigurationManager来聚合来自不同来源的配置属性,包括命令行参数,环境变量,文件,远程资源和原始对象以及服务器将运行的端口。 完成所有设置后,Main.swift类将初始化路由器和其他配置,并分别使用initialize()和run()方法运行服务器。

 进口基金会 
进口Kitura
导入LoggerAPI
导入配置
导入生成
导入CloudFoundryConfig
导入SwiftMetrics
导入SwiftMetricsDash
 公共让路由器= Router() 
公共让经理= ConfigurationManager()
公共变量端口:整数= 8080
 公共函数initialize()抛出{ 
  manager.load(文件:“ config.json”,relativeFrom:.project) 
.load(.environmentVariables)
 端口= manager.port 
 让sm =试试SwiftMetrics() 
让_ =试试SwiftMetricsDash(swiftMetricsInstance:sm,端点:路由器)
  router.all(“ / *”,中间件:BodyParser()) 
router.all(“ /”,中间件:StaticFileServer())
 尝试initializeCRUDResources(管理器:管理器,路由器:路由器) 

  initializeSwaggerRoute(路径:ConfigurationManager.BasePath.project.path +“ /definitions/Remote-Robot.yaml”) 
router.get(“ / health”){请求,响应,_ in
尝试response.send(json:[“ status”:“ UP”])。end()
}
}
 公共功能run()引发{ 
Kitura.addHTTPServer(onPort:端口,with:路由器)
Kitura.run()
}

该应用程序使用HeliumLogger进行日志记录,使用SwiftMetrics显示有关服务器内存和cpu使用情况的度量标准,使用CloudConfigurations部署到IBM Bluemix平台,以及使用Kitura进行服务器端开发。 这些依赖关系是从Package.swift中的Swift Package Manager管理的,您想要使用的任何其他依赖关系都可以在此处添加。

 导入PackageDescription 
 让包=包( 
名称:“远程机器人”,
目标:[
Target(名称:“ Application”,依赖项:[.Target(name:“ Generated”)]),
目标(名称:“远程机器人”,依赖项:[。目标(名称:“应用程序”)])
],
依赖项:[
.Package(URL:“ https://github.com/IBM-Swift/Kitura.git”,majorVersion:1,minor:7),
.Package(URL:“ https://github.com/IBM-Swift/HeliumLogger.git”,majorVersion:1,minor:7),
.Package(URL:“ https://github.com/IBM-Swift/CloudConfiguration.git”,majorVersion:2),
.Package(URL:“ https://github.com/RuntimeTools/SwiftMetrics.git",majorVersion:1),
.Package(URL:“ https://github.com/IBM-Swift/Aphid.git”,majorVersion:0)
],
排除:[“ src”]

生成并运行

您可以从Xcode生成并运行生成的应用程序。 默认情况下,该应用程序侦听端口8080。 有内置的仪表板是应用程序生成的一部分。

  • Swift Metrics仪表板-您将能够监视传入的请求,响应时间,CPU利用率和内存占用量。
  • Swagger API Explorer-您将能够查看所有API定义,并且还可以使用仪表板测试API

可以使用URL http:// localhost:8080 / swiftmetrics-dash /访问Swift Metrics仪表板

生成的应用程序具有集成了Swagger的API资源管理器,可以通过URL http:// localhost:8080 / explorer /在浏览器中进行访问

创建路线

让我们创建自己的路由,以接收来自机器人远程控制UI的POST请求。 Router()对象具有GET,PUT,POST,DELETE方法来创建自己的路由,这些路由将PATH作为参数并公开请求,响应和下一个变量,如以下代码所示:

 进口基金会 
进口Kitura
导入LoggerAPI
导入氦气记录仪
进口申请
导入SwiftyJSON
导入生成
 私有let路径=“ / api / IoT / RobotContent” 
 做{ 
  HeliumLogger.use(LoggerMessageType.info) 
尝试initialize()
//创建路由以将RobotContent发送到MQTT平台
router.post(path){请求,响应,下一个
Log.debug(“ POST \(path)”)
守卫let contentType = request.headers [“ Content-Type”],
contentType.hasPrefix(“ application / json”)其他{
response.status(.unsupportedMediaType)
response.send(json:JSON([“错误”:“请求内容类型必须是application / json”]))
返回next()
}
警卫队.json(let json)? = request.body else {
response.status(.badRequest)
response.send(json:JSON([“错误”:“请求正文无法解析为JSON”]))
返回next()
}
做{
让模型=试试RobotContent(json:json)
//调用远程服务
尝试RemoteRobotService()。sendRobotContent(model:model)
//
response.send(json:model.toJSON())
下一个()

}将let错误捕获为ModelError {
response.status(.unprocessableEntity)
response.send(json:JSON([“ error”:error.localizedDescription]))
下一个()
} {
Log.error(“ handleCreate期间发生InternalServerError:\(错误)”)
response.status(.internalServerError)
下一个()
}
}
尝试运行()
  }捕获让错误{ 
Log.error(error.localizedDescription)
}

从远程UI收到请求后,您可以将其保存到数据库中,或者在我们的情况下,数据作为MQTT消息发布到IoT平台。 用于将MQTT消息发布到IBM IoT平台的模块是IBM开发的Aphid Client。 下列类将JSON作为MQTT消息发送到IoT平台。

 进口基金会 
进口蚜虫
导入生成
 公共类RemoteRobotService { 
公共功能sendRobotContent(model:RobotContent)抛出{
让客户端= MQTTConnection()
尝试client.connect()
client.publish(主题:Credentials.IOT_TOPIC,withMessage:model.toJSON()。rawString()!)

而config.status == ConnectionStatus.connected {
睡眠(10)
}
}
}

要建立与IoT平台的MQTT连接,我们需要在设备注册后使用IBM IoT平台的凭证。以下Swift类有助于创建MQTT连接。

 进口基金会 
进口蚜虫
 类MQTTConnection:蚜虫,MQTTDelegate { 

在里面() {
super.init(clientId:Credentials.IOT_CLIENT,cleanSess:true,用户名:Credentials.API_KEY,密码:Credentials.API_TOKEN,主机:Credentials.IOT_HOST,端口:Int32(Credentials.IOT_PORT))
super.delegate =自我
}

func didConnect(){
打印(“已连接!”)
}
func didLoseConnection(错误:错误?){
打印(“连接丢失”,错误!)
}

func didCompleteDelivery(令牌:字符串){
打印(令牌)
}

公共功能didReceiveMessage(topic:String,message:String){
打印(主题,消息)
}
}

确保在Credentials.swift对象中替换您的IoT平台凭据

 公共结构凭证{ 
//来自bluemix的IOT设备凭证
公共静态let API_KEY =“ ”
公共静态let API_TOKEN =“ ”
公共静态让IOT_CLIENT =“ a::RemoteRobot”
公共静态让IOT_HOST =“ .messaging.internetofthings.ibmcloud.com”
公共静态让IOT_PORT = 1883
公共静态让IOT_TOPIC =“ iot-2 / type / / id / / evt / / fmt / json”

}

准备好所有代码库之后,您可以通过编辑方案选择项目为可执行文件并运行来从Xcode启动服务器。 您将看到该项目在端口8080上运行,并且可以访问上述URL。

运行机器人遥控器

从此处的GitHub存储库中克隆远程UI代码:并运行该代码。 运行代码后,您将看到以下输出UI。 远程UI基本上通过访问REST-ful API http:// locahost:8080 / api / IoT / RobotContent将文本和blinkColor发送到swift服务器

设置IBM BlueMix

  • 使用控制台在IBM BlueMix中设置IoT平台,以获取要在您的应用程序中使用的凭证
  • 设置Watson Text-To-Speech并保存凭据以在您的应用程序中使用

创建Raspberry-PI驱动的机器人

我们将创建一个机器人,该机器人可以说话并闪烁连接到它的LED。 该机器人由Raspberry-PI驱动。 为此,我们需要

  • 可以使用音频插孔连接的任何扬声器(https://www.adafruit.com/product/1669)
  • NeoPixel扩散8mm通孔LED — 5件装(https://www.adafruit.com/product/1734)

有关安装和配置的信息,请参见以下针对tjBOt进行配置的说明https://github.com/ibmtjbot/tjbot

下一步是编写[highlight] nodejs [/ highlight]代码,该代码订阅Swift服务器已发布到的IoT平台中的主题。 以下[highlight] nodejs [/ highlight]代码使用npm MQTT客户端(Watson开发人员SDK)连接到IoT平台,以连接到Watson Text-to-Speech服务,以将文本转换为声波。

  //实例化我们的TJBot! 
var tj = new TJBot(hardware,tjConfig,Credentials);
//关闭LED
tj.shine('off');
  mqtt_client.on('connect',function(){ 
mqtt_client.subscribe(渠道,功能(错误,已授予){
如果(错误){
console.log(err);
}
console.log(已授予);
});
});
  mqtt_client.on('message',function(topic,message){ 
var contentForRobot = JSON.parse(消息)
var text = contentForRobot.text
var ledColor = contentForRobot.blinkColor
  console.log(“ Text:” + text); 
console.log(“ blinkColor:” + ledColor);

//调用watson api并播放声音。
如果(文本){
playTextToTheSpeaker(text);
}
  //发送信号使颜色发光 
if(ledColor){
tj.shine(ledColor.toLowerCase())
}
});
  const textToSpeech =新的TextToSpeechV1( 
{
//如果此处未指定,SDK将退回到TEXT_TO_SPEECH_USERNAME和TEXT_TO_SPEECH_PASSWORD
//环境属性,然后是Bluemix的VCAP_SERVICES环境属性
用户名:凭据。TEXT_TO_SPEECH_USERNAME,
密码:凭据。TEXT_TO_SPEECH_PASSWORD
}
);
  / ** 
这会调用带有文字的watson服务并播放给扬声器
** /
函数playTextToTheSpeaker(text){
const reader =新的wav.Reader();
  //“格式”事件在WAVE标头的末尾发出 
reader.on('format',function(format){
//从阅读器的输出中剥离WAVE标头
reader.pipe(新的Speaker(格式));
});
  textToSpeech.synthesize({text:text,accept:'audio / wav'})。pipe(reader); 
}

要正确使用Watson开发人员云sdk将Watson Text-To-Speech的输出传递到扬声器,需要以下依赖项。

以及遵循Bluemix平台的凭证。 替换在Credentials.js文件中找到的详细信息。

  module.exports = { 
IOT_API_KEY:“ ”,
IOT_AUTH_TOKEN:'',
IOT_ORG:'',
IOT_DEVICE_TYPE:“ ”,
IOT_DEVICE_ID:“ ”,
TEXT_TO_SPEECH_USERNAME:“ ”,
TEXT_TO_SPEECH_PASSWORD:''
}

安装依赖项并使用以下命令启动nodejs应用程序

  npm安装 
节点index.js

该应用程序开始在IoT平台中侦听该主题,并且当该主题接收到MQTT消息时,此nodejs应用程序将接收JSON,该JSON调用Watson开发人员云“文本到语音”,并将响应路由到发言人。 您可以从机器人听到您在UI中键入的内容。 Node.js应用程序还使用tjbot库以选定颜色发光LED。 所选颜色是主题的响应。 以下是nodeJs应用程序接收到的主题的输出。

  { 
“ text”:“您好,来自远程客户端”,
“ blinkColor”:“绿色”
}

吉布

请在此处找到所有3个组件的GitHub存储库。 您只需要添加凭据并运行每个组件即可查看输出。

优酷

参考链接

  • Kitura.io
  • GitHub上的Kitura
  • IBM Watson SDK
  • 蚜虫MQTT
  • Swift在IBM Slack社区