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 { // 事件时间 //事件类型 //发送者 //单位编号 //信息内容 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
完成以后编译通过,并且能够实现服务器和客户端的实时消息推送。