elastic communication是基于c#开发支持.net和mono的通讯组件(简称EC),EC的主要目的简化mono和.net下的通讯开发难度,通过EC可以非常快速地开发基于mono和.net的通讯交互应用。EC抽取的基础的通讯协议默认支持protobuf,msgpack的数据对象进行通讯交互,开发者不可以根据自己的制要制订更多的序列化方式支持;EC不紧紧支持简单的对像传输,还提供了控制器,方法控制器和更方便的远程接口调用功能。
以下是ES希望实现的最终目标
借助于Xamarin实现不同移动端的实现,由于这一块个人工作原因还没细化实现,通过开源相关代码可以让感兴趣的人更好进一步去完成相关功能。
功能简介
EC实现通讯功能是非常方便的事情,下面通讯简单的几种场景来介绍一下EC在通讯上的应用。
HelloWord
- 服务端
namespace HelloWord.Server { [Controller] public class Program { static void Main(string[] args) { ECServer.Open(); System.Threading.Thread.Sleep(-1); } public string HelloWord(ISession session,Hello e) { return string.Format("hello {0} [say time:{1}]", e.Name, DateTime.Now); } } [MessageID(0x1)] [ProtoContract] public class Hello { [ProtoMember(1)] public string Name { get; set; } } }
- 客户端
private EC.ProtoSyncClient mClient = new ProtoSyncClient("127.0.0.1"); mClient.Send<string>(new Hello { Name=textBox1.Text })
远程方法访问
EC支持远程方法调用,如果用过wcf那对这功能感觉应该不会陌生,而EC也是通过接口的方式来定义远程调用行为;wcf同一方法重载需要重新定义名称,而ec则支持同一方法多个重载版本。为了满足更复杂的需要,EC的远程调用同样支持out和ref参数。
- 接口定义
namespace Remoting.Service { public interface IUserService { User Register(string name, string email); } }
- 服务端
[SOAService(typeof(Service.IUserService))] class Program : IUserService { static void Main(string[] args) { ECServer.Open(); System.Threading.Thread.Sleep(-1); } public Service.User Register(string name, string email) { User user = new User(); user.EMail = email; user.Name = name; user.CreateTime = DateTime.Now; return user; } }
- 客户端
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private ProtoClient mClient = new ProtoClient("192.168.7.111"); private IUserService UserService; private void Form1_Load(object sender, EventArgs e) { UserService = mClient.CreateInstance<IUserService>(); } private void cmdRegister_Click(object sender, EventArgs e) { User user= UserService.Register(txtName.Text, txtEMail.Text); txtCreateTime.Text = user.CreateTime.ToString(); } }
数据访问示例
数据访问应该是最常见的一种应用场,以下是定义一个简单的数据查询示例。
- 服务端
[EC.Controller] public class Program { static void Main(string[] args) { DBContext.SetConnectionDriver<SqliteDriver>(DB.DB1); DBContext.SetConnectionString(DB.DB1, "Data Source=northwindEF.db;Pooling=true;FailIfMissing=false;"); ECServer.Open(); System.Threading.Thread.Sleep(-1); } public IList<Employee> OnEmployeeSearch(ISession session, EmployeeSearch e) { return new Expression().List<Models.Employees, Employee>(); } public IList<Customer> OnCustomerSearch(ISession session, CustomerSearch e) { return new Expression().List<Models.Customers, Customer>(); } public IList<Order> OnOrderSearch(ISession session, OrderSearch e) { Expression exp = new Expression(); if (e.CustomerID != null) exp &= Models.Orders.customerID == e.CustomerID; if (e.EmployeeID > 0) exp &= Models.Orders.employeeID == e.EmployeeID; return exp.List<Models.Orders, Order>(); } public IList<OrderDetail> GetOrderDetail(ISession session, GetDetail e) { Expression exp = Models.OrderDetails.orderID == e.OrderID; JoinTable jt = Models.OrderDetails.productID.InnerJoin(Models.Products.productID); jt.Select("OrderDetails.*", Models.Products.productName.Name); return exp.List<OrderDetail>(jt); } }
- 客户端
private ProtoSyncClient mClient = new ProtoSyncClient("127.0.0.1"); private void FrmMain_Load(object sender, EventArgs e) { cbEmployees.Items.Add(new Employee()); foreach (Employee item in mClient.Send<IList<Employee>>(new EmployeeSearch())) { cbEmployees.Items.Add(item); } cbCustomers.Items.Add(new Customer()); foreach (Customer item in mClient.Send<IList<Customer>>(new CustomerSearch())) { cbCustomers.Items.Add(item); } } private void cmdSearch_Click(object sender, EventArgs e) { OrderSearch os = new OrderSearch(); if (cbCustomers.SelectedItem != null) os.CustomerID = ((Customer)cbCustomers.SelectedItem).CustomerID; if (cbEmployees.SelectedItem != null) os.EmployeeID = ((Employee)cbEmployees.SelectedItem).EmployeeID; gdOrder.DataSource = mClient.Send<IList<Order>>(os); } private void gdOrder_SelectionChanged(object sender, EventArgs e) { if (gdOrder.SelectedRows.Count > 0) { Order order = (Order)gdOrder.SelectedRows[0].DataBoundItem; GetDetail getdetail = new GetDetail(); getdetail.OrderID = order.OrderID; gdDetail.DataSource = mClient.Send<IList<OrderDetail>>(getdetail); } }
AppModule
AppModule类似于asp.net的httpModule,它可以在EC服务中载实始化的时候进行加载,通过AppModule可以实现消息处理,处理日志,全局信息定义等相关主要功能。
public class FilterModel : IAppModel
{ public string Name
{ get { return "Filter"; }
} private System.Threading.Timer mTimer; public void Init(IApplication application)
{ //application.Filters.Add(new LoginFilter()); application.Disconnected += (o, e) => { "{0} disposed applicaion event".Log4Info(e.Session.Channel.EndPoint);
};
application.Connected += (o, e) => { "{0} connect applicaion event".Log4Info(e.ChannelConnectArgs.Channel.EndPoint);
};
application.SendCompleted += (o, e) => { "{0} send completed applicaion event".Log4Info(e.Session.Channel.EndPoint);
};
application.MethodProcess += (o, e) => { //application e.Application["Path"] = @"c:\"; //sexxion e.Session["folder"] = "aaa";
};
application.Error += (o, e) => { "{0} channel error {1}".Log4Error(e.Info.Channel.EndPoint, e.Info.Error.Message);
};
mTimer = new System.Threading.Timer(o => {
application.Server.Send(new User { Name = Guid.NewGuid().ToString("N"),CreateTime = DateTime.Now }, application.Server.GetOnlines());
}, null, 1000, 1000);
} public string Command(string cmd)
{ throw new NotImplementedException();
}
}
Filter
这个特性在EC上是提供比较有用的功能,通讯filter可以对调用方法加入权限,日志,拦载等逻辑功能。
public class AdminFilter : FilterAttribute
{ public override void Execute(IMethodContext context)
{ "admin filter ->{0}".Log4Debug(context.Handler); base.Execute(context);
}
}
[Controller] public class Controller
{
[SkipFilter(typeof(LoginFilter))]
[ThreadPool] public User Regisetr(ISession session, User user)
{
user.CreateTime = DateTime.Now; "Register invoke[Name:{0} Email:{1}]".Log4Debug(user.Name, user.EMail); return user;
}
[AdminFilter] public IList<User> Search(ISession session, Query query)
{ "Search invoke".Log4Debug();
List<User> users = new List<User>();
users.Add(new User());
users.Add(new User()); return users;
}
}
开源地址
https://github.com/IKende/ec/
https://github.com/IKende/ec/tree/master/Samples
来源:oschina
链接:https://my.oschina.net/u/1000376/blog/537845