您的位置:首页 > 移动开发 > Android开发

SignalR在Xamarin Android中的使用

2015-11-12 14:47 288 查看
原文:SignalR在Xamarin Android中的使用 ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程。实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据。

下面介绍一下本人在Android手机开发中的使用,开发编译环境使用Xamarin。手机作为一个客户端接入服务器。

首先,在Xamarin中建立Android App,添加SignalR Client开发包,目前最新版本为2.2.0.0。

然后,添加FireHub类。FireHub类的实现代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Client;
using Microsoft.AspNet.SignalR.Client.Hubs;

using NicoDemo.Model;

namespace Nico.Android.SignalR
{
public class FireHub
{
#region 变量声明
public HubConnection _connection=null;
private IHubProxy _proxy=null;
public bool IsConnected = false;
public delegate void ReceiveMessageDelegate(string msg);
public event ReceiveMessageDelegate Receive=null;
public delegate void HubCloseDelegate();
public event HubCloseDelegate CloseHub = null;
public delegate void HubStatusChangedDelegate(int state,string msg);
public event HubStatusChangedDelegate StateChanged = null;

public delegate void AddWebMessageDelegate(WebMessage wm);
public event AddWebMessageDelegate AddWebMessage = null;
#endregion

#region 初始化
public FireHub()
{
IsConnected = false;
_connection = null;
_proxy = null;
}

public string Dispose()
{
try
{
if (_connection != null)
{
try
{
_connection.Stop();
}
catch
{

}
_connection = null;
}
if (_proxy != null)
_proxy = null;
IsConnected = false;
return "";
}
catch(Exception err)
{
return string.Format("({0}-{1})",err.Message + err.StackTrace);
}
}
#endregion

#region HUB事件
void _connection_Closed()
{
if (CloseHub != null)
CloseHub();
IsConnected = false;
}

void _connection_Received(string obj)
{
if (Receive != null)
Receive(obj);
}
#endregion

#region HUB客户端方法

public bool Connect(string url,int timeout=5000)
{
try
{
if (_connection == null)
{
_connection = new HubConnection(url);//,queryString);
_connection.Received += _connection_Received;
_connection.Closed += _connection_Closed;
_connection.StateChanged += _connection_StateChanged;
_proxy = _connection.CreateHubProxy("notifyHub");
}
if (_connection.Start().Wait(timeout))//同步调用
{
IsConnected = true;
return true;
}
else
{
IsConnected = false;
_connection.Dispose();
_connection = null;
_proxy = null;
return false;
}
}
catch
{
return false;
}
}

void _connection_StateChanged(StateChange obj)
{
try
{
switch (obj.NewState)
{
case ConnectionState.Disconnected:
IsConnected = false;
if (_connection != null)
{
_connection.Dispose();
_connection = null;
_proxy = null;
}
if (StateChanged != null)
StateChanged(0,"");
break;
}
}
catch(Exception err)
{
if (StateChanged != null)
StateChanged(1, "_connection_StateChanged:"+err.Message);
}
}

public bool ConnectToServer(UsersEntity user,int timeout=5000)
{
try
{
if (_connection == null || _proxy == null||!IsConnected)
return false;
return _proxy.Invoke("connect",user.ID,user.Name,user.TypeID).Wait(timeout);
}
catch(Exception err)
{
if (StateChanged != null)
StateChanged(1, "ConnectToServer:"+err.Message);
return false;
}
}

public bool SendMessageToAll(UsersEntity user,string message, int timeout = 5000)
{
try
{
if (_connection == null || _proxy == null || !IsConnected)
return false;
_proxy.Invoke("sendMessageToAll", user.ID,user.Name,user.TypeID,message);//.Wait(timeout);
return true;
}
catch(Exception err)
{
if (StateChanged != null)
StateChanged(1,"SendMessageToAll:"+ err.Message);
return false;
}
}

public bool SendMessageToPrivate(string toConnID, string message)
{
try
{
if (_connection == null || _proxy == null || !IsConnected)
return false;
_proxy.Invoke("sendPrivateMessage", toConnID, message);
return true;
}
catch(Exception err)
{
if (StateChanged != null)
StateChanged(1, "SendMessageToPrivate:"+err.Message);
return false;
}
}
#endregion

#region 公共函数
public bool SendToWeb(UsersEntity user,int timeout=5000)
{
try
{
//        <th>事件时间</th>
//<th>事件类型</th>
//<th>发送者</th>
//<th>单位编号</th>
//<th>信息内容</th>
if (!SendMessageToAll(user,"connect test", timeout))
return false;
return true;
}
catch (Exception err)
{
if (StateChanged != null)
StateChanged(1, "SendToWeb:"+err.Message);
return false;
}
}

#endregion

}

public class HubUser
{
[DisplayName("连接ID")]
public string ConnectionId { get; set; }

[DisplayName("用户ID")]
public int UserID { get; set; }

[DisplayName("用户名")]
public string UserName { get; set; }

[DisplayName("用户类型")]
public int TypeID { get; set; }

[DisplayName("连入时间")]
public DateTime ConnectionTime { get; set; }

public HubUser(string connID,int userID, string name,int typeID)
{
ConnectionId = connID;
UserID = userID;
UserName = name;
TypeID = typeID;
ConnectionTime = DateTime.Now;
}
}

public class WebMessage
{
public string ToConnID{get;set;}
public DateTime MessageDate{get;set;}
public string MessageContent { get; set; }
public bool IsAnswer{get;set;}
public int RepeatCounts { get; set; }
public bool IsRemovable { get; set; }

public WebMessage()
{
ToConnID=string.Empty;
MessageDate=DateTime.Now;
MessageContent = string.Empty;
IsAnswer=false;
RepeatCounts = 0;
IsRemovable = false;
}
}
}


