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 ...
随机推荐
- Keil C51处理可重入函数问题的探讨
在程序设计中,变量具体可以分为四种类型:全局变量.静态全局变量.局部变量.静态局部变量.这几种变量类型对函数的可重入产生的重大的影响,因为不同的编译器采用不同的策略. 针对51的存储区有限,keil ...
- 《Programming WPF》翻译 第7章 2.图形
原文:<Programming WPF>翻译 第7章 2.图形 图形时绘图的基础,代表用户界面树的元素.WPF支持多种不同的形状,并为它们每一个都提供了元素类型. 7.2.1基本图形类 在 ...
- 通过基于 Linux 的软件 VPN 设备连接到 Windows Azure 虚拟网络
摘要 本文章将说明如何通过使用软件 VPN 设备,将本地办公室或站点连接到 Windows Azure 虚拟网络.在构建原型或在构建可以尽快利用云的"开发/测试"工作流时,软件VP ...
- hdu1067-Gap(bfs+哈希)
Let's play a card game called Gap. You have 28 cards labeled with two-digit numbers. The first digit ...
- 利用智能手机(Android)追踪一块磁铁(三)
更新磁铁追踪算法的源代码,Android Studio项目工程 github地址:https://github.com/amazingyyc/MagnetLocate 说明:将磁铁的位置信息封装成消息 ...
- DreamWeaver文件保存时,提示"发生共享违例"问题的解决方法
在学习牛腩老师的JS视频中,视频中的例子要求实现一个是23个3相乘的结果,在用Dreamweaver制作时,, <script language="javascript" t ...
- 一段代码说明javascript闭包执行机制
假设你能理解以下代码的执行结果,应该就算理解闭包的执行机制了. var name = "tom"; var myobj = { name: "jackson", ...
- C#遍历获取枚举的值,名和属性
获取: Type type = typeof(ParamServiceType); var values = Enum.GetValues(type); ; i < values.Length; ...
- Emit技术使用实例及应用思路
System.Reflection.Emit提供了动态创建类并生成程序集的功能. 适用于.NET Framework 2.0及其以后的版本. 动态生成类在对于O/R Mapping来说有很大的作用,在 ...
- ssh localhost无密码登录设置
亲测... ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys ...