原文: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 }

完成以后编译通过,并且能够实现服务器和客户端的实时消息推送。

SignalR在Xamarin Android中的使用的更多相关文章

  1. [置顶] Xamarin android中使用signalr实现即时通讯

    前面几天也写了一些signalr的例子,不过都是在Web端,今天我就来实践一下如何在xamarin android中使用signalr,刚好工作中也用到了这个,也算是总结一下学到的东西吧,希望能帮助你 ...

  2. Xamarin.Android中使用android:onClick="xxx"属性

    原文:Xamarin.Android中使用android:onClick="xxx"属性 在原生Android开发中,为一个View增加点击事件,有三种方式: 1.使用匿名对象 ( ...

  3. Xamarin Android 中Acitvity如何传递数据

    在xamarin android的开发中,activity传递数据非常常见,下面我也来记一下在android中activity之间传递数据的几种方式, Xamarin Android中Activity ...

  4. 5、xamarin.android 中如何对AndroidManifest.xml 进行配置和调整

    降低学习成本是每个.NET传教士义务与责任. 建立生态,保护生态,见者有份. 我们在翻看一些java的源码经常会说我们要在AndroidManifest.xml 中添加一些东西.而我们使用xamari ...

  5. Xamarin.Android中使用ResideMenu实现侧滑菜单

    上次使用Xamarin.Android实现了一个比较常用的功能PullToRefresh,详情见:Xamarin. Android实现下拉刷新功能 这次将实现另外一个手机App中比较常用的功能:侧滑菜 ...

  6. MVP架构在xamarin android中的简单使用

    好几个月没写文章了,使用xamarin android也快接近两年,还有一个月职业生涯就到两个年了,从刚出来啥也不会了,到现在回头看这个项目,真jb操蛋(真辛苦了实施的人了,无数次吐槽怎么这么丑),怪 ...

  7. 在 Xamarin.Android 中使用 Notification.Builder 构建通知

    0 背景 在 Android 4.0 以后,系统支持一种更先进的 Notification.Builder 类来发送通知.但 Xamarin 文档含糊其辞,多方搜索无果,遂决定自己摸索. 之前的代码: ...

  8. Xamarin Android中引用Jar包的方法

    新建一个Java Bingdings Library 将Jar包复制,或使用添加已存在的文件,到Jars文件夹中 确认属性中的“生成操作” 如果有类型转换不正确,请修改Transforms文件夹中的相 ...

  9. Xamarin.Android中实现延迟跳转

    http://blog.csdn.net/candlewu/article/details/52953228 方法一: 使用Handler().PostDelayed 延迟启动 new Handler ...

随机推荐

  1. hdr(host), hdr_beg(host) , path_beg

    ACL derivatives : hdr([<name>[,<occ>]]) : exact string match 字符串精确匹配 hdr_beg([<name&g ...

  2. JS的substr与substring的区别

    substr返回从指定位置开始的指定长度的子字符串 str.substr(star[,length])  第二个参数可选,不选的话,截取到最后,如果length为0或者负数,那么返回的将是一个空字符串 ...

  3. Hdu5126-stars(两次CDQ分治)

    题意: 简化就是有两种操作,一种是插入(x,y,z)这个坐标,第二种是查询(x1,y1,z1)到(x2,y2,z2)(x1<=x2,y1<=y2,z1<=z2)的长方体包含多少个点. ...

  4. safari浏览器cookie问题

        这个题目可能有点大了,这里主要讨论一种解决safari浏览器阻止第三方cookie问题.       场景       公司存在多个域名(a.com,b.com,co.com)这些域名应该统一 ...

  5. Git的一些用法(建立新的branch)

    建立新的branch和查看全部的branch(kk的代码是基于现有的branch) 切换到branch kk: 当然我们也能够在android studio里操作: 注意切换的时候代码会丢失,必须先c ...

  6. [转]laravel 4之视图及Responses

    http://dingjiannan.com/2013/laravel-responses/   laravel 4之视图及Responses 16 Aug 2013 Laravel的Response ...

  7. 微信小程序demo豆瓣图书

    最近微信小程序被炒得很火热,本人也抱着试一试的态度下载了微信web开发者工具,开发工具比较简洁,功能相对比较少,个性化设置也没有.了解完开发工具之后,顺便看了一下小程序的官方开发文档,大概了解了小程序 ...

  8. oracle开启/关闭归档模式

    1.改变非归档模式到归档模式: 1)SQL> conn / as sysdba (以DBA身份连接数据库) 2)SQL> shutdown immediate;(立即关闭数据库) 3)SQ ...

  9. 利用IIS7 解决URL访问限制问题

    网站可以通过URl直接访问一些不希望被访问的东西, 比如一些图片,js,css等等. 为了解决这个问题看了好多文章,不过毕竟我是新手菜鸟级别的,没有具体的解决方法,真心不知道怎么弄. 今天在看IIS的 ...

  10. access数据库的连接字符串以及数据库操作类

    <!--access数据库连接方式--> <add name="QYTangConnectionString" connectionString="Pr ...