使用云巴JS-SDK为Mac应用(基于Electron)实现消息通知

DaoCloud+是一个使用 Electron 迷你的托盘控制台程序,而且在写这个程序的时候最重要的原因就是希望能及时获取到我的镜像构建和应用运行(接口原因,目前无法支持)状态,但如果应用不能主动推送通知给我,那么这个应用能提供给我的价值就是微乎其微了。

DaoCloud+主界面
DaoCloud+通知中心.png

那么现在问题来了,在没有官方的推送服务支持时,如果能够实现应用主动推送呢?让官方去支持这个几乎是不可能,所以惯性思维让我第一想到这个解决方案定时请求API,对比上次状态作出通知。然后这种做法实在是在Low而且低效了,而且如果构建时间短于你的轮询时间,就会无法捕获到状态的变化了。

不过有个好消息是,目前很多平台都支持了Webhook,开发者通过自定义回调函数的方式来获取一些事件的消息,DaoCloud是支持镜像构建和持续集成的事件通知的,所以通过这个我们起码能实时获取到状态的变化而不需要去轮询API接口了,只需要将消息转发给客户端就可以了。

最后一个问题是通过什么方式来接收服务端的消息了,我没有去看过任何关于Mac平台上如何关于推送的资料(之前一个为了实现iOS应用的推送,各种什么证书啊什么的折腾死了,Android就好太多了),毕竟我们用的是Electron,所以只需要使用提供JavaScript SDK的推送服务即可,之前做客户一般都是使用了 极光推送小米推送百度推送* 等等,但这些一律都只是支持Android和iOS,而且目前只发现国内只有云巴(不是广告,不是软文,后面有强力吐槽)提供了JavaScript,毕竟这此公司的定位不一样。

云巴的JS-SDK是基于socket.io实现的,当然也是可以支持Electron或者NW.js这种框架啦,而且在使用上和Web的没有任何的不同。

现在开始

首先基于 electron-boilerplate 脚手架搭建项目的基本目录结构,以下是daocloud-plus已经按需整理好的目录结构

.
├── CHANGELOGS.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app
│   ├── app.html
│   ├── app.js
│   ├── background.js
│   ├── components
│   ├── env.js
│   ├── helpers
│   ├── images
│   ├── node_modules
│   ├── package.json
│   ├── stylesheets
│   └── vendor
├── build
├── config
├── gulpfile.js
├── node_modules
├── package.json
├── releases
├── resources
└── tasks

客户端

客户端这边需要生成一个别名(为了保证不重复这里使用了UUID)并且订阅即可。

DaoCloud那边只需要添加些Webhook即可
示例:http://daocloud-plus.blankapp.org/b131a88748f84b3f956839d3e9879baf

编写相关消息接收代码

/app/app.html

...
  <!-- 引入云巴 JS SDK -->
  <script src="./vendor/yunba/yunba-js-sdk.js"></script>
  <script src="./vendor/yunba/socket.io-1.3.5.js"></script>
...

/app/app.js

...

// 从 localStorage 获取别名,如果不存在则创建
var yunba_alias = localStorage.getItem('yunba_alias');
if (!yunba_alias) {
  yunba_alias = uuid.v4();
  yunba_alias = replaceall("-", "", yunba_alias);
  localStorage.setItem('yunba_alias', yunba_alias);
}
// 初始化云巴SDK
yunba.init(function (success) {
  if (success) {
    // 连接服务器
    yunba.connect(function (success, msg) {
      if (success) {
        // 设置别名,成功后服务端的消息将会在set_message_cb方法接收 
        yunba.set_alias({'alias': yunba_alias}, function (data) {
          if (data.success) {
            console.log('别名:' + yunba_alias + " 设置成功");
          } else {
            console.log(data.msg);
          }
        });
      } else {
        console.error(msg);
      }
    });
  } else {
    console.error(msg);
  }
});

// 云巴消息监听
yunba.set_message_cb(function (data) {
    console.log(data);
    // 创建一个通知
    var notification = new Notification('DaoCloud Plus', {
        body: data.msg
    });

});

...

服务端

服务端要做的事情就更加简单了,接收Webhook的发送过来的数据,通过云巴的REST接口发送给客户端即可,这里为了快速使用了 Laravel 框架,为什么这么简单的一个事情还要使用一个框架,那是因为我对PHP不熟,不想折腾~~

