项目 Hendrix:一个呼叫中心用户体验管理解决方案

  • François Le Droff

2011 年 9 月 19 日

话题:语言 & 开发

当 Adobe 的技术体验和创新小组(Technology Experience and Innovation Group) 在我们呼叫中心的同事旁边坐下并且观察存在于提供最佳用户体验之路的障碍时,我们已经明白下面两件事:

  • 首先,它主要是一个技术问题并且能够通过 Adobe 倡导的设计思路和创新方法解决它。
  • 其次,通过充分利用 Flex、Adobe LiveCycle Data Services 和 Adobe LiveCycle Collaboration Service 等 Adobe 技术,我们能够为所有 Adobe 支持和电话销售代理提供更为简单直观和更为有效的体验。

作为开发团队,我们应用 Adobe 集团客户已经使用过的相同成功策略和技术来改善 Adobe 内部运营是合理的。 这就是名称为 Hendrix 项目代码的产生原因。 截止现在,Hendrix 已经利用一个单一、简洁和直观的界面支持 Adobe 代理超过一年的时间。

要求

为了满足本文条件,你需要下列软件和文件。

Flex

LiveCycle 数据服务

预备知识

一些分布式应用程序架构的背景知识将会帮助你充分理解本文的内容。

图 1. Hendrix UI

图 1. Hendrix UI

相应的投资回报率(return on investment (ROI) )非常可观,并且受益面也非常广泛。 Hendrix 已经能够

  • 降低平均呼叫处理时间 15%
  • 降低呼叫代理转网率 30%
  • 支持实时访问富账号信息以便更有效地进行故障排查 g
  • 提升客户满意度 10%
  • 将代理培训时间从一个星期缩短到一天
  • 关于该项目应对的商务挑战的更多细节信息,参见 客户展示故事*。 本文的讨论比上述故事要深入一些,它提供对后台发生事件的概述以及对 Hendrix 架构的简介。

架构概述

在开发项目的软件架构和技术基础方面的主要目的是使得开发团队能够更有效地和集中全力地实现商业和用户体验要求。 我们的目的包含下列内容:

  • 通过概念提取和分离所关切的事项降低其复杂性
  • 避免重起炉灶;充分利用现有传统系统以及第三方框架
  • 通过使用代码生成工具避免编写任何样板文件代码(boiler plate code)
  • 通过直接利用设计人员的图形组件和使用程序化的植皮技术,能够有效地弥合开发人员和设计人员之间的间隙
  • 开发基础设施和工作流程必须支持不断更新的版本和连续的质量控制 最后,但不是最不重要的,通过对高可靠性、强可扩展性和高性能的要求,将驱动对关键架构的选择。

基础设施场景

图 2 给出的 Hendrix 集成场景的简化视图。.

图 2. Hendrix 基础设施场景

图 2. Hendrix 基础设施场景

Hendrix 支持多用户界面;它支持多信道和多屏幕功能。 该项目的第一阶段将客户服务代理和电话销售代理作为目标用户。 他们享受了 Hendrix web 浏览器体验,这些体验能够满足他们的需要以及 Adobe IT 对平顺部署、安装和升级的要求。

Hendrix 项目的第二阶段能够满足更高级的使用案例的要求并且将技术支持代理作为目标用户。 对这一版本来说,Adobe AIR 将能够用于提供桌面客户端应用程序,该应用程序支持与相应操作系统的更紧密集成。

接下来的版本是 Hendrix Mobile。 它也将利用 AIR 进行创建,并且它的用户是我们的售前和销售团队。 Hendrix 能够将他们关注的客户的最新信息(重要案例、客户环境、客户满意度等)直接推送到他们的移动设备上。

每个 Hendrix 客户端应用程序均建立于相同可扩展 JEE 中间件之上。 它们都使用 LiveCycle Data Services 服务来完成下列任务:

  • 访问和重用在 Adobe 的传统 SAP 系统中实现的现有业务规则和创建读取更新删除(Create Read Update Delete (CRUD) )操作
  • 从各种现有系统中提取数据(包括产品目录、市场营销材料、翻译引擎和序号服务器等)
  • 与呼叫中心的电话和现有的 Alcatel Lucent Genesys 计算机电话集成(computer telephony integration (CTI) )系统的互动

此外,在 Flash Player 中运行的 Flex 客户端能够直接调用 LiveCycle Collaboration Service 功能,以便支持技术支持团队在他们的支持会话过程中使用聊天、屏幕共享和白板等功能。

软件架构概述

在你较深入地了解开发 Hendrix 项目的原因和它的一些基本基础设施之后,你可能很想知道它的软件架构感。

正如图 2 所示,Hendrix 集成场景是由各种设备构成的。 为了完成这一集成工作,架构团队必须为关切的事项建立良好的分离模型和提供良好的模块化设计。 为了这一目的,必须将模块、库、包和类的 public API 的数量保持在最低水平。 这将会降低系统复杂性并且减少开发和维护费用。 整个系统看起来很复杂(参见图 3),但如果逐一地来看,这些子系统的实现方式并不那么复杂。

图 3. Hendrix 软件架构

图 3. Hendrix 软件架构

在 Flex 客户端和 Java 服务器上,开发团队赞成使用相同的架构式样,因为它有利于实现松散耦合和独立的开发、部署和测试。

  • 服务器和客户端应用程序可以划分为小型、松散耦合的单元 / 模块 / 项目,它们能够独立地进行开发、测试和发布。
  • 开发团队使用下列可扩展的控制反转(inversion of control (IoC))microcontainer:
  • 为了避免重起炉灶,开发团队充分利用成熟的第三方工具,其中包括登录框架(sl4j in Java、Thunderbolt for Flex)和其它各种工具(Apache libraries、Flexlib、Cairngorm 3)。

客户端侧架构

当 Adobe 工程团队创建一个企业 RIA for Adobe 时,Flash Platform 是一个自然选择,而且不太可能受到挑战。 然而,值得一提的是 Flash Platform 能够满足主要的技术要求,它允许 Hendrix 支持:

  • 各种操作系统和浏览器(甚至 Internet Explorer 6)
  • 丰富客户端(这使得 Hendrix 响应更快,因为我们能够通过将数据和状态移除到客户端降低服务器的负荷)
  • 多媒体内容

此外,我们的方法是设计驱动的。 信息架构师和用户体验设计团队将引导相关需求。 他们的目的是简化业务工程、隐匿系统复杂性、降低培训需求及减少平均处理时间。 他们制作出一个清晰和精心设计的用户界面,它首先是通过故事(stories)、 Adobe Fireworks 线框 (参见图 4) 和行为文档表述的,随后是通过 Adobe Illustrator 图像(参见图 5)进行表述的。

图 4. Hendrix 范例线框

图 4. Hendrix 范例线框

图 5. Hendrix 图像

图 5. Hendrix 图像

Adobe Flex Framework 支持开发团队高效快速地实现期望的完美像素(pixel-perfect )的结果

  • Flex 组件能够用作可扩展构件块,我们能够将它们组合在一起以便建立丰富的图像组件(向导、时间线、等等)、动作设计和用户手势图像效果。
  • 高可定制 Flex 植皮能力可以由 Photoshop 和 Illustrator 组件提供驱动,它能够弥合设计人员和开发人员之间的间隙。

记住在 Flex4 中最大的变化是关于植皮的两个新概念。 首先,Flex 4 引入了一组新的 MXML 标签,它们用于定义图形(graphics)、文本原语(text primitives)、填充(fills)、笔画(strokes)、梯度(gradients)、位图(bitmaps)、过滤器(filters)、掩码(masks)、阿尔法(alphas)、转换(transforms)和混合模式(blend modes)。 其次,它引入了 FXG,这是一种适用于 Adobe Flash Platform 的基于 XML 的矢量图形交换格式。 这些能力可以简化 Hendrix 的开发人员 - 设计人员的工作流程。

Hendrix 设计人员将用户界面创建为矢量图像(通过 Illustrator),而 Flex 开发人员以后可以在他们的代码中重新使用它(参见图 6)。 Illustrator 组件能够以 FXG 文档导出,通过 Flex SDK 编译器进行编译并且以高优化静态组件的形式告终。

图 6. Hendrix 设计人员 - 开发人员工作流程

图 6. Hendrix 设计人员 - 开发人员工作流程

Flash Player 或 AIR?

AIR 运行环境允许 RIAs 在浏览器之外运行。 AIR 不仅允许部署 HTML、JavaScript 和 Flex 应用程序,而且支持通过 SQLite 数据库或与其一起发售的加密本地存储设备使用嵌入数据存储设备。

通过使用 Flex SDK,你可以利用你的 Flex 代码基创建目标用户为 Flash Player 或 AIR 的版本。 基于 Flash Player web 应用程序运行 AIR 桌面应用程序的最大优点是与底层操作系统(Windows、Linux 或 Mac OS)进行互动的能力,这样它将会把应用程序从 Flash Player 和浏览器沙箱中释放出来。 AIR 应用程序能够创建通知,改变 Dock 或系统托盘图标,访问文件系统、访问麦克风和网络摄像头以及与其它过程互动。

我们的用户体验团队在 Hendrix 的第一版本中没有要求提供 AIR 功能。 相反,该第一版本被设计和发布为 Flash Player 的一个 web 应用程序,它使得到所有最终用户的部署和透明更新变得简单,其中包括客户服务和电话销售代理。

移动 AIR

在 Adobe 销售和售前团队表达了他们需要一款 Mobile CRM 应用程序之后, 实现 Hendrix Mobile on AIR(参见图 7) 变成相关路标的一个组成部分。

我们的用户体验团队将现有的 Hendrix 应用程序转换为一款移动应用程序,它能够充分利用 AIR 支持的多点触摸功能、加速计和手指手势,如果需要,还包括麦克风、摄像机、视频和地理定位服务等。

图 7. Hendrix Mobile

图 7. Hendrix Mobile

现在 AIR 技术能够用于在智能手机(包括 iPhone 3GS、iPhone 4、iPod Touch 和 Android 手机)和平板电脑(包括 iPad、Xoom 和 BlackBerry Playbook)上部署应用程序

AIR 运行环境已经在 Acer、HTC、Motorola、RIM 和 Samsung 开发的许多设备上进行了预安装。 此外,它也能够通过 Android Market 或 Amazon Appstore for Android 等应用程序商店进行安装(AIR 开发人员也可以使用这些商店发布应用程序)。

AIR 2.6 能够为 Android 和 iOS 平台提供相同的功能和性能(使用 OpenGL ES2 处理快速图形)。 开发人员甚至能够充分利用 iOS 4 中的新功能,例如多任务(multitasking)、用于更高屏幕分辨率的视网膜显示技术(retina display)和前后摄像头支持功能等。

然而,iOS 设备不支持 AIR 运行环境 ,因此开发人员需要使用 AIR 开发人员工具(AIR Developer Tool (ADT))将 AIR 应用程序打包为本机应用程序。 顺便说一句,这是一种你可以选择的针对任何支持的平台的方法。

Flex 框架

Flex 架构师喜欢争论特定框架的优点和缺点;以前 Java 架构师也是如此。 凡事不可一蹴而就。 Flex 是它自己的框架以及 Flex 4 Spark 模型和其相应的植皮能力可以被看作为一个 MVC 框架是毫无价值的。

然而,当创建高级企业面向对象系统(它要求能够以自动方式构造、检索和隔离对象)时,IoC 框架是值得考虑的选择。

Parsley

对于 Hendrix,Flex IoC 框架的选择是 Parsley。 开发团队认为 Parsley 的设计宗旨是成为框架中的框架;Hendrix 团队提供的一些 Cairngorm 3 库实际上是在 Parsley 之上创建的。

Cairngorm 3 Module 库是其中一个范例。 Cairngorm 3 Module 提供一组基础设施代码,它能够帮助模块加载和卸载,以及通过增加 Parsley Messaging API 以便确保下发到给定模块的消息总是能够到达它们的目的地来减少模块之间的通信。

Cairngorm 3

与早期的 Cairngorm 2 框架不同,Cairngorm 3 的许多部分适用于各种框架。 如果你在你的项目中希望使用 Parsley、Spring ActionScript、Robotlegs、PureMVC、Swiz、Mate 或另一个框架,Cairngorm 3 将是很好的补充框架。

Cairngorm 3 由下列内容构成:

  • 描述我们的域驱动设计(Domain-Driven Design)方法和倡导关于持续集成的工具配备及质量的指南
  • 一组独立的工具库和范例项目

因为 Hendrix 团队在我们的项目中广泛地使用 Cairngorm 3,所以我们也回馈 Cairngorm 3。如果你希望深入研究我们的架构最佳方法并且需要了解我们的工具包,那么我们邀请你访问Cairngorm 3 wiki*并且试用我们的 Cairngorm 3 库和范例项目。

系统之间通信

本节描述 Hendrix 系统之间的通信过程,它们能够支持 Flex 客户端应用程序和后端服务之间的快速可靠的数据交换。

对象序列化(Object serialization)

如果你在你的应用程序中均能够控制服务器侧和客户端侧,则几乎没有理由对文本进行序列化和去序列化(特别是冗长的 XML 文本)。 对象序列化(object serialization)的速度总是较快。 在 Hendrix 项目中,速度和可扩展性是主要的要求,因此我们决定不使用 web 服务(以及不可靠的 SOAP 方法)而是选择使用对象序列化方法。 特别地,我们使用下列技术:

  • Genesys 代理交互(Agent Interaction)SDK 和其 Java 代理交互层(Agent Interaction Layer (AIL))库。 AIL API 支持 Hendrix Java 中间件利用现有的 Genesys Telephony/AIL 服务器通过 sockets 进行交互,以便管理代理登录活动、监测和改变代理状态以及发起向外的交互,而不论媒体的类型。
  • SAP Java Connector (SAP JCo) 和其底层高性能基于 JNI 的 RFC 中间件。 这将支持 Java 中间件和 SAP 后端之间的 TCP/IP 通信。
  • 动作消息格式(Action Message Format (AMF))。AMF 是 Flash Player 支持的二进制对象格式并且是由 Adobe LiveCycle Data Services Java 中间件解决方案实现的。

AMF 可以用于对 ActionScript 对象图表进行序列化。 在序列化之后,AMF 编码对象图表可以用于在会话过程中保存和检索应用程序的全局状态,或允许两个端点通过强类型数据(strongly typed data)的交换进行通信。

图 8. Census、James Ward 的序列化基准应用程序的屏幕截图

图 8. Census、James Ward 的序列化基准应用程序的屏幕截图

James Ward 已经创建一个Census RIA Benchmark*应用程序,它使用大量的方法,包括 SOAP、JSON、XML 和 AMF 对数据加载进行比较。 正如你在图 8 中看到的那样,AMF 在所有方面均极为有效(即使在没有压缩的情形下)。 并且,它不仅仅在加载方面速度较快—它也能够加速客户端侧的排序和过滤并且在客户端侧要求较少内存。

HTTP 或 RTMP

实时消息协议(Real-Time Messaging Protocol (RTMP))是一种设计宗旨为在 Adobe Flash Platform 技术之间进行高效传输数据的协议。 RTMP 是一个用于创建产品和技术的可用开放规范,它支持以开放的 SWF、FLV、F4V 格式 以及 AMF 格式提供视频、语音和数据,这些格式均与 Adobe Flash Player 兼容。

利用 Adobe LiveCycle Data Services 能够提供两种形式的 RTMP:

  • 一种能够运行于 TCP 并且使用一种非标准端口:端口 1935。 因为 Hendrix 团队不能在一些外购的呼叫中心的防火墙上打开这一端口,故我们不考虑这一纯 RTMP 协议选择。
  • 第二种能够在 HTTP(S) 请求中封装 RTMP 消息。 它的名称是 RTMPT(S),这一形式支持该协议遍历防火墙并且使用标准端口。

在考虑 RTMPT 之后,Hendrix 团队决定在短期内使其保持简单状态,并且通过使用 HTTP 轮询(polling)和捎带确认(piggybacking)技巧仿真推送操作。 Hendrix 网络拓扑在使用外购的呼叫中心防火墙和代理、Adobe 内部网防火墙以及负荷均衡器之后变得更为复杂,因此起初简捷是非常重要的。 如果相应的业务具有下列需求,该团队将对从 HTTP 转移到 RTMPT 协议进行评估:

  • 实时数据推送能力
  • 当一个客户端关闭时给出完整及时的通知(如果你需要知道 reps 是否在线或离线,这是呼叫中心应用程序的一个有趣的功能。 较传统的基于 HTTP 的服务通常不能接收离去的客户端的通知,直到服务器上相应的 HTTP 会议超时。)
  • 降低时延并且获得更高的吞吐量(参见图 9 和图 10)

图 9. LiveCycle Data Services 能够支持多达 40,000 个平均时延为 400ms 的并发用户(来源:LiveCycle Data Services 3 Performance Brief)

图 9. LiveCycle Data Services 能够支持多达 40,000 个平均时延为 400ms 的并发用户(来源:LiveCycle Data Services 3 Performance Brief)

图 10. LiveCycle Data Services 能够在 15ms 之内推送多达 400, 000 条消息(来源:LiveCycle Data Services 3 Performance Brief)

图 10. LiveCycle Data Services 能够在 15ms 之内推送多达 400, 000 条消息(来源:LiveCycle Data Services 3 Performance Brief)

中级架构

Hendrix 中间件是一款利用 LiveCycle Data Services 创建的、并且运行于 JEE 应用程序服务器上的 Java web 应用程序。 LiveCycle Data Services 消息基础设施能够提供下列支持功能:

  • 通过其 Flex remoting 和代理服务提供的面向服务的 API
  • 通过其 Flex 信息服务提供的发布 - 预订消息 API
  • 通过其数据管理和代理服务提供的面向资源的 API

信道配置

LiveCycle Data Services 是与协议无关的。 支持协议和序列化机制的每种组合均能够作为客户端和服务器之间的消息信道,而不影响客户端或服务器交换或处理消息的方式 hout affecting how messages are exchanged or processed by the client or server.

消息信道来自下列三个主要系列:

  • RTMP 信道创建一个到服务器的单一双工 socket RTMP 连接 。 如果该直接 RTMP TCP 连接尝试失败,则 Flash Player 将尝试 RTMPT (通过一个 HTTP 代理的隧道) 或最终倒回到自适应 HTTP 请求,它们在客户端和服务器之间利用隧道 来回传送 RTMP 数据。
  • 传统的 AMF/HTTP 信道,它们充分利用 JEE servlet API 并且使用模块化的 IO(blocking IO)。 它们能够配置为长轮询(long polling)、流(streaming)或简单轮询(simple polling),同时启用捎带确认(piggybacking)功能。 (第一版的 Hendrix 可以使用长轮询(long polling)和捎带确认(piggybacking)功能。)
  • 使用 LiveCycle Data Services NIO 服务器的 AMF/HTTP 信道,它们在行为上与基于 servlet 的 AMF 信道 / 端点是相同的,但使用一个 NIO 服务器和最小的 HTTP 堆栈以支持按比例增加到数千个连接。 (当该服务向更多呼叫中心开放时,Hendrix 将转向 NIO。)

如果你希望了解关于信道配置的更多细节信息,请阅读 Damon Cooper 的 博客帖子,它的标题是 BlazeDS 和 LCDS:信道,随处可见的信道(BlazeDS and LCDS: Channels, Channels Everywhere)*

通过 LiveCycle Data Services 暴露 SAP 服务

为了充分利用现有的传统 SAP CRM 系统,一个 ABAP 开发团队实现了一组 Hendrix 专用的外观服务(fa??ade service),它将 CRM SAP 传统系统中存在的现有业务规则和架构聚集在一起。 这些 ABAP 函数是以 Remote Function Calls (RFCs) 的形式暴露的,它们是用于基于 TCP/IP 或 CPI-C 的 SAP 客户端和服务器之间通信的标准 SAP 接口。Java 中间件应用程序服务器可以通过 SAP Java Connector (SAP JCo) 使用它们。

通过 SAP Jco,这些 RFC 可以包含于 Java 服务中,并且 ABAP 架构可以包含于 Java 实体中。 然后,因此产生的 Java API 能够适用于外观 API(fa??ade API),它可以通过 LiveCycle Data Services 进行暴露并且可以由相应的 Flex 客户端使用。

正如对象相关的映射技术一样,要求的管道工程(plumbing)将导致大量的样板代码(boiler plate code)。 Hendrix 团队已经开发了其自己的解决方案以便内窥 RFC 并且生成大部分的 RFC-to-Java-to-Flex 映射代码。 LiveCycle Data Services 工程团队已经对其进行查看并且获得了一些进展。 他们将在今年晚些时候为 LiveCycle Data Services 发布一个 SAP Connector。 这将通过利用 SAP 进行模型驱动开发的工具来增加 Flash Builder 的功能。 除了连接到一个或更多的 SAP 系统,该连接器还支持开发人员内窥和寻找 RFC 模块和函数,将 SAP RFC 函数映射到 Flex 远程函数,在 Flex 中定制函数(修改函数名称、参数、输入和输出)以及生成 ActionScript fa??ades 以便与 SAP 进行通信。 关于这方面的更多信息,参见 Damon Cooper 的帖子数据服务的 SAP 连接器介绍(Introduction to the SAP Connector in Data Services)*

