SignalR在Xamarin Android中的使用
原文: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中的使用的更多相关文章
- [置顶]
Xamarin android中使用signalr实现即时通讯
前面几天也写了一些signalr的例子,不过都是在Web端,今天我就来实践一下如何在xamarin android中使用signalr,刚好工作中也用到了这个,也算是总结一下学到的东西吧,希望能帮助你 ...
- Xamarin.Android中使用android:onClick="xxx"属性
原文:Xamarin.Android中使用android:onClick="xxx"属性 在原生Android开发中,为一个View增加点击事件,有三种方式: 1.使用匿名对象 ( ...
- Xamarin Android 中Acitvity如何传递数据
在xamarin android的开发中,activity传递数据非常常见,下面我也来记一下在android中activity之间传递数据的几种方式, Xamarin Android中Activity ...
- 5、xamarin.android 中如何对AndroidManifest.xml 进行配置和调整
降低学习成本是每个.NET传教士义务与责任. 建立生态,保护生态,见者有份. 我们在翻看一些java的源码经常会说我们要在AndroidManifest.xml 中添加一些东西.而我们使用xamari ...
- Xamarin.Android中使用ResideMenu实现侧滑菜单
上次使用Xamarin.Android实现了一个比较常用的功能PullToRefresh,详情见:Xamarin. Android实现下拉刷新功能 这次将实现另外一个手机App中比较常用的功能:侧滑菜 ...
- MVP架构在xamarin android中的简单使用
好几个月没写文章了,使用xamarin android也快接近两年,还有一个月职业生涯就到两个年了,从刚出来啥也不会了,到现在回头看这个项目,真jb操蛋(真辛苦了实施的人了,无数次吐槽怎么这么丑),怪 ...
- 在 Xamarin.Android 中使用 Notification.Builder 构建通知
0 背景 在 Android 4.0 以后,系统支持一种更先进的 Notification.Builder 类来发送通知.但 Xamarin 文档含糊其辞,多方搜索无果,遂决定自己摸索. 之前的代码: ...
- Xamarin Android中引用Jar包的方法
新建一个Java Bingdings Library 将Jar包复制,或使用添加已存在的文件,到Jars文件夹中 确认属性中的“生成操作” 如果有类型转换不正确,请修改Transforms文件夹中的相 ...
- Xamarin.Android中实现延迟跳转
http://blog.csdn.net/candlewu/article/details/52953228 方法一: 使用Handler().PostDelayed 延迟启动 new Handler ...
随机推荐
- WPF InkCanvas MouseDown及MouseLeftButtonDown事件不触发的代替事件
PreviewMouseDown事件可以触发 再通过e.LeftButton 的状态判断是否按钮被按下 特此备忘
- 关于google的C++ coding style
大家都知道google的开源项目有很多,不过我观察过一些开源项目,觉得代码质量就是这家最好了.这些“教条”式规定的背后是是来自于常年工程经验积累上的理性思考. 为什么好?主要有以下几点: 1.规范,就 ...
- 漏洞:WebRTC 泄漏用户IP
WebRTC又称为“网页即时通信”,是一组API函数,它经过W3C组织的认证,支持浏览器之间的语音通话.视频聊天和P2P模式分享文件. 这个协议主要包括:getUserMedia,RTCPe ...
- hihoCoder 1092 : Have Lunch Together
题目大意:小hi和小ho去咖啡厅喝咖啡,咖啡厅可以看作是n * m的矩阵,每个点要么为空,要么被人.障碍物.椅子所占据,小hi和小ho想要找两个相邻的椅子.起初两个人都在同一个点,求两人到达满足要求的 ...
- PHP 字符串替换 substr_replace 与 str_replace 函数
PHP 字符串替换 用于从字符串中替换指定字符串. 相关函数如下: substr_replace():把字符串的一部分替换为另一个字符串 str_replace():使用一个字符串替换字符串中的另一些 ...
- PC--CSS技巧
1.图片不存在的时候,显示一个默认图片 <img src=”01.jpg” onerror=”this.src=’02.jpg'” /> 2.CSS强制图片自适应大小 img {width ...
- Hadoop集群启动之后,datanode节点未正常启动的问题
Hadoop集群启动之后,用JPS命令查看进程发现datanode节点上,只有TaskTracker进程.如下图所示 master的进程: 两个slave的节点进程 发现salve节点上竟然没有dat ...
- .net 4.5 新特性 async await 一般处理程序实例
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using Sys ...
- Eclipse安装Vim——viPlugin插件
1.下载viPlugin: http://www.viplugin.com/files/viPlugin_2.14.0.zip 2.安装 解压后有两个文件夹: features 和 plugins 把 ...
- NSBundle 类
NSBundle NSBundle继承于NSObject,NSBundle是一个程序包,其中包含了程序会使用的资源(图像,声音,编辑好的代码,nib文件). 一. 初始化NSBundle + (ins ...