使用 laravel 创建 daocloud-plus-notifier 项目

$ larave new daocloud-plus-notifier

编写相关消息推送代码

/app/Http/routes.php

...

// 配置路由 
// 示例:http://daocloud-plus.blankapp.org/b131a88748f84b3f956839d3e9879baf
Route::post('/{alias}', 'NotifierController@webhook');

...

/app/Http/Controllers/NotifierController.php

<?php

namespace App\Http\Controllers;

use GuzzleHttp\Client;
use Validator;
use Lang;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class NotifierController extends Controller
{
    protected function webhook(Request $request, $alias)
    {
        $name = $request->input('name');
        $build = $request->input('build');

        if (!$build) {
            return $this->failure();
        }
        // 根据 build_type 和 status 组装消息
        $msg = Lang::get('daocloud.' . $build['build_type'] . '_' . strtolower($build['status']), ['name' => $name]);

        // 向别名发送消息,通过 env 方法获取到云巴的 AppKey 和 SecretKey
        $client = new Client();
        $response = $client->request('GET', 'http://rest.yunba.io:8080', [
            'query' => [
                'method' => 'publish_to_alias',
                'appkey' => env('YUNBA_APPKEY', ''),
                'seckey' => env('YUNBA_SECRET_KEY', ''),
                'alias' => $alias,
                'msg' =>  $msg
            ]
        ]);

        if ($response->getStatusCode() == 200) {
            return $this->success();
        }

        return $this->failure();
    }
}

编码完成

到此编码工作已经完成,代码比较简单,但是已经实现了给 Electron 程序添加了消息通知功能了。

头脑风暴

通过Electron+Webhook+云巴就可以快速实现了一个实用的Mac应用,其实通过Webhook可能做的事情还有很多很多,例如做一个基于Webhook的通知中心(哈哈,我竟然嫌现在的通知还不够多啊~)等等

相关文章

项目地址

吐槽一下云巴

不提供包依赖管理工具的支持

我不太清楚目前的公司开发有没有使用依赖管理工具,但是我个人认为直接以文件的方式引入SDK的方式实在是太Low并且低效了

例如Android,我只需要在build.gradle文件添加

compile 'com.squareup.retrofit2:retrofit:2.0.2'

例如iOS,只需要在Podfile添加一行

pod 'AFNetworking', '~> 3.0'

例如NPM,只需要执行一行命令

$ npm install lowdb --save

例如PHP,同样只需要一行命令

$ composer require fzaninotto/faker

等等...
然而,国内能提供包依赖管理工具支持的实在是少得可怜~~~

过于业余的接口命名规范

表示无法理解使用 publish2 这种命名~~

功能点相关概念重叠

在云巴的SDK里,alias 是基于 topic 来实现的,但是文档并没有说明,如果 alias 完全是基于 topic 的,那 alias 存在的意义是什么?

创建新应用时必须填写Android包名

以目前个人的理解,云巴不同于目前市面那些移动应用推送平台,并不局限于移动应用,但是在后台创建应用的时候为什么必须让我填写Android的包名?

运行提供官方提供的Demo过于麻烦

Android 的 Demo 可不可以直接用AndroidStudio来写啊?
有时候运行一个Demo的时候都要花上几个小时~~~

[建议] 为开发者创造使用场景

云巴这个平台个人感觉还是很优秀的(仅限提供的实时数据交换服务),可以做的事情太多了,但是官方给我们展现出的一些使用场景太少了,而且在这个推送市场如此饱和的市场,很难让我下定决心去选择使用在自己的项目上。这个时候官方应该为开发者创造更多的使用场景~~

以上吐槽同样适用于国内其他提供开发者服务的平台

为什么要吐槽

我们使用第三方提供的服务是为了什么?就是为了能够快速实现我需要的功能,然而大部分的服务提供商提供给开发者的包括SDK、文档往往是和快速实现背道而驰的,往往在很多项目中,我们使用到的仅仅是一个很小的功能,但却要进行非常复杂的配置等等。

关于我

如果你对这个项目或者这篇文章感兴趣,欢迎 Follow

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,590评论 0 15
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,079评论 25 707
  • 早上给公司的管理团队发出"如何提升新任主管管理能力的方法",从我阅读的其他的文章中裁剪出我认为非常好的重要部分直接...
    鹏姐姐阅读 146评论 0 0