最后,在Activity中增加对FireHub的使用,参考代码如下:

public class SignalRActivity : Activity
{
private FireHub _fireHub = null;
private UsersEntity _user = null;

protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);

// Create your application here
SetContentView(Resource.Layout.SignalR);

_user = new UsersEntity ();

Button btnConnectHub = FindViewById<Button> (Resource.Id.btnConnectHub);
btnConnectHub.Text = "监控网站连接";
btnConnectHub.Click += btnConnectHubClick;
}

protected void btnConnectHubClick(object sender,EventArgs e)
{
try
{
if (_fireHub != null)
{
StopHub();
lock (_syncUser)
{
_hubUser.Clear();
}
//UpdateList();
}
else
{
if (HubReconnect(false))
{
RunOnUiThread(new Action(()=>{ _txtView.Text=string.Format("{0}: 实时网站连接成功", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));}));
}
else
{
RunOnUiThread(new Action(()=>{ _txtView.Text=string.Format("{0}: 实时网站连接失败", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));}));
}
}
}
catch (Exception err)
{
//FormMain.STAErrLogger.Write(string.Format("{0}({1}-{2})", err.Message, "FormMain", "btnConnectHub_Click"));
}
}

#region HUB管理

bool HubReconnect(bool checkNull=true)
{
bool bRet = false;
bool isUpdate = false;
//重新连接到服务网站
if (!checkNull || _fireHub != null)
{
if (_fireHub != null)
_fireHub.IsConnected = false;
if (!ConnectHubServer())
{

}
else
{
bRet = true;
}
isUpdate = true;
}
return bRet;
}

