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的萬用字元
引用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程式設計師,只是實現了最基本的需求,後期還要繼續實現點選通知開啟應用等功能。歡迎大家前來探討,不吝賜教!