1. 程式人生 > >SignalR+HTML5實現訊息推送及Android通知欄訊息

SignalR+HTML5實現訊息推送及Android通知欄訊息

最近在研究使用SignalR實現跨平臺的訊息中心,WebAPI+SignalR作為資料介面和訊息中心,客戶端包含WPF桌面應用、Web應用和Android移動應用。這其中關鍵的功能點在於接收到實時訊息後的通知提醒,桌面應用和Web應用實現相對簡單,Android移動應用開發由於沒有相關經驗所以花費了一些時間。

開發環境

環境 版本
作業系統 Windows 10 proffesional
編譯器 HBuilder8.8.0
編譯器 Eclipse
測試環境 Android4.2/7.0

服務端

服務端的開發有了前面的經驗已經駕輕就熟了,包含三個簡單方法:上線提醒、下線提醒、訊息傳送,程式碼如下:

    public class MessageHub : Hub
    {
        public override Task OnConnected()
        {
            Clients.Others.listen("[" + DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss") + "]:" + Context.ConnectionId + ",上線了!");
            return base.OnConnected();
        }
        public override Task OnDisconnected
(bool stopCalled) { Clients.Others.listen("[" + DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss") + "]:" + Context.ConnectionId + ",下線了!"); return base.OnDisconnected(stopCalled); } public async Task Welcome(string name) { string message = "["
+ Context.ConnectionId + "][" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "]:" + name; await Clients.All.listen(message); } }

詳細的程式碼可以參考以前的博文

Android客戶端

Android客戶端採用HTML5開發,一方面是考慮和Web端的通用性,另一方面是因為本人不會原生Android開發。Android客戶端處理過程如下:與服務端建立連線,監聽訊息,接收訊息,建立通知。

SignalR JS客戶端傳送/接收訊息

SignalR的JavaScript客戶端程式碼在網上很多,具體原理和配置不再囉嗦。由於編譯器使用的是HBuilder(基於Eclipse開發),就使用了它自帶的MUI框架,省去了介面設計的麻煩。
建立一個MUI框架的移動應用專案:
這裡寫圖片描述
需要注意的是,MUI和JQuery的萬用字元 符號給JQuery使用,MUI的$全部使用mui代替。
引用SignalR的js類庫:

    <script src="js/mui.min.js"></script>
    <script type="text/javascript" src="js/jquery-1.6.4.min.js" ></script>
    <script type="text/javascript" src="js/jquery.signalR-2.2.2.min.js" ></script>
    <script type="text/javascript" src="js/common.js" ></script>
    <link href="css/mui.min.css" rel="stylesheet"/>

HTML介面:

<body>
    <div>
        <input type="button" id="_start" value="開啟連線" />
        <input type="button" id="_stop" value="斷開連線" />
        <input type="button" id="_clear" value="清空記錄" />
    </div>
    <div>
        <ul id="_messageList"></ul>
    </div>
    <form class="mui-input-group">
        <div class="mui-input-row">
            <input type="text" id='_msg' placeholder="請輸入">
        </div>
        <div class="mui-button-row">
            <input type="button" id='_send' value="傳送"/>
        </div>
    </form>
</body>

js程式碼:

    <script type="text/javascript" charset="utf-8">
        mui.init();

            mui.plusReady(function () {
            var startBtn = $('#_start');
            var stopBtn = $('#_stop');
            var listener = $.hubConnection('http://192.168.1.100/MessageBus',{ useDefaultPath: false });
            var hub=listener.createHubProxy('MessageHub');

            enable(stopBtn, false);
            enable(startBtn, true);

            //啟動
            startBtn.click(function () {
                startConnection();
                enable(stopBtn, true);
                enable(startBtn, false);
            });

            //停止
            stopBtn.click(function () {
                stopConnection();
                enable(startBtn, true);
                enable(stopBtn, false);
            });

            //清空列表
            $('#_clear').click(function () {
                $('#_messageList').children().remove();
            });

            //開啟連線
            function startConnection() {
                hub.on('listen',function (message) {

                    $('#_messageList').append('<li>' + message + '</li>'); 
                });

                listener.start().fail(function () {
                    $('#_messageList').append('<li>開啟連線失敗!</li>');
                }).done(function () {
                    $('#_messageList').append('<li>連線已開啟...</li>');
                });

            }

            //斷開連線
            function stopConnection() {
                listener.stop();
                $('#_messageList').append('<li>連線已斷開...</li>');
            };

            //按鈕切換
            function enable(button,enabled) {
                if (enabled) {
                    button.removeAttr("disabled");
                }
                else {
                    button.attr("disabled", "disabled");
                }
            }
            //傳送訊息
            $('#_send').click(function(){
                var msg=$('#_msg').val();
                hub.invoke('Welcome',msg);
                $('#_msg').val('');
            });       
     });

    </script>

實現效果:
這裡寫圖片描述

使用Native.js建立Android通知欄訊息

Native.js實際上是HTML5標準的一部分,並不是一門語言,能夠將手機作業系統的原生物件轉義,對映為JS物件,簡單講就是使用js操控手機作業系統。有了Native.js,對於像我這樣的.NET程式設計師開發手機應用是再好不過了。
根據查詢的資料編寫了一段用來建立通知欄訊息的程式碼:

            function CreateNotification(m,n){
                var NotifyID = n;
                var Context = plus.android.importClass("android.content.Context");
                var main = plus.android.runtimeMainActivity();
                var Noti = plus.android.importClass("android.app.Notification");
                var NotificationManager = plus.android.importClass("android.app.NotificationManager");
                var nm = main.getSystemService(Context.NOTIFICATION_SERVICE)
                var Notification = plus.android.importClass("android.app.Notification");
                var mNotification = new Notification.Builder(main);
                var pending=plus.android.importClass("android.app.PendingIntent");
                var intent=plus.android.importClass("android.content.Intent");

                //mNotification.setOngoing(true);
                mNotification.setContentTitle("您有一條未讀訊息");//標題
                mNotification.setContentText(m);//內容
                mNotification.setSmallIcon(17301620);//圖示
                mNotification.setTicker("First Time");//通知首次出現在通知欄時的效果
                mNotification.setNumber(5);//通知集合的數量
                //var str = dateToStr(new Date());
                //mNotification.setWhen(str);//通知產生時間
                //mNotification.setContentIntent();//通知欄點選事件
                mNotification.setDefaults(Noti.DEFAULT_VIBRATE);//聲音、閃燈、震動效果,可疊加
                mNotification.setPriority(Noti.PRIORITY_DEFAULT);//通知優先順序
                mNotification.flags=Notification.FLAG_ONLY_ALERT_ONCE;//發起通知時震動
                var mNb = mNotification.build()
                nm.notify(NotifyID , mNb);
            }

兩個引數分別代表通知內容和通知編號,其他設定已經在程式碼註釋中說明。結合上一部分的程式碼,在接收到實時訊息後,建立通知欄訊息,程式碼修改如下:

            var i=0;

            //開啟連線
            function startConnection() {
                hub.on('listen',function (message) {

                    $('#_messageList').append('<li>' + message + '</li>'); 
                    i=i+1;
                    CreateNotification(message,i);
                });

                listener.start().fail(function () {
                    $('#_messageList').append('<li>開啟連線失敗!</li>');
                }).done(function () {
                    $('#_messageList').append('<li>連線已開啟...</li>');
                });

            }

實現效果如下:
這裡寫圖片描述

備註

測試時使用了兩部手機、一臺伺服器,均位於同一區域網內。後將服務端部署到公網測試伺服器上,同樣可用。必須將SignalR服務端啟用跨域訪問,否則無法實現功能。

作為一個會一點點JS的.NET程式設計師,只是實現了最基本的需求,後期還要繼續實現點選通知開啟應用等功能。歡迎大家前來探討,不吝賜教!