public bool ConnectHubServer()
{
try
{
if (_fireHub == null)
_fireHub = new FireHub();
else
{
if (_fireHub.IsConnected)
return true;
}
if (!_fireHub.Connect("http://your service web", 5000))
{
RunOnUiThread(new Action(()=>{ _txtView.Text="实时报警服务网站不在服务状态";}));
if (_fireHub != null)
{
string strDispose = _fireHub.Dispose();
if (!string.IsNullOrEmpty(strDispose))
{
//FormMain.STAErrLogger.Write(string.Format("{0}({1})", "ConnectHubServer-0", strDispose));
}
}
_fireHub = null;
return false;
}
else
{

if (_fireHub.ConnectToServer(_user))
{
_fireHub.Receive -= _fireHub_Receive;
_fireHub.Receive += _fireHub_Receive;
_fireHub.CloseHub -= _fireHub_CloseHub;
_fireHub.CloseHub += _fireHub_CloseHub;
_fireHub.StateChanged -= _fireHub_StateChanged;
_fireHub.StateChanged += _fireHub_StateChanged;
_fireHub.AddWebMessage -= _fireHub_AddWebMessage;
_fireHub.AddWebMessage += _fireHub_AddWebMessage;

if (_webMessageManage == null)
{
_webMessageManage = new WebMessageManage();
_webMessageManage.WebMessageCallback += _webMessageManage_WebMessageCallback;
}
RunOnUiThread(new Action(()=>{ _txtView.Text="成功连接到实时报警服务网站";}));
}
else
{
RunOnUiThread(new Action(()=>{ _txtView.Text="连接到实时报警服务网站失败,请重新尝试";}));
string strDispose = _fireHub.Dispose();
if(!string.IsNullOrEmpty(strDispose))
{

}
_fireHub = null;
return false;
}
}
return true;
}
catch (Exception err)
{

return false;
}
}
#endregion

#region FireHub事件实现

void _fireHub_Receive(string msg)
{
try
{
HubMessage hm = new HubMessage();
hm = Newtonsoft.Json.JsonConvert.DeserializeObject<HubMessage>(msg);
if (hm == null)
return;
if (hm.M == "onConnected")
{
#region 客户端连接成功后的反馈消息

#endregion
}
else if (hm.M == "onNewUserConnected")
{
#region 有新的客户端接入

#endregion
}
else if (hm.M == "onUserDisconnected")
{
#region 客户端断开

#endregion
}
else if (hm.M == "messageReceived")
{
#region 定时广播巡查

#endregion
}
else if (hm.M == "sendCallbackMessage")
{
#region 私人消息发出成功后,返回反馈消息

#endregion
}
else if (hm.M == "sendPrivateMessage")
{
#region 接收到私人消息

#endregion
}
}
catch (Exception err)
{
RunOnUiThread(new Action(()=>{
_txtView.Text="HUB Error:" + err.Message + err.Source;
}));
}
}

void _fireHub_CloseHub()
{
StopHub();
}

public void StopHub()
{
try
{
RunOnUiThread(new Action(()=>{
_txtView.Text="实时报警服务网站关闭";
}));
if (_fireHub == null)
return;
string strDispose = _fireHub.Dispose();
if (!string.IsNullOrEmpty(strDispose))
{

}
_fireHub = null;
RunOnUiThread(new Action(()=>{
ChangeHubButtonStatus();
}));
}
catch (Exception err)
{

}
}

void _webMessageManage_WebMessageCallback(int flag)
{
try
{
if (flag == 0)
{
if ((DateTime.Now - _dtHubReconnect).TotalMinutes < 30)
{
return;
}
RunOnUiThread(new Action(()=>{

}));
//重新连接到服务网站
if(HubReconnect(true))
{
_dtHubReconnect = DateTime.Now;
}
}
}
catch (Exception err)
{

}
}

void _fireHub_AddWebMessage(WebMessage wm)
{
try
{
if (_webMessageManage != null)
{
_webMessageManage.AddMessage(wm);
}
}
catch (Exception err)
{

}
}

void _fireHub_StateChanged(int state, string msg)
{
try
{
switch (state)
{
case 0://断开连接了
{
RunOnUiThread(new Action(()=>{
_txtView.Text="HUB掉线";
}));
StopHub();
}
break;
case 1://HUB异常
{
RunOnUiThread(new Action(()=>{
_txtView.Text=msg;
}));
StopHub();
}
break;
}
}
catch (Exception err)
{

}
}

#endregion

}


完成以后编译通过,并且能够实现服务器和客户端的实时消息推送。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: