背景
这篇文档是基于之前那篇WebView版本的。当时在那篇文档中也说过,WebView版本的特点是,简单易用,把Bot的Url嵌入到WebView的Source对象中。但是这个方法的弊端就是,Xamarin的可控性太小,所有的都依赖于网页版的Bot的开发,并且WebView的性能终究不会比得上Xamarin通过自己发送请求。
那么这篇文档介绍的会是另外一种方式,也是比较推荐的,就是使用DirectLine API来直接通过Xamarin与Bot通信。
优点
这个方式的优点是,使用了Xamarin的MVVM的架构来实现,那么我现在的理解是,这个的可控性非常高,包括这个Bot的聊天样式,由Xamarin来控制,因为是Xamarin的Page,包括Bot返回的内容,可以是复杂的Card结构等等。
缺点
需要对Xamarin和Bot的开发都比较精通,要了解Bot的机制,Xamarin的MVVM等等。
技术介绍
首先是Key concepts in Direct Line API 3.0,这个是我们必须要熟悉的,因为这样才可以知道Direct Line究竟是什么和怎么使用。
但是这个文档中我们并不会使用这个里面介绍的调用API的方式,原因是如果看了这个文档,就会发现,Direct Line API还是基于Web API来调用,比如说,当开启一个新的conversation的时候,Direct Line API的指导使用是这样的:
如果这样使用的话,就意味着我们的每一次发送信息啊,等等,都是要使用类似HttpClient
来发起,这样的话是非常麻烦的。所以其实Direct Line给到我们另一种选择,就是有NuGet的类库。
类库介绍
想要使用Direct Line的类库,我们一共有两个NuGet的类库需要添加:
第一个类库非常直接了当,就是封装了所有Direct Line API的调用方法,变成一个DLL,这样避免我们不停开启HttpClient请求。
第二个类库应该是一个微软的客户端使用REST API请求时候的Runtime的依赖类库,我们没有直接的代码调用是从这个类库出来的。
具体实现
Azure
首先是要在Azure Portal建立一个Direct Line的Channel,方式是Azure Portal => Bot Service => Channels => Enable Direct Line Channel.
老样子,我们的Key是从这个Channel点击Edit之后得到的。
准备好Azure的部分之后,我们就可以回到Xamarin中了。
Xamarin
首先我们要开发一个类,命名为BotConnection.cs,这个类中定义了包括连接到Bot,发送信息,接受信息等基本上是一切与Bot交流的实现。
先看代码片段:
1 | public class BotConnection |
先介绍这些Fields。
首先是botId,是用来确定是哪个bot在和我们的Xamarin应用交流的,这个在之后接受信息的方法中会用到,我们只监听当前与我们交流的这个Bot给我们发送回来的信息。
directLineSecret就是从Azure portal得到的那个Secret Key。
DirectLineClient是用来实例化一个Direct Line的,这个Client可以用来新建对话,发送信息,接受信息,等等,一切和Direct Line相关的操作都是由它来发起。
Conversation故名思意是一个Bot和Xamarin应用之间的对话实例,这边我们在字段中就声明一个MainConversation,我assume bot应该可以有不止一个Conversation,来达到更复杂的应用场景,不过现在还没有涉及到。
ChannelAccount是Xamarin这个应用的一个identity,来指明具体是哪个Account在和Bot进行通信。
这边我们还是用到了和之前WebView版本一样的使用token来创建conversation的方式,注意我们还是可以使用最简便的直接使用subscription key的方式来启用。
接下来我们需要开发一个SendMessage的方法,这个方法是end user给Bot发送信息的。我们所有发送的所谓Message,在Bot中其实都是一个Activity
,Activity的Type属性需要赋值一个ActivityType
类的其中某个枚举值,普通的文字信息我们就是用的ActivityType.Message
格式。具体代码如下:
1 | public void SendMessage(string message) |
由于现在是使用纯的.NET类库来实现这个,所以我们要设计一个Model,来表达我们UI显示的时候每一条“信息”具体的一些内容和属性。现在由于实现的是最普通的文字版交流的Bot,所以Message的字段主要就是Text和Sender,但是我们还会增加一些类似于TextAlignment的属性来确定Bot的信息的位置和end user信息的位置是一边一个的。具体代码如下:
1 | public class Message |
注意上述代码中,hard code了sender为ME的情况,这是由于目前只有一个用户进行测试,之后会具体详细研究一下BotId和BotName以及UserId和UserName的用法。
最后不过也是最重要的就是GetMessageAsync
方法。这个方法是用来监听用户给Bot发送的信息的。具体实现如下:
1 | public async Task GetMessageAsync(ObservableCollection<Message> collection) |
说明:
首先是参数使用ObservableCollection
是典型的XAML中的绑定机制,当这个collection中的数据有变化时,UI自动也会发生变化。
最后一句话是让线程等待3秒,在循环中,实现了每3秒监听一次的效果。
最重要的概念是这个叫Watermark
的东西。这个是一个mark,记录了当前客户端见到的最后一条Bot给客户端发送的记录。这样我们每3秒更新一次的时候才只会更新最新的bot给我们需要发送的记录,并且重新设置这个watermark值。
最后一个就是开发UI并且绑定这个ObservableCollection<Message>
数据,这个就非常简单了,只是一个ListView,所以这里就不具体写了。
具体我写的code的下载链接:https://allenxamlistfunctionapp.blob.core.windows.net/allensharing/XamBotDirectLine.zip
评论