通过 LiveCycle Data Services 暴露 Genesys CTI

LiveCycle Data Services 和 Java 使得计算机技术集成(computer telephony integration (CTI) )变得非常简单。 最终用户能够在 Flash Player UI 中通过 LiveCycle Data Services Flex 远程服务触发 Genesys Java AIL 库的交互操作。 通过这些 Flex 的远程呼叫(remoting call),相应的代理能够:

  • 设置他或她的状态(Ready、Not Ready、等等)
  • 发起一个呼出呼叫(outbound call )
  • 接受一个呼入呼叫(incoming call)
  • 切换主叫信息细节
  • 保持一个呼叫
  • 利用已经识别的客户信息进行 cold/intelligent/warm 转接
  • 发起一个协商呼叫(consult call)
  • 释放一个呼叫

Genesys 库的核心也能够通过一种事件机制,通过它 Agent Interaction (Java API) 应用程序能够将服务器的状态通知用户,例如呼入呼叫(incoming call)、挂起(hang up)、断开(disconnection)、等等。

LiveCycle Data Services 能够提供实时的发布 - 预订消息 API,而 Hendrix 中间件可以使用它发布 CTI 事件给已经预定的 Flex 客户端。

由于 LiveCycle Data Services 的消息可靠性,CTI 解决方案是可靠的并且支持企业用户,LiveCycle Data Services 确保在整个网络中能够正确交换消息,而无论是否出现故障,只要客户端和服务器主机保持运行即可。 消息将按照顺序一次传送,并且只传送一次。

如果连接失败然后重新恢复,任何未传送的消息将自动和正确地重新传送,而不会出现由远端进行重复处理的风险。

为了激活这一功能,只需对 LiveCycle Data Services XML 配置文件进行一些少量必要的更改即可,具体来说:

充分利用 JEE 标准

最后但不是最不重要,Hendrix 中层(middle tier)还能够充分利用许多 JEE 标准 (在 JBoss 应用程序服务器中实现)。 除了简单的登录支持功能(这是生产监测和错误诊断的关键功能),Hendrix 还能够充分利用更多的高级 JEE 功能,其中包括

  • 用于以编程的方式控制 SAP CRUD 操作的事务范围的 Java 事务管理(Java transaction management)
  • 用于支持 Hendrix 中间件通过名称发现和搜索数据和对象的 Java 命名和目录接口(Java Naming and Directory Interface (JNDI)) 这将帮助团队使得 WAR 文件之外的配置(包括所有的 SAP、CTI 和其它后端链接参数)具体化。 因此,我们能够在开发、QA、数据移动(staging)和生产环境中创建和部署相同的 WAR 文件。
  • 用于管理、过滤和对 CTI 事件进行排队的 Java 消息服务(Java Message Service (JMS))
  • 用于管理和监测应用程序、系统对象和应用程序托管 Bean 的 Java 管理扩展(Java Management Extensions (JMX)) 这一功能对远程清除高速缓存、重新加载 JNDI 树、与其它应用程序服务互动以及在运行环境中更好地控制应用程序极为有用。
  • 我们还使用 JbossCache 避免不必要的后端往返来获取共享的元数据、产品目录和类似数据,以及支持分组(clustering)和会话(session)复制 (外加 Jgroups)。

下一步阅读方向

尽管本文提供了 Hendrix 架构的概述,但我们讨论的许多方面和挑战只涉及到表层。 下面是一些较为深入地讨论这些主题的资源。 在未来的文章中,我们将详细地讨论和演示 Hendrix 软件工厂技巧。 同时,如果你认为我们应该在这一项目的某一特定话题方面提供更详细的信息(例如,SAP 集成、CTI、安全、模块化或多屏支持功能),请告知我们(通过评注、 Twitter 或 email 均可)。

Creative Commons License

本文基于Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License*协议发布。

查看原文:项目 Hendrix:一个呼叫中心用户体验管理解决方案

语言 & 开发