微信蓝牙BLE接入调试指引 第三方服务器篇

微信蓝牙BLE接入调试指引

第三方服务器篇

构建第三方服务器

服务器的功能主要是接收微信发过来的绑定、解绑、菜单等事件,以及微信发过来的文本、设备发过来的数据等。

3.1 编译服务程序

QQ提供了服务程序的DEMO,下载地址如下:

Nordic nRF51822接入服务器端源代码

http://iot.weixin.qq.com/wiki/doc/blue/BlueDemoServer.zip

 

下载编译工具:

Download Java 1.7 64

http://www.cr173.com/soft/55503.html

或者

http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

Install and set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_80

 

Download Eclipse 64位 java EE

http://www.eclipse.org/downloads/

 

测试的电脑系统是WIN10 64位,其他系统或情况,自决。

 

导入代码:

打开eclipse,点菜单File-Import,弹出如下界面:

 微信蓝牙BLE接入调试指引 第三方服务器篇

选择General->Existing Projects into Workspace,点“Next”,选“Select root directory”,浏览BlueDemoServer目录,完成导入。

 

修改src/config.properties

appID=微信公众号的appID

appsecret=微信公众号的appsecret

token=自定义,访问令牌,是微信访问第三方服务器时需要附带的参数

 

BlueDemoServer代码包不是通过eclipse中的run来编译的,而是通过Ant插件来编译,编译脚本是build.xml,操作步骤如下:

点击菜单栏“Window->Show View->Ant”,打开Ant界面:

 微信蓝牙BLE接入调试指引 第三方服务器篇

然后,将Package Explorer里的build.xml拖拉到Ant界面里。

 微信蓝牙BLE接入调试指引 第三方服务器篇

展开bluelight,然后双击make-war

 微信蓝牙BLE接入调试指引 第三方服务器篇

如果没有错误,就会在dist目录下生成mpdevice.war文件,mpdevice的名字可以在build.xml中修改:

<property name="war.name" value="mpdevice.war" />

 

代码编译好后,我们接着就要申请个第三方服务器帐号。

3.2 申请第三方服务器帐号

一般公司申请的帐号,钱多选择多,这里只讲个人开发,想要免费服务好方便调试的,选择就很少,适合的有百度BAE和新浪SAE,这两个要免费使用都比较麻烦,但花个10块钱,就简单多了。

 

我申请的是SAE,讲一下过程。

 

打开http://www.sinacloud.com/sae.html 进入控制台,登陆,点击“创建应用”,进入后,填写二级域名,命字自己取,只要通过就行,然后是应用名,一般会自动生成与二级域名一样,然后,选择Java1.7,这时会提示要有云豆才可以创建,那就用淘宝充个10块钱,也别舍不得,10块有1000个云豆,可以用好久呢,用到调试结束都有剩的。然后在JVM等级里选择最便宜的A型,如下。点创建就可以了。

 微信蓝牙BLE接入调试指引 第三方服务器篇

 

创建好后,可以看到应用信息下的应用名称和网址,这个网址就是微信要访问的:

 微信蓝牙BLE接入调试指引 第三方服务器篇

点击应用名称,进入管理界面,到了管理界面,点击“代码管理”,在这里,点击“上传war包”,就可以将3.1编译出来的war包上传,注意,war包的名称必须应用名称一样,比如,你创建应用填的名称是test111,那么war包的文件名就得改为test111.war

 微信蓝牙BLE接入调试指引 第三方服务器篇

 

正常情况下,服务器在没有流量时会自动关闭,在有请求时会自动打开。另外,也可以手动操作,点击,“JVM管理”,可以在这里开关服务器。

 

上传好war包后,我们就可以配置微信第三方服务器了。

3.3 配置微信第三方服务器

通过网址http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login登入微信公众平台接口测试帐号,修改“接口配置信息”,在URL填入 http://xxxx.applinzi.com/callback因为第三方服务器把servlet name配置为callback,所以需加callback后缀,以便微信通过get发送的接入设备凭证能够被后台程序接收到。Token的值就config.propertiestoken的值相同。配置好后点“提交”就可以了。

 微信蓝牙BLE接入调试指引 第三方服务器篇

 

用微信扫描一下设备二维码进入公众号,如果有提示“欢迎关注蓝牙灯泡demo测试公众号!”说明服务器的配置已经成功了。

3.4 调试

服务器程序的功能主要处理微信绑定事件、菜单按键事件、微信文本,以及与BLE设备数据互发。打开BlueDemoServer代码里的BlueDemoServer\bluelight\src\com\bluelight\demo\service\CallbackService.java文件,可以看到,主要的事件处理都在这里。

SUBSCRIBE 用户关注公众号后发的订阅事件

CLICK 用户点击菜单时发的点击事件

TEXT 用户发来的文本

BIND 绑定设备时发来的事件

DEVICE_TEXT 设备发来的文本

 

首先调试一下SUBSCRIBEBIND功能,用微信扫描设备二维码,然后点击“绑定设备”,微信会向服务器发送BIND事件,查看服务程序的log,看看是否正常。

 

服务程序的log的查看方法:

SAE控制台里,点击“运维”下的“日志中心”,日志类型选择“notice”,再点查询,就要以看到代码里用System.out.println打印出来的信息了。

 微信蓝牙BLE接入调试指引 第三方服务器篇

 

 

在CallbackService.java中可以看到有两个点击事件V1001_LIGHT_ONV1002_LIGHT_OFF,所以我们需要在测试公众号创建对应的菜单按钮。

打开http://mp.weixin.qq.com/debug,选择自定义菜单:

 微信蓝牙BLE接入调试指引 第三方服务器篇

填上已获得的access_token值,然后填body,内容如下:

{

        "button": [

            {

                "type": "click", 

                "name": "open", 

                "key": "V1001_LIGHT_ON", 

                "sub_button": [ ]

            }, 

            {

                "type": "click", 

                "name": "close", 

                "key": "V1002_LIGHT_OFF", 

                "sub_button": [ ]

            }

        ]

点击“检查问题”按钮后,在进入手机微信公众号,就会发现多了两个按键:

 微信蓝牙BLE接入调试指引 第三方服务器篇

点击按钮,微信会向服务器发送对应的CLICK事件,查看服务程序的log,看通信是否正常。

 

另外,点击按钮出,可能会出现没反应,而正常情况下,微信应该显示“已发送点灯消息:”,这时去看查服务器LOG,会发现有这样的错误提示:

SAE java.lang.RuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

 

这表示,服务器程序在调用API时,如https://api.weixin.qq.com/device/transmsg?access_token=ACCESS_TOKEN因认证问题而失败了。

 

解决的方法是打上这个PATCH

--- a/src/com/bluelight/demo/api/util/HttpUtil.java

+++ b/src/com/bluelight/demo/api/util/HttpUtil.java

@@ -15,6 +15,14 @@

 import org.apache.http.client.methods.HttpPost;

 import org.apache.http.entity.StringEntity;

 import org.apache.http.impl.client.DefaultHttpClient;

 import org.apache.http.util.EntityUtils;

+import java.security.cert.X509Certificate;

+import javax.net.ssl.SSLContext;

+import javax.net.ssl.TrustManager;

+import javax.net.ssl.X509TrustManager;

+import org.apache.http.conn.ssl.SSLSocketFactory;

+import org.apache.http.conn.ClientConnectionManager;

+import org.apache.http.conn.scheme.Scheme;

+import org.apache.http.conn.scheme.SchemeRegistry;

 

 /**

  * 服务器端http请求工具类

@@ -44,6 +52,33 @@ public class HttpUtil {

                return rs;

        }

 

+       public static HttpClient wrapClient(HttpClient base) {

+               try {

+               SSLContext ctx = SSLContext.getInstance("TLS"); 

+               X509TrustManager tm = new X509TrustManager() {

+               public void checkClientTrusted(X509Certificate[] xcs,

+               String string) {

+               }

+               public void checkServerTrusted(X509Certificate[] xcs,

+               String string) {

+               }

+               public X509Certificate[] getAcceptedIssuers() {

+               return null;

+               }

+               };

+               ctx.init(null, new TrustManager[] { tm }, null);

+               SSLSocketFactory ssf = new SSLSocketFactory(ctx);

+               ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

+               ClientConnectionManager ccm = base.getConnectionManager();

+               SchemeRegistry sr = ccm.getSchemeRegistry();

+               sr.register(new Scheme("https", ssf, 443));

+               return new DefaultHttpClient(ccm, base.getParams());

+               } catch (Exception ex) {

+               ex.printStackTrace();

+               return null;

+               }

+               }

+       

        /**

         * access_token 接口直接调用,其它调用doGet

         */

@@ -51,6 +86,7 @@ public class HttpUtil {

                try {

                        HttpGet httpGet = new HttpGet(url);

                        HttpClient httpclient = new DefaultHttpClient();

+                       httpclient = wrapClient(httpclient);

                        HttpResponse response = httpclient.execute(httpGet);

                        String resultContent = new Utf8ResponseHandler()

                                        .handleResponse(response);

@@ -90,6 +126,7 @@ public class HttpUtil {

                        StringEntity entity = new StringEntity(body, "UTF-8");

                        httpPost.setEntity(entity);

                        HttpClient httpclient = new DefaultHttpClient();

+                       httpclient = wrapClient(httpclient);

                        HttpResponse response = httpclient.execute(httpPost);

                        String resultContent = new Utf8ResponseHandler()

                                        .handleResponse(response);

 

微信蓝牙BLE接入调试指引 第三方服务器篇

上一篇:微信支付开发(6) 收货地址共享接口


下一篇:微信公众平台开发-- 关闭微信浏览器